<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;use App\Models\Concerns\BelongsToCompany;


class Ticket extends Model
{
    use SoftDeletes, LogsActivity, BelongsToCompany;

    protected $fillable = [
        'number','title','description','status_id','priority_id','category_id','type_id',
        'requester_id','assignee_id','department_id','sla_response_due','sla_resolution_due',
        'sla_response_breached','sla_resolution_breached','first_response_at',
        'resolved_at','closed_at','satisfaction_score','satisfaction_comment'
    ];

    protected function casts(): array {
        return [
            'sla_response_due'       => 'datetime',
            'sla_resolution_due'     => 'datetime',
            'first_response_at'      => 'datetime',
            'resolved_at'            => 'datetime',
            'closed_at'              => 'datetime',
            'sla_response_breached'  => 'boolean',
            'sla_resolution_breached'=> 'boolean',
        ];
    }

    // ── Relaciones ────────────────────────────────────────────────────────────
    public function status(): BelongsTo    { return $this->belongsTo(TicketStatus::class); }
    public function priority(): BelongsTo  { return $this->belongsTo(TicketPriority::class); }
    public function category(): BelongsTo  { return $this->belongsTo(TicketCategory::class); }
    public function type(): BelongsTo      { return $this->belongsTo(TicketType::class); }
    public function requester(): BelongsTo { return $this->belongsTo(User::class, 'requester_id'); }
    public function assignee(): BelongsTo  { return $this->belongsTo(User::class, 'assignee_id'); }
    public function department(): BelongsTo{ return $this->belongsTo(Department::class); }
    public function comments(): HasMany    { return $this->hasMany(TicketComment::class)->latest(); }
    public function publicComments(): HasMany { return $this->hasMany(TicketComment::class)->where('is_internal', false)->latest(); }
    public function history(): HasMany     { return $this->hasMany(TicketHistory::class)->latest(); }
    public function attachments(): HasMany { return $this->hasMany(TicketAttachment::class); }

    // ── Scopes ────────────────────────────────────────────────────────────────
    public function scopeOpen($q)       { return $q->whereHas('status', fn($s) => $s->where('is_final', false)); }
    public function scopeClosed($q)     { return $q->whereHas('status', fn($s) => $s->where('is_final', true)); }
    public function scopeForUser($q, $userId) { return $q->where('requester_id', $userId); }
    public function scopeForAgent($q, $userId){ return $q->where('assignee_id', $userId); }
    public function scopeUnassigned($q) { return $q->whereNull('assignee_id'); }

    // ── Helpers ───────────────────────────────────────────────────────────────

    // Genera el próximo número de ticket: TKT-0001
    public static function generateNumber(): string {
        $last = static::withTrashed()->orderBy('id', 'desc')->first();
        $next = $last ? ((int) substr($last->number, 4)) + 1 : 1;
        return 'TKT-' . str_pad($next, 4, '0', STR_PAD_LEFT);
    }

    // Estado del SLA para la vista
    public function getSlaStatusAttribute(): string {
        if ($this->status->is_final) return 'closed';
        if (!$this->sla_resolution_due) return 'none';
        $now = now();
        if ($now->gt($this->sla_resolution_due)) return 'breached';  // rojo
        if ($now->gt($this->sla_resolution_due->subHours(2))) return 'warning'; // amarillo
        return 'ok'; // verde
    }

    // Tiempo restante para resolución como texto
    public function getSlaRemainingAttribute(): string {
        if (!$this->sla_resolution_due || $this->status->is_final) return '—';
        $diff = now()->diff($this->sla_resolution_due);
        if (now()->gt($this->sla_resolution_due)) {
            return 'Vencido ' . $diff->h . 'h ' . $diff->i . 'm';
        }
        return $diff->days > 0
            ? $diff->days . 'd ' . $diff->h . 'h restantes'
            : $diff->h . 'h ' . $diff->i . 'm restantes';
    }

    // Registra un evento en el historial
    public function addHistory(string $action, string $description, ?int $userId = null,
                               ?string $field = null, ?string $old = null, ?string $new = null): void {
        $this->history()->create([
            'user_id'       => $userId ?? auth()->id(),
            'action'        => $action,
            'field_changed' => $field,
            'old_value'     => $old,
            'new_value'      => $new,
            'description'   => $description,
        ]);
    }

    public function getActivitylogOptions(): LogOptions {
        return LogOptions::defaults()->logOnly(['title','status_id','priority_id','assignee_id'])
            ->logOnlyDirty()
            ->setDescriptionForEvent(fn($e) => "Ticket {$this->number}: {$e}");
    }

    public function aiClassification()
    {
        return $this->hasOne(\App\Models\AiClassification::class);
    }

    public function aiKbDraft()
    {
        return $this->hasOne(\App\Models\AiKbDraft::class);
    }
}