<?php

namespace App\Models;

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

class Equipment extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'name',
        'type',
        'description',
        'image',
        'is_active',
        'sort_order',
        'start_time',
        'end_time',
        'slot_duration'
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'sort_order' => 'integer',
        'slot_duration' => 'integer',
        'start_time' => 'datetime:H:i',
        'end_time' => 'datetime:H:i'
    ];

    /**
     * Get all available equipment types.
     */
    public static function getTypes(): array
    {
        return [
            'golf_car' => 'Golf Car',
            'boat' => 'Boat'
        ];
    }

    /**
     * Get the formatted type name.
     */
    public function getTypeNameAttribute(): string
    {
        return self::getTypes()[$this->type] ?? ucfirst($this->type);
    }

    /**
     * Get the image URL.
     */
    public function getImageUrlAttribute(): string
    {
        return $this->image ? asset('storage/' . $this->image) : asset('images/placeholder.jpg');
    }

    /**
     * Check if the equipment is active.
     */
    public function isActive(): bool
    {
        return $this->is_active;
    }

    /**
     * Scope a query to only include active equipment.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope a query to only include equipment of a specific type.
     */
    public function scopeOfType($query, $type)
    {
        return $query->where('type', $type);
    }

    /**
     * Scope a query to order by sort order.
     */
    public function scopeOrdered($query)
    {
        return $query->orderBy('sort_order', 'asc')->orderBy('created_at', 'desc');
    }

    /**
     * Get all time slots for a specific date.
     */
    public function getTimeSlotsForDate($date): array
    {
        return $this->timeSlots()
            ->forDate($date)
            ->future()
            ->orderBy('start_time')
            ->get()
            ->map(function ($timeSlot) {
                return [
                    'id' => $timeSlot->id,
                    'start_time' => $timeSlot->start_time->format('H:i'),
                    'end_time' => $timeSlot->end_time->format('H:i'),
                    'is_reserved' => $timeSlot->isReserved(),
                    'is_available' => $timeSlot->isAvailable(),
                    'status' => $timeSlot->status,
                    'reservation_id' => $timeSlot->reservation_id,
                ];
            })
            ->toArray();
    }

    /**
     * Check if a specific time slot is available for a date.
     */
    public function isSlotAvailable($date, $startTime): bool
    {
        return $this->timeSlots()
            ->forDate($date)
            ->where('start_time', $startTime)
            ->available()
            ->future()
            ->exists();
    }

    /**
     * Get available time slots for a specific date.
     */
    public function getAvailableSlotsForDate($date): array
    {
        return $this->timeSlots()
            ->forDate($date)
            ->available()
            ->future()
            ->orderBy('start_time')
            ->get()
            ->map(function ($timeSlot) {
                return [
                    'id' => $timeSlot->id,
                    'date' => $timeSlot->slot_date->format('Y-m-d'),
                    'start_time' => $timeSlot->start_time->format('H:i'),
                    'end_time' => $timeSlot->end_time->format('H:i'),
                    'duration_minutes' => $timeSlot->duration_minutes,
                ];
            })
            ->toArray();
    }

    /**
     * Get reserved time slots for a specific date.
     */
    public function getReservedSlotsForDate($date): array
    {
        return $this->timeSlots()
            ->forDate($date)
            ->reserved()
            ->future()
            ->orderBy('start_time')
            ->get()
            ->map(function ($timeSlot) {
                return [
                    'id' => $timeSlot->id,
                    'start_time' => $timeSlot->start_time->format('H:i'),
                    'end_time' => $timeSlot->end_time->format('H:i'),
                    'reservation_id' => $timeSlot->reservation_id,
                ];
            })
            ->toArray();
    }

    /**
     * Get the relationships.
     */
    public function reservations()
    {
        return $this->hasMany(EquipmentReservation::class);
    }

    /**
     * Get the time slots for this equipment.
     */
    public function timeSlots()
    {
        return $this->hasMany(TimeSlot::class);
    }

    /**
     * Get a summary of the equipment for API responses.
     */
    public function toApiArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'type' => $this->type,
            'type_name' => $this->type_name,
            'description' => $this->description,
            'image' => $this->image_url,
            'is_active' => $this->is_active,
            'sort_order' => $this->sort_order,
            'start_time' => $this->start_time->format('H:i'),
            'end_time' => $this->end_time->format('H:i'),
            'slot_duration' => $this->slot_duration,
            'created_at' => $this->created_at->toISOString(),
            'updated_at' => $this->updated_at->toISOString(),
        ];
    }

    /**
     * Get full details of the equipment for API responses.
     */
    public function toApiDetailArray(): array
    {
        return array_merge($this->toApiArray(), [
            'total_reservations' => $this->reservations()->count(),
            'active_reservations' => $this->reservations()->where('status', 'confirmed')->count(),
        ]);
    }
}
