<?php

use App\Services\AvailabilityService;
use Carbon\Carbon;
use Livewire\Volt\Component;

new class extends Component
{
    public int $year;

    public int $month;

    public ?string $selectedDate = null;

    public array $monthAvailability = [];

    public array $availableSlots = [];

    public array $bookedDates = [];

    public function mount(array $bookedDates = []): void
    {
        $this->bookedDates = $bookedDates;
        $this->year = now()->year;
        $this->month = now()->month;
        $this->loadMonthAvailability();
    }

    public function loadMonthAvailability(): void
    {
        $service = app(AvailabilityService::class);
        $this->monthAvailability = $service->getMonthAvailability($this->year, $this->month);
    }

    public function previousMonth(): void
    {
        $date = Carbon::create($this->year, $this->month, 1)->subMonth();

        // Prevent navigating to past months
        if ($date->lt(now()->startOfMonth())) {
            return;
        }

        $this->year = $date->year;
        $this->month = $date->month;
        $this->selectedDate = null;
        $this->availableSlots = [];
        $this->loadMonthAvailability();
    }

    public function nextMonth(): void
    {
        $date = Carbon::create($this->year, $this->month, 1)->addMonth();
        $this->year = $date->year;
        $this->month = $date->month;
        $this->selectedDate = null;
        $this->availableSlots = [];
        $this->loadMonthAvailability();
    }

    public function selectDate(string $date): void
    {
        // Prevent selecting user's already booked dates
        if (in_array($date, $this->bookedDates)) {
            return;
        }

        $status = $this->monthAvailability[$date] ?? 'unavailable';

        if (in_array($status, ['available', 'partial'])) {
            $this->selectedDate = $date;
            $this->loadAvailableSlots();
        }
    }

    public function loadAvailableSlots(): void
    {
        if (! $this->selectedDate) {
            $this->availableSlots = [];

            return;
        }

        $service = app(AvailabilityService::class);
        $this->availableSlots = $service->getAvailableSlots(
            Carbon::parse($this->selectedDate)
        );
    }

    /**
     * Get the day headers with locale-aware ordering.
     *
     * @return array<string>
     */
    private function getDayHeaders(): array
    {
        $days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

        // Arabic calendar traditionally starts on Saturday
        if (app()->getLocale() === 'ar') {
            array_unshift($days, array_pop($days));
        }

        return $days;
    }

    /**
     * Build calendar days array for the current month.
     *
     * @return array<int, array{date: string, day: int, status: string}|null>
     */
    private function buildCalendarDays(): array
    {
        $firstDay = Carbon::create($this->year, $this->month, 1);
        $lastDay = $firstDay->copy()->endOfMonth();

        // Calculate start padding based on locale
        $startPadding = $firstDay->dayOfWeek;
        if (app()->getLocale() === 'ar') {
            // Adjust for Saturday start
            $startPadding = ($firstDay->dayOfWeek + 1) % 7;
        }

        $days = array_fill(0, $startPadding, null);

        // Fill month days
        $current = $firstDay->copy();
        while ($current->lte($lastDay)) {
            $dateStr = $current->format('Y-m-d');

            // Check if user has already booked this date
            $status = in_array($dateStr, $this->bookedDates)
                ? 'user_booked'
                : ($this->monthAvailability[$dateStr] ?? 'unavailable');

            $days[] = [
                'date' => $dateStr,
                'day' => $current->day,
                'status' => $status,
            ];
            $current->addDay();
        }

        return $days;
    }

    public function with(): array
    {
        return [
            'monthName' => Carbon::create($this->year, $this->month, 1)->translatedFormat('F Y'),
            'calendarDays' => $this->buildCalendarDays(),
            'dayHeaders' => $this->getDayHeaders(),
            'bookedDates' => $this->bookedDates,
        ];
    }
}; ?>

