import { Head, router } from '@inertiajs/react';
import { ArrowRight } from 'lucide-react';
import { useState } from 'react';
import type { TimeValue } from '@/components/booking/calendar-utils';
import {
    combine,
    isSameDay,
    pad,
    startOfDay,
} from '@/components/booking/calendar-utils';
import DatePickerCard from '@/components/booking/date-picker-card';
import PageIntro from '@/components/booking/page-intro';
import TimeSlotCard from '@/components/booking/time-slot-card';
import TransferDurationCard from '@/components/booking/transfer-duration-card';
import TripSummaryBar from '@/components/booking/trip-summary-bar';
import SiteFooter from '@/components/home/site-footer';
import SiteHeader from '@/components/home/site-header';
import { Spinner } from '@/components/ui/spinner';
import { update } from '@/routes/booking/schedule';
import type { TripSummary } from '@/types/booking';

type Errors = Partial<Record<'date' | 'time', string>>;

function formatDeadline(date: Date): string {
    const day = date.toLocaleDateString('en-US', {
        month: 'short',
        day: 'numeric',
    });
    const time = date.toLocaleTimeString('en-US', {
        hour: '2-digit',
        minute: '2-digit',
    });

    return `${day}, ${time}`;
}

function earliestSlot(): TimeValue {
    const soon = new Date(Date.now() + 60 * 60 * 1000);
    const minutes = Math.ceil(soon.getMinutes() / 15) * 15;

    return minutes === 60
        ? { hour: (soon.getHours() + 1) % 24, minute: 0 }
        : { hour: soon.getHours(), minute: minutes };
}

function initialSelection(
    pickupAt: string | null,
    pickupDate: string | null,
): {
    date: Date;
    time: TimeValue;
} {
    if (pickupAt) {
        const [day, clock] = pickupAt.split(' ');
        const [year, month, date] = day.split('-').map(Number);
        const [hour, minute] = clock.split(':').map(Number);

        return {
            date: new Date(year, month - 1, date),
            time: { hour, minute },
        };
    }

    const today = startOfDay(new Date());
    const earliest = earliestSlot();

    if (pickupDate) {
        const [year, month, date] = pickupDate.split('-').map(Number);
        const chosen = new Date(year, month - 1, date);

        if (chosen > today) {
            return { date: chosen, time: { hour: 9, minute: 0 } };
        }
    }

    const rollsOver = earliest.hour < new Date().getHours();

    return {
        date: rollsOver
            ? new Date(
                  today.getFullYear(),
                  today.getMonth(),
                  today.getDate() + 1,
              )
            : today,
        time: earliest,
    };
}

export default function BookingSchedule({ trip }: { trip: TripSummary }) {
    const [today] = useState(() => startOfDay(new Date()));
    const [initial] = useState(() =>
        initialSelection(trip.pickup_at, trip.pickup_date),
    );
    const [date, setDate] = useState(initial.date);
    const [time, setTime] = useState<TimeValue>(initial.time);
    const [errors, setErrors] = useState<Errors>({});
    const [processing, setProcessing] = useState(false);

    const deadline = combine(date, time);
    deadline.setHours(deadline.getHours() - 2);

    const title = trip.destination
        ? `${trip.pickup} to ${trip.destination}`
        : trip.pickup;

    const submit = () => {
        router.put(
            update.url(),
            {
                date: `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`,
                time: `${pad(time.hour)}:${pad(time.minute)}`,
            },
            {
                onStart: () => setProcessing(true),
                onFinish: () => setProcessing(false),
                onError: (validationErrors) => setErrors(validationErrors),
            },
        );
    };

    return (
        <>
            <Head title="Date & Time Select" />
            <div className="min-h-screen bg-mist font-google text-navy dark:bg-ink dark:text-white">
                <SiteHeader variant="solid" />

                <main className="mx-auto max-w-7xl px-4 pt-10 pb-20 sm:px-6 lg:px-10 lg:pt-16">
                    <PageIntro
                        title="Date & Time Select"
                        breadcrumbs={['Booking', title]}
                    />

                    <TripSummaryBar trip={trip} />

                    <div className="mt-12 grid items-start gap-5 lg:grid-cols-[1.45fr_1fr]">
                        <DatePickerCard
                            today={today}
                            selected={date}
                            onSelect={setDate}
                            cancellationDeadline={formatDeadline(deadline)}
                            error={errors.date}
                        />
                        <TimeSlotCard
                            value={time}
                            onChange={setTime}
                            earliest={
                                isSameDay(date, today) ? earliestSlot() : null
                            }
                            durationMinutes={
                                trip.estimate?.duration_minutes ?? null
                            }
                            error={errors.time}
                        />
                    </div>

                    <div className="mt-5">
                        <TransferDurationCard trip={trip} />
                    </div>

                    <div className="mt-8 flex justify-end">
                        <button
                            type="button"
                            onClick={submit}
                            disabled={processing}
                            className="flex w-full items-center justify-center gap-2 rounded-lg bg-gold px-8 py-3.5 text-base font-semibold text-white transition-colors hover:bg-gold-dark disabled:opacity-70 sm:w-auto"
                        >
                            {processing && <Spinner />}
                            Continue to vehicles
                            <ArrowRight className="size-4" />
                        </button>
                    </div>
                </main>

                <SiteFooter className="bg-mist dark:bg-ink" />
            </div>
        </>
    );
}
