import * as DialogPrimitive from '@radix-ui/react-dialog';
import { router } from '@inertiajs/react';
import { X } from 'lucide-react';
import type { ComponentProps, FormEvent, ReactNode } from 'react';
import { useState } from 'react';
import PlaceAutocomplete from '@/components/booking/place-autocomplete';
import InputError from '@/components/input-error';
import {
    Dialog,
    DialogClose,
    DialogDescription,
    DialogOverlay,
    DialogPortal,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';
import { Spinner } from '@/components/ui/spinner';
import { search } from '@/routes/booking';
import type { PlaceValue } from '@/types/booking';
import { emptyPlace } from '@/types/booking';

const inputClass =
    'w-full rounded-lg border border-navy/10 px-3 py-2.5 text-sm text-navy outline-none placeholder:text-gray-400 focus:border-gold focus:ring-2 focus:ring-gold/20';

type Errors = Partial<Record<string, string>>;

function Field({
    id,
    label,
    error,
    children,
}: {
    id: string;
    label: string;
    error?: string;
    children: ReactNode;
}) {
    return (
        <div>
            <label htmlFor={id} className="text-xs text-navy">
                {label}
            </label>
            <div className="mt-1.5">{children}</div>
            <InputError message={error} className="mt-1 text-xs" />
        </div>
    );
}

function TextInput(props: ComponentProps<'input'>) {
    return <input className={inputClass} {...props} />;
}

export default function GuestBookingDialog({
    children,
}: {
    children: ReactNode;
}) {
    const [open, setOpen] = useState(false);
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');
    const [flight, setFlight] = useState('');
    const [pickup, setPickup] = useState<PlaceValue>(emptyPlace());
    const [destination, setDestination] = useState<PlaceValue>(emptyPlace());
    const [errors, setErrors] = useState<Errors>({});
    const [processing, setProcessing] = useState(false);

    const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();

        router.post(
            search.url(),
            {
                service_type: 'airport',
                pickup,
                destination,
                passengers: 1,
                bags: 1,
                guest: { name, email, flight: flight || null },
            },
            {
                onStart: () => setProcessing(true),
                onFinish: () => setProcessing(false),
                onError: (validationErrors) => setErrors(validationErrors),
            },
        );
    };

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>{children}</DialogTrigger>
            <DialogPortal>
                <DialogOverlay className="bg-navy/70" />
                <DialogPrimitive.Content className="fixed top-1/2 left-1/2 z-50 max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-xl bg-white font-google shadow-2xl duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95">
                    <div className="flex items-center justify-between border-b border-navy/10 px-5 py-4">
                        <DialogTitle className="text-lg font-semibold text-navy">
                            Book as a guest
                        </DialogTitle>
                        <DialogClose
                            className="rounded-md p-1 text-gray-400 transition-colors hover:text-navy"
                            aria-label="Close"
                        >
                            <X className="size-4" />
                        </DialogClose>
                    </div>

                    <DialogDescription className="px-5 pt-4 text-xs text-gray-500">
                        No account needed. We will send your booking details to
                        this email address.
                    </DialogDescription>

                    <form onSubmit={handleSubmit} className="space-y-4 p-5">
                        <Field
                            id="guest_name"
                            label="Full Name"
                            error={errors['guest.name']}
                        >
                            <TextInput
                                id="guest_name"
                                value={name}
                                onChange={(event) =>
                                    setName(event.target.value)
                                }
                                placeholder="John Doe"
                                autoComplete="name"
                                required
                            />
                        </Field>
                        <Field
                            id="guest_email"
                            label="Email Address"
                            error={errors['guest.email']}
                        >
                            <TextInput
                                id="guest_email"
                                type="email"
                                value={email}
                                onChange={(event) =>
                                    setEmail(event.target.value)
                                }
                                placeholder="you@example.com"
                                autoComplete="email"
                                required
                            />
                        </Field>
                        <Field
                            id="guest_pickup"
                            label="Pickup Address"
                            error={errors['pickup.address']}
                        >
                            <PlaceAutocomplete
                                id="guest_pickup"
                                value={pickup}
                                onChange={setPickup}
                                placeholder="123 Main St, New York, NY"
                                inputClassName={inputClass}
                                currentLocation
                                required
                            />
                        </Field>
                        <Field
                            id="guest_destination"
                            label="Destination"
                            error={errors['destination.address']}
                        >
                            <PlaceAutocomplete
                                id="guest_destination"
                                value={destination}
                                onChange={setDestination}
                                placeholder="JFK International Airport"
                                inputClassName={inputClass}
                                required
                            />
                        </Field>
                        <Field
                            id="guest_flight"
                            label="Flight Details (Optional)"
                            error={errors['guest.flight']}
                        >
                            <TextInput
                                id="guest_flight"
                                value={flight}
                                onChange={(event) =>
                                    setFlight(event.target.value)
                                }
                                placeholder="Flight DL123 arriving 14:30"
                            />
                        </Field>

                        <button
                            type="submit"
                            disabled={processing}
                            className="mt-2 flex w-full items-center justify-center gap-2 rounded-lg bg-gold py-3 text-sm font-medium text-white transition-colors hover:bg-gold-dark disabled:opacity-70"
                        >
                            {processing && <Spinner />}
                            Continue to date &amp; time
                        </button>
                    </form>
                </DialogPrimitive.Content>
            </DialogPortal>
        </Dialog>
    );
}
