import type { DashboardAvailability, DashboardAvailabilityDay } from '@admin/types/dashboard';
import { router } from '@inertiajs/react';
import { useEffect, useMemo, useState } from 'react';

const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];

type AvailabilityCalendarProps = {
    availability: DashboardAvailability;
};

function dayTone(day: DashboardAvailabilityDay): string {
    if (day.occupied === 0) {
        return 'bg-success/10';
    }

    if (day.available === 0) {
        return 'bg-danger/10';
    }

    return 'bg-warning/10';
}

function formatDay(date: string): string {
    return new Date(`${date}T00:00:00`).toLocaleDateString('en-GB', {
        weekday: 'long',
        day: 'numeric',
        month: 'long',
    });
}

export function AvailabilityCalendar({ availability }: AvailabilityCalendarProps) {
    const initial = availability.days.some((day) => day.date === availability.today)
        ? availability.today
        : (availability.days[0]?.date ?? availability.today);
    const [selected, setSelected] = useState(initial);

    useEffect(() => {
        setSelected(initial);
    }, [initial]);

    const selectedDay = availability.days.find((day) => day.date === selected) ?? availability.days[0];
    const arrivals = useMemo(
        () => availability.stays.filter((stay) => stay.checkIn === selected).length,
        [availability.stays, selected],
    );
    const departures = useMemo(
        () => availability.stays.filter((stay) => stay.checkOut === selected).length,
        [availability.stays, selected],
    );

    function openMonth(month: string): void {
        router.get(route('dashboard'), { month }, { preserveScroll: true, preserveState: true, only: ['availability'] });
    }

    return (
        <div className="grid grid-cols-1 gap-6 xl:grid-cols-12">
            <div className="xl:col-span-7">
                <div className="mb-4 flex items-center justify-between gap-3">
                    <button type="button" className="ti-btn ti-btn-sm ti-btn-outline-primary" onClick={() => openMonth(availability.prev)}>
                        Previous
                    </button>
                    <h6 className="mb-0 text-base font-semibold">{availability.label}</h6>
                    <button type="button" className="ti-btn ti-btn-sm ti-btn-outline-primary" onClick={() => openMonth(availability.next)}>
                        Next
                    </button>
                </div>
                <div className="mb-3 flex flex-wrap gap-3 text-xs text-gray-500 dark:text-white/60">
                    <span className="inline-flex items-center gap-1"><span className="inline-block h-2.5 w-2.5 rounded-sm bg-success/40" /> Free</span>
                    <span className="inline-flex items-center gap-1"><span className="inline-block h-2.5 w-2.5 rounded-sm bg-warning/40" /> Partly booked</span>
                    <span className="inline-flex items-center gap-1"><span className="inline-block h-2.5 w-2.5 rounded-sm bg-danger/40" /> Full</span>
                </div>
                <div className="grid grid-cols-7 gap-1.5 text-center text-xs text-gray-500 dark:text-white/50">
                    {weekdays.map((day) => (
                        <div key={day} className="py-1 font-medium">
                            {day}
                        </div>
                    ))}
                    {Array.from({ length: availability.startOffset }, (_, index) => (
                        <div key={`pad-${index}`} />
                    ))}
                    {availability.days.map((day) => {
                        const dayNumber = Number(day.date.slice(8));
                        const isSelected = day.date === selected;
                        const isToday = day.date === availability.today;

                        return (
                            <button
                                key={day.date}
                                type="button"
                                onClick={() => setSelected(day.date)}
                                className={`rounded-sm px-1 py-2 text-left transition ${dayTone(day)} ${isSelected ? 'ring-2 ring-primary' : ''}`}
                            >
                                <span className={`block text-sm text-gray-800 dark:text-white ${isToday ? 'font-semibold' : ''}`}>
                                    {dayNumber}
                                </span>
                                <span className="block text-[11px] text-gray-600 dark:text-white/70">
                                    {day.available} free
                                </span>
                            </button>
                        );
                    })}
                </div>
            </div>
            <div className="xl:col-span-5">
                {selectedDay ? (
                    <>
                        <div className="mb-3">
                            <h6 className="mb-1 text-base font-semibold">{formatDay(selectedDay.date)}</h6>
                            <p className="mb-0 text-sm text-gray-500 dark:text-white/60">
                                {selectedDay.available} free · {selectedDay.occupied} occupied
                                {arrivals > 0 ? ` · ${arrivals} arriving` : ''}
                                {departures > 0 ? ` · ${departures} leaving` : ''}
                            </p>
                        </div>
                        <div className="max-h-[28rem] overflow-auto rounded-sm border border-gray-100 dark:border-white/10">
                            <table className="ti-custom-table ti-custom-table-head mb-0 w-full">
                                <thead>
                                    <tr>
                                        <th scope="col" className="!text-start">
                                            Number
                                        </th>
                                        <th scope="col" className="!text-start">
                                            Room
                                        </th>
                                        <th scope="col" className="!text-start">
                                            Night
                                        </th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {availability.units.length === 0 ? (
                                        <tr>
                                            <td colSpan={3} className="py-8 text-center text-gray-500">
                                                No room numbers yet.
                                            </td>
                                        </tr>
                                    ) : (
                                        availability.units.map((unit) => {
                                            const stay = availability.stays.find(
                                                (item) => item.unitId === unit.id && item.checkIn <= selected && item.checkOut > selected,
                                            );

                                            return (
                                                <tr key={unit.id}>
                                                    <td className="font-medium">{unit.number}</td>
                                                    <td>{unit.room}</td>
                                                    <td>
                                                        {stay ? (
                                                            <span>
                                                                <span className="block">{stay.guest}</span>
                                                                <span className="text-xs text-gray-500">{stay.statusLabel}</span>
                                                            </span>
                                                        ) : !unit.active ? (
                                                            <span className="badge bg-secondary/10 text-secondary">Closed</span>
                                                        ) : (
                                                            <span className="badge bg-success/10 text-success">Available</span>
                                                        )}
                                                    </td>
                                                </tr>
                                            );
                                        })
                                    )}
                                </tbody>
                            </table>
                        </div>
                    </>
                ) : null}
            </div>
        </div>
    );
}