<div>
    <!-- Calendar Header -->
    <div class="flex items-center justify-between mb-4">
        <flux:button size="sm" wire:click="previousMonth" variant="ghost">
            <flux:icon name="chevron-{{ app()->getLocale() === 'ar' ? 'right' : 'left' }}" class="size-5" />
        </flux:button>

        <flux:heading size="lg" class="text-body">{{ $monthName }}</flux:heading>

        <flux:button size="sm" wire:click="nextMonth" variant="ghost">
            <flux:icon name="chevron-{{ app()->getLocale() === 'ar' ? 'left' : 'right' }}" class="size-5" />
        </flux:button>
    </div>

    <!-- Day Headers -->
    <div class="grid grid-cols-7 gap-1 mb-2" dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
        @foreach($dayHeaders as $day)
            <div class="text-center text-sm font-semibold text-zinc-600 dark:text-zinc-400">
                {{ __("calendar.{$day}") }}
            </div>
        @endforeach
    </div>

    <!-- Calendar Grid -->
    <div class="calendar-grid" dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
        @foreach($calendarDays as $dayData)
            @if($dayData === null)
                <div class="calendar-cell"></div>
            @else
                <button
                    wire:click="selectDate('{{ $dayData['date'] }}')"
                    @class([
                        'calendar-cell rounded-lg text-center transition-colors font-medium min-h-[44px]',
                        'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400 dark:hover:bg-emerald-900/50' => $dayData['status'] === 'available',
                        'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400 dark:hover:bg-amber-900/50' => $dayData['status'] === 'partial',
                        'bg-sky-100 text-sky-700 cursor-not-allowed dark:bg-sky-900/30 dark:text-sky-400' => $dayData['status'] === 'user_booked',
                        'bg-zinc-100 text-zinc-400 cursor-not-allowed dark:bg-zinc-800 dark:text-zinc-600' => in_array($dayData['status'], ['past', 'closed', 'blocked', 'full']),
                        'ring-2 ring-amber-500 dark:ring-amber-400' => $selectedDate === $dayData['date'],
                    ])
                    @disabled(in_array($dayData['status'], ['past', 'closed', 'blocked', 'full', 'user_booked']))
                >
                    {{ $dayData['day'] }}
                </button>
            @endif
        @endforeach
    </div>

    <!-- Time Slots -->
    @if($selectedDate)
        <div class="mt-6">
            <flux:heading size="sm" class="mb-3 text-body">
                {{ __('booking.available_times') }} -
                {{ \Carbon\Carbon::parse($selectedDate)->translatedFormat('d M Y') }}
            </flux:heading>

            @if(count($availableSlots) > 0)
                <div class="time-slots-grid">
                    @foreach($availableSlots as $slot)
                        <button
                            wire:click="$parent.selectSlot('{{ $selectedDate }}', '{{ $slot }}')"
                            class="time-slot-btn rounded-lg border border-amber-500 text-amber-600 hover:bg-amber-500 hover:text-white transition-colors dark:border-amber-400 dark:text-amber-400 dark:hover:bg-amber-500 dark:hover:text-white"
                        >
                            {{ \Carbon\Carbon::parse($slot)->format('g:i A') }}
                        </button>
                    @endforeach
                </div>
            @else
                <p class="text-zinc-500 dark:text-zinc-400">{{ __('booking.no_slots_available') }}</p>
            @endif
        </div>
    @endif

    <!-- Legend -->
    <div class="flex flex-wrap gap-4 mt-6 text-sm">
        <div class="flex items-center gap-2">
            <div class="w-4 h-4 rounded bg-emerald-100 dark:bg-emerald-900/30"></div>
            <span class="text-zinc-600 dark:text-zinc-400">{{ __('booking.available') }}</span>
        </div>
        <div class="flex items-center gap-2">
            <div class="w-4 h-4 rounded bg-amber-100 dark:bg-amber-900/30"></div>
            <span class="text-zinc-600 dark:text-zinc-400">{{ __('booking.partial') }}</span>
        </div>
        @if(count($bookedDates) > 0)
            <div class="flex items-center gap-2">
                <div class="w-4 h-4 rounded bg-sky-100 dark:bg-sky-900/30"></div>
                <span class="text-zinc-600 dark:text-zinc-400">{{ __('booking.user_booked') }}</span>
            </div>
        @endif
        <div class="flex items-center gap-2">
            <div class="w-4 h-4 rounded bg-zinc-100 dark:bg-zinc-800"></div>
            <span class="text-zinc-600 dark:text-zinc-400">{{ __('booking.unavailable') }}</span>
        </div>
    </div>
</div>
