<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;

class Appointment extends Model
{
    /** @use HasFactory<\Database\Factories\AppointmentFactory> */
    use HasFactory;

    protected $fillable = [
        'customer_id',
        'vehicle_id',
        'assigned_technician_id',
        'scheduled_datetime',
        'estimated_duration_minutes',
        'appointment_type',
        'service_requested',
        'customer_notes',
        'internal_notes',
        'status',
        'checked_in_at',
        'completed_at',
        'service_order_id',
    ];

    protected $casts = [
        'scheduled_datetime' => 'datetime',
        'checked_in_at' => 'datetime',
        'completed_at' => 'datetime',
        'estimated_duration_minutes' => 'integer',
    ];

    // Relationships
    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }

    public function vehicle(): BelongsTo
    {
        return $this->belongsTo(Vehicle::class);
    }

    public function assignedTechnician(): BelongsTo
    {
        return $this->belongsTo(Technician::class, 'assigned_technician_id');
    }

    public function serviceOrder(): BelongsTo
    {
        return $this->belongsTo(ServiceOrder::class);
    }

    // Scopes
    public function scopeToday($query)
    {
        return $query->whereDate('scheduled_datetime', today());
    }

    public function scopeUpcoming($query)
    {
        return $query->where('scheduled_datetime', '>=', now());
    }

    public function scopeForTechnician($query, $technicianId)
    {
        return $query->where('assigned_technician_id', $technicianId);
    }

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

    public function scopeInDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('scheduled_datetime', [$startDate, $endDate]);
    }

    // Accessors & Mutators
    public function getFormattedDateTimeAttribute(): string
    {
        return $this->scheduled_datetime->format('M j, Y g:i A');
    }

    public function getFormattedDateAttribute(): string
    {
        return $this->scheduled_datetime->format('M j, Y');
    }

    public function getFormattedTimeAttribute(): string
    {
        return $this->scheduled_datetime->format('g:i A');
    }

    public function getEndTimeAttribute(): Carbon
    {
        return $this->scheduled_datetime->addMinutes($this->estimated_duration_minutes);
    }

    public function getFormattedEndTimeAttribute(): string
    {
        return $this->end_time->format('g:i A');
    }

    public function getStatusColorAttribute(): string
    {
        return match($this->status) {
            'scheduled' => 'blue',
            'confirmed' => 'green',
            'in_progress' => 'yellow',
            'completed' => 'emerald',
            'cancelled' => 'red',
            'no_show' => 'gray',
            default => 'blue'
        };
    }

    public function getTypeColorAttribute(): string
    {
        return match($this->appointment_type) {
            'maintenance' => 'blue',
            'repair' => 'red',
            'inspection' => 'yellow',
            'estimate' => 'purple',
            'pickup' => 'green',
            'delivery' => 'indigo',
            default => 'blue'
        };
    }

    // Helper Methods
    public function canBeModified(): bool
    {
        return in_array($this->status, ['scheduled', 'confirmed']) && 
               $this->scheduled_datetime->isFuture();
    }

    public function canBeCheckedIn(): bool
    {
        return $this->status === 'confirmed' && 
               $this->scheduled_datetime->isPast() && 
               !$this->checked_in_at;
    }

    public function canBeCompleted(): bool
    {
        return in_array($this->status, ['confirmed', 'in_progress']) && 
               $this->checked_in_at;
    }

    public function isOverdue(): bool
    {
        return $this->status === 'scheduled' && 
               $this->scheduled_datetime->isPast();
    }

    public function getDurationInHours(): float
    {
        return round($this->estimated_duration_minutes / 60, 1);
    }

    // Status Management
    public function confirm(): bool
    {
        if ($this->status === 'scheduled') {
            return $this->update(['status' => 'confirmed']);
        }
        return false;
    }

    public function checkIn(): bool
    {
        if ($this->canBeCheckedIn()) {
            return $this->update([
                'status' => 'in_progress',
                'checked_in_at' => now()
            ]);
        }
        return false;
    }

    public function complete(): bool
    {
        if ($this->canBeCompleted()) {
            return $this->update([
                'status' => 'completed',
                'completed_at' => now()
            ]);
        }
        return false;
    }

    public function cancel(): bool
    {
        if ($this->canBeModified()) {
            return $this->update(['status' => 'cancelled']);
        }
        return false;
    }

    public function markNoShow(): bool
    {
        if ($this->isOverdue()) {
            return $this->update(['status' => 'no_show']);
        }
        return false;
    }
}
