<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class SupportTicket extends Model
{
    use HasFactory;

    protected $fillable = [
        'ticket_number',
        'device_id',
        'customer_phone',
        'customer_name',
        'subject',
        'description',
        'status',
        'priority',
        'assigned_to',
        'assigned_staff_id',
        'created_by',
        'attachments',
        'conversation_history',
        'lead_score',
        'first_response_at',
        'resolved_at',
        'last_activity_at',
    ];

    protected $casts = [
        'attachments' => 'array',
        'conversation_history' => 'array',
        'lead_score' => 'integer',
        'first_response_at' => 'datetime',
        'resolved_at' => 'datetime',
        'last_activity_at' => 'datetime',
    ];

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($ticket) {
            if (empty($ticket->ticket_number)) {
                $ticket->ticket_number = 'TKT-' . strtoupper(uniqid());
            }
            $ticket->last_activity_at = now();
        });

        static::updating(function ($ticket) {
            $ticket->last_activity_at = now();
        });
    }

    // Relationships
    public function device()
    {
        return $this->belongsTo(Device::class);
    }

    public function assignedAgent()
    {
        return $this->belongsTo(User::class, 'assigned_to');
    }

    public function assignedStaff()
    {
        return $this->belongsTo(Staff::class, 'assigned_staff_id');
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function messages()
    {
        return $this->hasMany(TicketMessage::class, 'ticket_id');
    }

    public function lead()
    {
        return $this->hasOne(Lead::class, 'ticket_id');
    }

    // Scopes
    public function scopeByStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    public function scopeByPriority($query, $priority)
    {
        return $query->where('priority', $priority);
    }

    public function scopeAssigned($query)
    {
        return $query->whereNotNull('assigned_to');
    }

    public function scopeUnassigned($query)
    {
        return $query->whereNull('assigned_to');
    }

    public function scopeOpen($query)
    {
        return $query->whereIn('status', ['open', 'pending', 'in_progress', 'on_hold']);
    }

    public function scopeClosed($query)
    {
        return $query->whereIn('status', ['resolved', 'closed']);
    }

    public function scopeAssignedToUser($query, $userId)
    {
        return $query->where('assigned_to', $userId);
    }

    // Methods
    public function assignToAgent($agentId)
    {
        $this->assigned_to = $agentId;
        $this->save();

        // Update agent's current ticket count
        $agent = TicketAgent::where('user_id', $agentId)
            ->where('device_id', $this->device_id)
            ->first();

        if ($agent) {
            $agent->increment('current_tickets');
        }

        // Add system message
        $this->addSystemMessage("Ticket assigned to " . $this->assignedAgent->name);

        return $this;
    }

    public function changeStatus($newStatus, $userId = null)
    {
        $oldStatus = $this->status;
        $this->status = $newStatus;

        if ($newStatus === 'resolved' || $newStatus === 'closed') {
            $this->resolved_at = now();

            // Decrement agent's current ticket count
            if ($this->assigned_to) {
                $agent = TicketAgent::where('user_id', $this->assigned_to)
                    ->where('device_id', $this->device_id)
                    ->first();

                if ($agent && $agent->current_tickets > 0) {
                    $agent->decrement('current_tickets');
                }
            }
        }

        $this->save();

        // Add system message
        $this->addSystemMessage("Status changed from {$oldStatus} to {$newStatus}");

        return $this;
    }

    public function addMessage($message, $senderType = 'customer', $senderId = null, $messageType = 'text', $attachments = null)
    {
        $ticketMessage = $this->messages()->create([
            'sender_type' => $senderType,
            'sender_id' => $senderId,
            'message' => $message,
            'message_type' => $messageType,
            'attachments' => $attachments,
        ]);

        // Set first response time if this is the first agent response
        if ($senderType === 'agent' && !$this->first_response_at) {
            $this->first_response_at = now();
            $this->save();
        }

        return $ticketMessage;
    }

    public function addSystemMessage($message)
    {
        return $this->messages()->create([
            'sender_type' => 'system',
            'message' => $message,
            'message_type' => 'text',
        ]);
    }

    public function calculateResponseTime()
    {
        if (!$this->first_response_at) {
            return null;
        }

        return $this->created_at->diffInMinutes($this->first_response_at);
    }

    public function calculateResolutionTime()
    {
        if (!$this->resolved_at) {
            return null;
        }

        return $this->created_at->diffInMinutes($this->resolved_at);
    }

    public function isOpen()
    {
        return in_array($this->status, ['open', 'pending', 'in_progress', 'on_hold']);
    }

    public function isClosed()
    {
        return in_array($this->status, ['resolved', 'closed']);
    }

    public function getUnreadMessagesCount()
    {
        return $this->messages()->where('is_read', false)->where('sender_type', 'customer')->count();
    }
}
