<?php
declare(strict_types=1);

namespace App\Modules\Reservations\Models;

use App\Core\Model;
use App\Core\App;

class Reservation extends Model
{
    protected static string $table = 'reservations';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = true;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'reservation_number',
        'facility_id',
        'booker_type',
        'player_id',
        'member_id',
        'booker_name',
        'booker_phone',
        'reservation_date',
        'start_time',
        'end_time',
        'duration_hours',
        'time_tier',
        'unit_rate',
        'total_amount',
        'payment_id',
        'status',
        'confirmed_at',
        'cancelled_at',
        'cancel_reason',
        'notes',
        'created_by',
    ];

    /**
     * Get all reservation statuses with Arabic labels.
     */
    public static function getStatuses(): array
    {
        return [
            'pending'    => 'قيد الانتظار',
            'confirmed'  => 'مؤكد',
            'checked_in' => 'تم الدخول',
            'completed'  => 'مكتمل',
            'cancelled'  => 'ملغى',
            'no_show'    => 'لم يحضر',
        ];
    }

    /**
     * Get the Arabic label for a status key.
     */
    public static function getStatusLabel(string $status): string
    {
        $statuses = self::getStatuses();
        return $statuses[$status] ?? $status;
    }

    /**
     * Get the badge color for a status.
     */
    public static function getStatusColor(string $status): string
    {
        $colors = [
            'pending'    => '#D97706',
            'confirmed'  => '#0284C7',
            'checked_in' => '#7C3AED',
            'completed'  => '#059669',
            'cancelled'  => '#DC2626',
            'no_show'    => '#6B7280',
        ];
        return $colors[$status] ?? '#6B7280';
    }

    /**
     * Get all booker types with Arabic labels.
     */
    public static function getBookerTypes(): array
    {
        return [
            'member'     => 'عضو',
            'non_member' => 'غير عضو',
            'player'     => 'لاعب',
            'guest'      => 'ضيف',
        ];
    }

    /**
     * Get the Arabic label for a booker type key.
     */
    public static function getBookerTypeLabel(string $type): string
    {
        $types = self::getBookerTypes();
        return $types[$type] ?? $type;
    }

    /**
     * Generate a unique reservation number in the format RES-YYYYMMDD-XXXX.
     */
    public static function generateNumber(): string
    {
        $today = date('Ymd');
        $prefix = 'RES-' . $today . '-';

        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM `reservations` WHERE `reservation_number` LIKE ?",
            [$prefix . '%']
        );
        $seq = ((int) ($row['cnt'] ?? 0)) + 1;

        return $prefix . str_pad((string) $seq, 4, '0', STR_PAD_LEFT);
    }

    /**
     * Search reservations with filters and pagination.
     */
    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $query = static::query()
            ->leftJoin('facilities', '`reservations`.`facility_id` = `facilities`.`id`')
            ->select('`reservations`.*, `facilities`.`name_ar` as facility_name');

        if (!empty($filters['q'])) {
            $search = '%' . $filters['q'] . '%';
            $query = $query->whereRaw(
                '(`reservations`.`reservation_number` LIKE ? OR `reservations`.`booker_name` LIKE ? OR `reservations`.`booker_phone` LIKE ?)',
                [$search, $search, $search]
            );
        }

        if (!empty($filters['facility_id'])) {
            $query = $query->where('facility_id', '=', (int) $filters['facility_id']);
        }

        if (!empty($filters['status'])) {
            $query = $query->where('status', '=', $filters['status']);
        }

        if (!empty($filters['date_from'])) {
            $query = $query->whereRaw('`reservations`.`reservation_date` >= ?', [$filters['date_from']]);
        }

        if (!empty($filters['date_to'])) {
            $query = $query->whereRaw('`reservations`.`reservation_date` <= ?', [$filters['date_to']]);
        }

        $query = $query->orderBy('reservation_date', 'DESC')->orderBy('start_time', 'ASC');

        return $query->paginate($perPage, $page);
    }

    /**
     * Get all reservations for a facility on a specific date (for conflict detection).
     */
    public static function getForFacilityDate(int $facilityId, string $date): array
    {
        return static::query()
            ->where('facility_id', '=', $facilityId)
            ->where('reservation_date', '=', $date)
            ->whereRaw("`reservations`.`status` NOT IN ('cancelled', 'no_show')")
            ->orderBy('start_time', 'ASC')
            ->get();
    }
}
