<?php

namespace App\Models;

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

class HousekeepingTask extends Model
{
    use HasFactory, \App\Traits\HotelScopeTrait;

    protected $fillable = [
        'hotel_id',
        'room_id',
        'task_name',
        'task_type',
        'description',
        'status',
        'assigned_to',
        'assigned_staff_id',
        'assigned_at',
        'scheduled_date',
        'scheduled_time',
        'completed_time',
        'estimated_duration',
        'actual_duration',
        'priority',
        'notes',
        'started_at'
    ];

    protected $casts = [
        'scheduled_date' => 'date',
        'scheduled_time' => 'datetime',
        'completed_time' => 'datetime',
        'assigned_at' => 'datetime',
        'started_at' => 'datetime',
        'estimated_duration' => 'integer',
        'actual_duration' => 'integer',
        'priority' => 'string'
    ];

    /**
     * Automatically update room status when task is created or updated
     */
    protected static function boot()
    {
        parent::boot();

        static::updated(function ($task) {
            // If task status changed to completed, update the room status
            if ($task->isDirty('status') && $task->status === 'completed') {
                $room = $task->room;
                if ($room) {
                    $room->update([
                        'housekeeping_status' => 'clean',
                        'status' => 'available',
                        'last_cleaned_at' => now()
                    ]);
                }
            }
            
            // If task status changed to in_progress, update the room status
            if ($task->isDirty('status') && $task->status === 'in_progress') {
                $room = $task->room;
                if ($room) {
                    $room->update([
                        'housekeeping_status' => 'in_progress',
                        'status' => 'cleaning'
                    ]);
                }
            }

            // If task status changed to pending, update the room status
            if ($task->isDirty('status') && $task->status === 'pending') {
                $room = $task->room;
                if ($room) {
                    $room->update([
                        'housekeeping_status' => 'dirty',
                        'status' => 'cleaning'
                    ]);
                }
            }
        });

        static::created(function ($task) {
            // When a new task is created, update the room status to in_progress
            if ($task->room) {
                $task->room->update([
                    'housekeeping_status' => 'in_progress',
                    'status' => 'cleaning'
                ]);
            }
        });
    }

    // Relationship with room
    public function room()
    {
        return $this->belongsTo(Room::class);
    }

    // Relationship with staff (using assigned_staff_id)
    public function staff()
    {
        return $this->belongsTo(Staff::class, 'assigned_staff_id');
    }

    // Relationship with assigned user (using assigned_to)
    public function assignedUser()
    {
        return $this->belongsTo(Staff::class, 'assigned_to');
    }

    // Scope for today's tasks
    public function scopeToday($query)
    {
        return $query->whereDate('scheduled_date', today());
    }

    // Scope for pending tasks
    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    // Scope for in progress tasks
    public function scopeInProgress($query)
    {
        return $query->where('status', 'in_progress');
    }

    // Scope for completed tasks
    public function scopeCompleted($query)
    {
        return $query->where('status', 'completed');
    }

    // Scope for cancelled tasks
    public function scopeCancelled($query)
    {
        return $query->where('status', 'cancelled');
    }

    // Scope for high priority tasks
    public function scopeHighPriority($query)
    {
        return $query->where('priority', 'high');
    }

    // Scope for tasks by room
    public function scopeByRoom($query, $roomId)
    {
        return $query->where('room_id', $roomId);
    }

    // Scope for tasks by staff
    public function scopeByStaff($query, $staffId)
    {
        return $query->where('assigned_staff_id', $staffId);
    }

    // Scope for overdue tasks
    public function scopeOverdue($query)
    {
        return $query->where('scheduled_date', '<', today())
                    ->whereIn('status', ['pending', 'in_progress']);
    }

    // Accessor for is_overdue
    public function getIsOverdueAttribute()
    {
        return $this->scheduled_date < today() && 
               in_array($this->status, ['pending', 'in_progress']);
    }

    // Accessor for duration_minutes
    public function getDurationMinutesAttribute()
    {
        if ($this->started_at && $this->completed_time) {
            return $this->started_at->diffInMinutes($this->completed_time);
        }
        return null;
    }

    // Method to mark as in progress
    public function markAsInProgress()
    {
        $this->update([
            'status' => 'in_progress',
            'started_at' => $this->started_at ?: now()
        ]);
    }

    // Method to mark as completed
    public function markAsCompleted()
    {
        $this->update([
            'status' => 'completed',
            'completed_time' => now()
        ]);
    }

    // Method to calculate efficiency
    public function getEfficiencyScoreAttribute()
    {
        if (!$this->estimated_duration || !$this->actual_duration) {
            return null;
        }

        if ($this->actual_duration <= $this->estimated_duration) {
            return 100;
        }

        return max(0, round(($this->estimated_duration / $this->actual_duration) * 100));
    }

    // Accessor for full staff name
    public function getAssignedStaffNameAttribute()
    {
        if ($this->staff) {
            return $this->staff->first_name . ' ' . $this->staff->last_name;
        }
        return 'Unassigned';
    }
}