import { Head, Link, router, useForm, usePage } from '@inertiajs/react';
import { usePublicHeader } from '@/components/public-header';
import {
    ArrowRight,
    CalendarDays,
    Car,
    CheckCircle2,
    ChevronDown,
    ClipboardList,
    Clock,
    CreditCard,
    ExternalLink,
    KeyRound,
    LayoutDashboard,
    LogOut,
    Mail,
    Maximize2,
    Menu,
    Minimize2,
    Phone,
    MapPin,
    MapPinCheck,
    MapPinHouse,
    Plus,
    RotateCcw,
    Search,
    ShieldCheck,
    Sparkles,
    Star,
    Trash2,
    User,
    X,
} from 'lucide-react';
import { QRCodeSVG } from 'qrcode.react';
import { type FormEvent, useEffect, useState } from 'react';
import { BookingListCard } from '@/components/booking/booking-list-card';
import { DateStrip } from '@/components/booking/date-strip';
import { TimeSlotGrid } from '@/components/booking/time-slot-grid';
import {
    formatBookingDate,
} from '@/lib/booking-timezones';
import { useBookingDateTimeFormatters } from '@/hooks/use-booking-timezone';
import { StatusBadge } from '@/components/status-badge';
import { ThemeToggle } from '@/components/theme-toggle';
import { useBookingListGlobalExpanded, BOOKING_LIST_EXPANDED_KEYS } from '@/hooks/use-booking-list-global-expanded';
import { Button, buttonVariants } from '@/components/ui/button';
import { serviceStatusBorderClass } from '@/lib/service-status-border';
import { cn, formatUSPhone } from '@/lib/utils';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { NativeSelect } from '@/components/ui/native-select';
import type { User as AuthUser } from '@/types/auth';

/* ── Types ───────────────────────────────────────────── */

type Section = 'overview' | 'profile' | 'bookings' | 'booking-detail' | 'vehicles' | 'cancellations';

const VALID_SECTIONS: Section[] = ['overview', 'profile', 'bookings', 'booking-detail', 'vehicles', 'cancellations'];

function hashToSection(hash: string): Section {
    const s = hash.replace('#', '') as Section;

    return VALID_SECTIONS.includes(s) ? s : 'overview';
}

type BookingRow = {
    id: number;
    uuid: string;
    payment_status: string;
    service_status: string;
    service_type?: 'mobile' | 'fixed' | null;
    scheduled_at: string;
    created_at?: string | null;
    total: number;
    amount_paid: number;
    balance_due_cents?: number;
    payment_url?: string | null;
    vehicle_id?: number | null;
    vehicle?: { make: string; model: string; year: number; size?: string; color?: string | null } | null;
    package?: { id: number; name: string } | null;
    addons?: Array<{ id: number; name: string; pivot: { price: number } }> | null;
    location?: { name: string; address: string | null; city: string | null; state: string | null; zip: string | null } | null;
    service_address?: string | null;
    service_city?: string | null;
    service_state?: string | null;
    service_zip?: string | null;
    can_edit?: boolean;
    can_reschedule?: boolean;
    can_cancel?: boolean;
};

type VehicleRow = {
    id: number;
    make: string;
    model: string;
    year: number;
    color: string | null;
    size: string;
    is_default: boolean;
};

type WashBayLocation = {
    id: number;
    name: string;
    address: string | null;
    city: string | null;
    state: string | null;
    zip: string | null;
};

type BookingSettings = {
    customer_can_edit: boolean;
    customer_can_reschedule: boolean;
    customer_can_cancel: boolean;
};

type Props = {
    bookings: BookingRow[];
    vehicles: VehicleRow[];
    defaultLocation: WashBayLocation | null;
    washBayLocations: WashBayLocation[];
    membershipPlans: unknown[];
    activeMembership: unknown | null;
    apiTokens: unknown[];
    createdApiToken: string | null;
    bookingSettings: BookingSettings;
};

/* ── Helpers ─────────────────────────────────────────── */

type ClosedRange = { start_date: string; end_date: string; label: string | null };

function toDateKey(date: Date): string {
    const pad = (n: number) => String(n).padStart(2, '0');
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
}

function initials(name: string) {
    return name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase();
}

function fmtBooked(iso: string) {
    const d = new Date(iso);
    const m = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    const y = String(d.getFullYear()).slice(-2);
    const raw = d.getHours();
    const ampm = raw >= 12 ? 'pm' : 'am';
    const h = raw % 12 || 12;
    const min = String(d.getMinutes()).padStart(2, '0');

    return `${m}-${day}-${y} ${h}:${min}${ampm}`;
}

function fmtLocationAddress(location: WashBayLocation): string | null {
    if (!location.address) {
        return null;
    }

    let line = location.address;
    if (location.city) {
        line += `, ${location.city}`;
    }
    if (location.state) {
        line += `, ${location.state}`;
    }
    if (location.zip) {
        line += ` ${location.zip}`;
    }

    return line;
}

/* ── Field ───────────────────────────────────────────── */

function Field({ label, children, error }: { label: string; children: React.ReactNode; error?: string }) {
    return (
        <div className="flex flex-col gap-1.5">
            <Label className="text-sm font-medium">{label}</Label>
            {children}
            {error && <p className="text-xs text-destructive">{error}</p>}
        </div>
    );
}

/* ── Main component ──────────────────────────────────── */

function ActiveNowCard({
    serviceStatus,
    uuid,
    total,
    scheduledDate,
    scheduledTime,
    vehicleSize,
    vehicleLabel,
    packageName,
    addons,
    onViewDetails,
}: {
    serviceStatus: string;
    uuid: string;
    total: number;
    scheduledDate: string;
    scheduledTime: string;
    vehicleSize: string | null;
    vehicleLabel: string | null;
    packageName: string | null;
    addons?: Array<{ id: number; name: string; pivot: { price: number } }> | null;
    onViewDetails: () => void;
}) {
    const [open, setOpen] = useState(false);
    const addonTotal = (addons ?? []).reduce((sum, a) => sum + a.pivot.price, 0);
    const packagePrice = total - addonTotal;

    return (
        <div
            className={cn(
                'overflow-hidden rounded-2xl border border-l-[3px] bg-card shadow-sm',
                serviceStatusBorderClass(serviceStatus),
            )}
        >
            <button
                type="button"
                onClick={() => setOpen((v) => !v)}
                className="w-full bg-muted/40 px-4 py-3 text-sm transition-colors hover:bg-muted/60"
            >
                {/* Row 1: status + ping + booking # on left, total + chevron on right */}
                <div className="flex items-start justify-between gap-2">
                    <div className="flex flex-col items-start gap-1">
                        <div className="flex items-center gap-1.5">
                            <span className="relative flex size-2.5 shrink-0">
                                <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-orange-400 opacity-75" />
                                <span className={`relative inline-flex size-2.5 rounded-full ${serviceStatus === 'in_progress' ? 'bg-orange-500' : 'bg-teal-500'}`} />
                            </span>
                            <StatusBadge status={serviceStatus} />
                        </div>
                        <p className="font-mono text-xs text-muted-foreground">
                            #{uuid.slice(0, 8).toUpperCase()}
                        </p>
                    </div>
                    <div className="flex items-center gap-2">
                        <p className="font-bold text-primary">${(total / 100).toFixed(2)}</p>
                        <ChevronDown
                            className={cn(
                                'size-4 shrink-0 text-muted-foreground transition-transform duration-200',
                                open && 'rotate-180',
                            )}
                        />
                    </div>
                </div>

                {/* Row 2: 2×2 grid — Package | Vehicle, Date | Time */}
                <div className="mt-3 grid grid-cols-2 gap-2 text-left">
                    <div>
                        <p className="text-xs text-muted-foreground">Package</p>
                        <p className="truncate text-sm font-medium">{packageName ?? 'Car Wash'}</p>
                    </div>
                    <div>
                        <p className="text-xs text-muted-foreground">Vehicle</p>
                        {vehicleSize ? (
                            <>
                                <p className="text-sm font-medium capitalize">{vehicleSize}</p>
                                {vehicleLabel ? (
                                    <p className="truncate text-xs text-muted-foreground">{vehicleLabel}</p>
                                ) : null}
                            </>
                        ) : (
                            <p className="text-sm font-medium text-muted-foreground">—</p>
                        )}
                    </div>
                    <div>
                        <p className="text-xs text-muted-foreground">Date</p>
                        <p className="text-sm font-medium">{scheduledDate}</p>
                    </div>
                    <div>
                        <p className="text-xs text-muted-foreground">Time</p>
                        <p className="text-sm font-medium">{scheduledTime}</p>
                    </div>
                </div>
            </button>

            {open ? (
                <div className="border-t px-4 py-3">
                    <div className="space-y-1">
                        <div className="flex items-start justify-between gap-2">
                            <div>
                                <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">Package</p>
                                <p className="font-semibold">{packageName ?? 'Car Wash'}</p>
                            </div>
                            <p className="shrink-0 font-medium">${(packagePrice / 100).toFixed(2)}</p>
                        </div>
                        {(addons ?? []).map((addon) => (
                            <div key={addon.id} className="flex items-center justify-between gap-2">
                                <p className="text-sm text-muted-foreground">+ {addon.name}</p>
                                <p className="shrink-0 text-sm text-muted-foreground">
                                    ${(addon.pivot.price / 100).toFixed(2)}
                                </p>
                            </div>
                        ))}
                    </div>
                    <button
                        type="button"
                        onClick={onViewDetails}
                        className="mt-3 w-full rounded-lg border px-3 py-2 text-sm font-medium transition-colors hover:bg-muted"
                    >
                        View details
                    </button>
                </div>
            ) : null}
        </div>
    );
}

export default function CustomerPortal({
    bookings,
    vehicles,
    defaultLocation,
    washBayLocations,
}: Props) {
    const { auth } = usePage().props as { auth?: { user?: AuthUser } };
    const user = auth?.user;
    const { brandName } = usePublicHeader();
    const { timezone, formatDate, formatTime } = useBookingDateTimeFormatters();

    const [section, setSection] = useState<Section>(() => hashToSection(window.location.hash));
    const [sidebarOpen, setSidebarOpen] = useState(false);
    const [selectedBookingId, setSelectedBookingId] = useState<number | null>(null);
    const [showVehicleForm, setShowVehicleForm] = useState(false);
    const [bookingSearch, setBookingSearch] = useState('');
    const [sidebarSearch, setSidebarSearch] = useState('');
    const {
        allExpanded: allBookingsExpanded,
        expandRevision: bookingExpandRevision,
        toggleAllExpanded: toggleAllBookingsExpanded,
    } = useBookingListGlobalExpanded(BOOKING_LIST_EXPANDED_KEYS.customerPortalBookings);

    const upcomingBookings = bookings.filter(
        (b) => ['scheduled', 'arrived', 'in_progress'].includes(b.service_status),
    );
    const activeNowBookings = bookings.filter(
        (b) => b.service_status === 'arrived' || b.service_status === 'in_progress',
    );
    const cancelledBookings = bookings.filter((b) => b.service_status === 'cancelled');
    const noShowBookings = bookings.filter((b) => b.service_status === 'no_show');
    const selectedBooking = selectedBookingId
        ? bookings.find((b) => b.id === selectedBookingId) ?? null
        : null;

    /* Forms */
    const profileForm = useForm({
        name: user?.name ?? '',
        email: user?.email ?? '',
        phone: (user?.phone as string | undefined) ?? '',
        office_suite: (user?.office_suite as string | undefined) ?? '',
        cell: (user?.cell as string | undefined) ?? '',
    });
    const submitProfile = (e: FormEvent) => {
        e.preventDefault();
        profileForm.patch('/portal/profile', {
            preserveScroll: true,
            onSuccess: () => navigate('overview'),
        });
    };

    const locationForm = useForm({
        location_id: defaultLocation?.id?.toString() ?? '',
    });
    const submitDefaultLocation = (e: FormEvent) => {
        e.preventDefault();
        locationForm.post('/portal/default-location', {
            preserveScroll: true,
            onSuccess: () => navigate('overview'),
        });
    };

    const passwordForm = useForm({ current_password: '', password: '', password_confirmation: '' });
    const submitPassword = (e: FormEvent) => {
        e.preventDefault();
        passwordForm.put('/portal/password', {
            preserveScroll: true,
            onSuccess: () => {
                passwordForm.reset();
                navigate('overview');
            },
        });
    };

    const vehicleForm = useForm({
        make: '', model: '', year: new Date().getFullYear(), color: '', size: 'sedan',
    });
    const submitVehicle = (e: FormEvent) => {
        e.preventDefault();
        vehicleForm.post('/portal/vehicles', {
            onSuccess: () => { vehicleForm.reset(); setShowVehicleForm(false); },
        });
    };

    /* Reschedule */
    const [rescheduleId, setRescheduleId] = useState<number | null>(null);
    const [rescheduleLoading, setRescheduleLoading] = useState(false);
    const [rescheduleDate, setRescheduleDate] = useState<Date | null>(null);
    const [rescheduleTime, setRescheduleTime] = useState<string | null>(null);
    const [rescheduleSlots, setRescheduleSlots] = useState<Record<string, Record<string, number>>>({});
    const [rescheduleClosedRanges, setRescheduleClosedRanges] = useState<ClosedRange[]>([]);

    const closeReschedule = () => {
        setRescheduleId(null);
        setRescheduleDate(null);
        setRescheduleTime(null);
        setRescheduleSlots({});
        setRescheduleClosedRanges([]);
    };

    const openReschedule = (booking: BookingRow) => {
        setRescheduleId(booking.id);
        setRescheduleDate(null);
        setRescheduleTime(null);
        setRescheduleSlots({});
        setRescheduleClosedRanges([]);
        setRescheduleLoading(true);

        fetch(`/portal/bookings/${booking.id}/available-slots`, {
            headers: { Accept: 'application/json' },
        })
            .then((res) => res.json())
            .then((data: { availableSlotsByDate?: Record<string, Record<string, number>>; closedDateRanges?: ClosedRange[] }) => {
                setRescheduleSlots(data.availableSlotsByDate ?? {});
                setRescheduleClosedRanges(data.closedDateRanges ?? []);
            })
            .finally(() => setRescheduleLoading(false));
    };

    const rescheduleTimesForDay = rescheduleDate ? (rescheduleSlots[toDateKey(rescheduleDate)] ?? {}) : {};

    const submitReschedule = () => {
        if (!rescheduleId || !rescheduleDate || !rescheduleTime) return;

        const [hh, mm] = rescheduleTime.split(':').map(Number);
        const scheduled = new Date(rescheduleDate);
        scheduled.setHours(hh, mm, 0, 0);

        router.post(
            `/portal/bookings/${rescheduleId}/reschedule`,
            { scheduled_at: scheduled.toISOString() },
            { onSuccess: () => closeReschedule() },
        );
    };

    const handleCancel = (id: number) => {
        if (!window.confirm('Cancel this booking?')) return;
        router.post(`/portal/bookings/${id}/cancel`, { reason: 'customer_cancelled' });
    };

    const activeVehicleIds = new Set(
        bookings
            .filter((b) => ['scheduled', 'arrived', 'in_progress'].includes(b.service_status))
            .map((b) => b.vehicle_id)
            .filter((id): id is number => id != null),
    );

    const handleSetDefault = (id: number) => {
        router.post(`/portal/vehicles/${id}/set-default`);
    };

    const handleDeleteVehicle = (id: number) => {
        if (!window.confirm('Remove this vehicle from your account?')) return;
        router.delete(`/portal/vehicles/${id}`);
    };

    const openBookingDetail = (id: number) => {
        setSelectedBookingId(id);
        setSection('booking-detail');
    };

    useEffect(() => {
        const onHashChange = () => setSection(hashToSection(window.location.hash));
        window.addEventListener('hashchange', onHashChange);
        return () => window.removeEventListener('hashchange', onHashChange);
    }, []);

    const navigate = (s: Section) => {
        window.location.hash = s === 'overview' ? '' : s;
        setSection(s);
        setSidebarOpen(false);
    };

    /* ── Sidebar search index ── */
    const searchIndex = [
        { kind: 'nav' as const, id: 'overview' as Section,      label: 'Overview',       hint: 'Portal home',           Icon: LayoutDashboard },
        { kind: 'nav' as const, id: 'profile' as Section,       label: 'Personal Info',  hint: 'Profile & password',    Icon: User },
        { kind: 'nav' as const, id: 'bookings' as Section,      label: 'My Bookings',    hint: 'All appointments',      Icon: CalendarDays },
        { kind: 'nav' as const, id: 'vehicles' as Section,      label: 'My Vehicles',    hint: 'Registered vehicles',   Icon: Car },
        { kind: 'nav' as const, id: 'cancellations' as Section, label: 'Cancellations',  hint: 'Cancelled & missed',    Icon: RotateCcw },
        ...bookings.map((b) => ({
            kind: 'booking' as const,
            id: b.id,
            label: b.package?.name ?? 'Car Wash',
            hint: `#${b.uuid.slice(0, 8).toUpperCase()} · ${formatDate(b.scheduled_at)}`,
        })),
        ...vehicles.map((v) => ({
            kind: 'vehicle' as const,
            id: v.id,
            label: `${v.year} ${v.make} ${v.model}`,
            hint: v.size + (v.color ? ` · ${v.color}` : ''),
        })),
    ];

    type SidebarSearchItem = (typeof searchIndex)[number];

    const sidebarQ = sidebarSearch.toLowerCase().trim();
    const sidebarResults: SidebarSearchItem[] = sidebarQ
        ? searchIndex.filter(
              (item) =>
                  item.label.toLowerCase().includes(sidebarQ) ||
                  item.hint.toLowerCase().includes(sidebarQ),
          )
        : [];

    const handleSidebarSelect = (item: SidebarSearchItem) => {
        if (item.kind === 'nav') navigate(item.id);
        else if (item.kind === 'booking') openBookingDetail(item.id);
        else navigate('vehicles');
        setSidebarSearch('');
    };

    const NAV_PORTAL = [
        { id: 'overview' as Section,      label: 'Overview',      Icon: LayoutDashboard },
        { id: 'profile' as Section,       label: 'Personal Info', Icon: User },
    ];

    const NAV_ACCOUNT = [
        { id: 'bookings' as Section,      label: 'My Bookings',   Icon: CalendarDays, badge: upcomingBookings.length },
        { id: 'vehicles' as Section,      label: 'My Vehicles',   Icon: Car,          badge: vehicles.length },
        { id: 'cancellations' as Section, label: 'Cancellations', Icon: RotateCcw,    badge: cancelledBookings.length + noShowBookings.length },
    ];

    const sidebarNavItemClass = (active: boolean) =>
        cn(
            'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors',
            active
                ? 'bg-primary font-medium text-primary-foreground'
                : 'text-muted-foreground hover:bg-primary/10 hover:text-primary',
        );

    /* ── Sidebar content ── */
    const sidebarContent = (
        <div className="flex h-full flex-col">
            {/* Logo */}
            <div className="flex h-14 shrink-0 items-center gap-2.5 border-b px-4">
                <button
                    type="button"
                    onClick={() => navigate('overview')}
                    className="flex items-center gap-2.5 transition-opacity hover:opacity-80"
                >
                    <div className="flex size-6 items-center justify-center rounded-lg bg-primary">
                        <Car className="size-4 text-primary-foreground" />
                    </div>
                    <span className="font-bold">{brandName}</span>
                </button>
                <div className="ml-auto">
                    <ThemeToggle />
                </div>
            </div>

            {/* User */}
            <button
                type="button"
                onClick={() => navigate('overview')}
                className="group flex w-full items-center gap-3 border-b px-4 py-3 text-left transition-colors hover:bg-primary/10"
            >
                <div className="flex size-9 shrink-0 items-center justify-center rounded-full bg-primary/10 text-sm font-bold text-primary transition-colors group-hover:bg-primary/15">
                    {user ? initials(user.name) : '?'}
                </div>
                <div className="min-w-0">
                    <p className="truncate text-sm font-semibold transition-colors group-hover:text-primary">
                        {user?.name}
                    </p>
                    <p className="truncate text-xs text-muted-foreground transition-colors group-hover:text-primary/80">
                        {user?.email}
                    </p>
                </div>
            </button>

            {/* Search */}
            <div className="border-b px-3 py-3">
                <div className="relative">
                    <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
                    <Input
                        type="text"
                        placeholder="Search bookings, vehicles…"
                        value={sidebarSearch}
                        onChange={(e) => setSidebarSearch(e.target.value)}
                        className="h-8 pl-8 pr-7 text-sm"
                    />
                    {sidebarSearch && (
                        <button
                            type="button"
                            onClick={() => setSidebarSearch('')}
                            className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                        >
                            <X className="size-3.5" />
                        </button>
                    )}
                </div>
            </div>

            {/* Nav or search results */}
            <div className="flex-1 overflow-y-auto px-3 py-3">
                {sidebarSearch ? (
                    sidebarResults.length === 0 ? (
                        <p className="px-2 py-6 text-center text-xs text-muted-foreground">
                            No results for "{sidebarSearch}"
                        </p>
                    ) : (
                        <div className="flex flex-col gap-3">
                            {(['nav', 'booking', 'vehicle'] as const).map((kind) => {
                                const group = sidebarResults.filter((r) => r.kind === kind);
                                if (group.length === 0) return null;
                                const groupLabel =
                                    kind === 'nav' ? 'Sections' : kind === 'booking' ? 'Bookings' : 'Vehicles';
                                return (
                                    <div key={kind}>
                                        <p className="mb-1 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                                            {groupLabel}
                                        </p>
                                        <div className="flex flex-col gap-0.5">
                                            {group.map((item) => (
                                                <button
                                                    key={`${item.kind}-${item.id}`}
                                                    type="button"
                                                    onClick={() => handleSidebarSelect(item)}
                                                    className="flex w-full flex-col rounded-lg px-3 py-2 text-left transition-colors hover:bg-accent/60"
                                                >
                                                    <span className="text-sm font-medium">{item.label}</span>
                                                    <span className="text-xs text-muted-foreground">{item.hint}</span>
                                                </button>
                                            ))}
                                        </div>
                                    </div>
                                );
                            })}
                        </div>
                    )
                ) : (
                    /* Normal grouped nav */
                    <div className="flex flex-col gap-5">
                        {/* Portal */}
                        <div>
                            <p className="mb-1 px-3 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                                Portal
                            </p>
                            <div className="flex flex-col gap-0.5">
                                {NAV_PORTAL.map(({ id, label, Icon }) => (
                                    <button
                                        key={id}
                                        type="button"
                                        onClick={() => navigate(id)}
                                        className={sidebarNavItemClass(section === id)}
                                    >
                                        <Icon className="size-4 shrink-0" />
                                        {label}
                                    </button>
                                ))}
                            </div>
                        </div>

                        {/* My Account */}
                        <div>
                            <p className="mb-1 px-3 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                                My Account
                            </p>
                            <div className="flex flex-col gap-0.5">
                                {NAV_ACCOUNT.map(({ id, label, Icon, badge }) => (
                                    <button
                                        key={id}
                                        type="button"
                                        onClick={() => navigate(id)}
                                        className={sidebarNavItemClass(section === id)}
                                    >
                                        <Icon className="size-4 shrink-0" />
                                        <span className="flex-1 text-left">{label}</span>
                                        {badge > 0 && (
                                            <span
                                                className={cn(
                                                    'flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[10px] font-semibold',
                                                    section === id
                                                        ? 'bg-primary-foreground/20 text-primary-foreground'
                                                        : 'bg-primary/10 text-primary',
                                                )}
                                            >
                                                {badge}
                                            </span>
                                        )}
                                    </button>
                                ))}
                            </div>
                        </div>

                        {/* Quick Actions */}
                        <div>
                            <p className="mb-1 px-3 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                                Quick Actions
                            </p>
                            <div className="flex flex-col gap-0.5">
                                <Link
                                    href="/book/location"
                                    className={sidebarNavItemClass(false)}
                                >
                                    <Sparkles className="size-4 shrink-0" />
                                    <span className="flex-1">Book a Wash</span>
                                    <ArrowRight className="size-3.5 opacity-50" />
                                </Link>
                            </div>
                        </div>
                    </div>
                )}
            </div>

            {/* Logout */}
            <div className="shrink-0 border-t px-3 py-3">
                <Button
                    variant="ghost"
                    className="w-full justify-center text-muted-foreground hover:text-foreground"
                    onClick={() => router.post('/logout')}
                >
                    <LogOut className="size-4" />
                    Logout
                </Button>
            </div>
        </div>
    );

    /* ── Overview ── */

    const overviewContent = (
        <div>
            {/* Currently being serviced */}
            {activeNowBookings.length > 0 && (
                <div className="mb-6 flex flex-col gap-3">
                    <div className="flex items-center gap-2">
                        <span className="relative flex size-2.5">
                            <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-orange-400 opacity-75" />
                            <span className="relative inline-flex size-2.5 rounded-full bg-orange-500" />
                        </span>
                        <h2 className="scroll-m-20 text-xl font-semibold tracking-tight">Your car is being serviced right now</h2>
                    </div>
                    <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                        {activeNowBookings.map((b) => {
                            const scheduledDate = b.scheduled_at
                                ? formatDate(b.scheduled_at)
                                : 'Date TBD';
                            const scheduledTime = b.scheduled_at
                                ? formatTime(b.scheduled_at)
                                : 'Time TBD';
                            const vehicleLabel = b.vehicle
                                ? `${b.vehicle.year} ${b.vehicle.make} ${b.vehicle.model}`
                                : null;

                            return (
                                <ActiveNowCard
                                    key={b.id}
                                    serviceStatus={b.service_status}
                                    uuid={b.uuid}
                                    total={b.total}
                                    scheduledDate={scheduledDate}
                                    scheduledTime={scheduledTime}
                                    vehicleSize={b.vehicle?.size ?? null}
                                    vehicleLabel={vehicleLabel}
                                    packageName={b.package?.name ?? null}
                                    addons={b.addons}
                                    onViewDetails={() => openBookingDetail(b.id)}
                                />
                            );
                        })}
                    </div>
                </div>
            )}

            {/* Benton grid: Bookings spans 2 cols on lg, full row on sm */}
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
                {/* My Bookings — wide */}
                <button
                    type="button"
                    onClick={() => navigate('bookings')}
                    className="group relative flex flex-col gap-5 rounded-2xl border bg-card p-6 text-left transition-all hover:border-primary hover:bg-primary hover:shadow-md sm:col-span-2 lg:col-span-2"
                >
                    {upcomingBookings.length > 0 && (
                        <span className="absolute right-4 top-4 rounded-full bg-primary px-2.5 py-0.5 text-xs font-semibold text-primary-foreground group-hover:bg-white/20 group-hover:text-white">
                            {upcomingBookings.length} upcoming
                        </span>
                    )}
                    <div className="flex size-10 items-center justify-center rounded-xl bg-primary/10 transition-colors group-hover:bg-white/20">
                        <CalendarDays className="size-5 text-primary transition-colors group-hover:text-white" />
                    </div>
                    <div>
                        <p className="font-semibold transition-colors group-hover:text-primary-foreground">My Bookings</p>
                        <p className="mt-1 text-sm text-muted-foreground transition-colors group-hover:text-primary-foreground/70">Check the status of your appointments or see past washes</p>
                    </div>
                </button>

                {/* Personal Info */}
                <button
                    type="button"
                    onClick={() => navigate('profile')}
                    className="group relative flex flex-col gap-5 rounded-2xl border bg-card p-6 text-left transition-all hover:border-primary hover:bg-primary hover:shadow-md"
                >
                    <div className="flex size-10 items-center justify-center rounded-xl bg-primary/10 transition-colors group-hover:bg-white/20">
                        <User className="size-5 text-primary transition-colors group-hover:text-white" />
                    </div>
                    <div>
                        <p className="font-semibold transition-colors group-hover:text-primary-foreground">Personal Info</p>
                        <p className="mt-1 text-sm text-muted-foreground transition-colors group-hover:text-primary-foreground/70">Update your details, email preferences or password</p>
                    </div>
                </button>

                {/* My Vehicles */}
                <button
                    type="button"
                    onClick={() => navigate('vehicles')}
                    className="group relative flex flex-col gap-5 rounded-2xl border bg-card p-6 text-left transition-all hover:border-primary hover:bg-primary hover:shadow-md"
                >
                    <div className="flex size-10 items-center justify-center rounded-xl bg-primary/10 transition-colors group-hover:bg-white/20">
                        <Car className="size-5 text-primary transition-colors group-hover:text-white" />
                    </div>
                    <div>
                        <p className="font-semibold transition-colors group-hover:text-primary-foreground">My Vehicles</p>
                        <p className="mt-1 text-sm text-muted-foreground transition-colors group-hover:text-primary-foreground/70">Manage your registered vehicles and sizes</p>
                    </div>
                </button>

                {/* Cancellations */}
                <button
                    type="button"
                    onClick={() => navigate('cancellations')}
                    className="group relative flex flex-col gap-5 rounded-2xl border bg-card p-6 text-left transition-all hover:border-primary hover:bg-primary hover:shadow-md"
                >
                    <div className="flex size-10 items-center justify-center rounded-xl bg-primary/10 transition-colors group-hover:bg-white/20">
                        <RotateCcw className="size-5 text-primary transition-colors group-hover:text-white" />
                    </div>
                    <div>
                        <p className="font-semibold transition-colors group-hover:text-primary-foreground">Cancellations</p>
                        <p className="mt-1 text-sm text-muted-foreground transition-colors group-hover:text-primary-foreground/70">Manage your cancelled appointments and refunds</p>
                    </div>
                </button>

                {/* Book CTA */}
                <Link
                    href="/book/location"
                    className="group relative flex flex-col gap-5 overflow-hidden rounded-2xl bg-primary p-6 text-primary-foreground transition-all hover:brightness-110 hover:shadow-md"
                >
                    <div className="flex size-10 items-center justify-center rounded-xl bg-white/15">
                        <Sparkles className="size-5" />
                    </div>
                    <div>
                        <p className="font-semibold">Book a Car Wash Now!</p>
                        <p className="mt-1 text-sm text-primary-foreground/70">Schedule your next wash in minutes</p>
                    </div>
                    <ArrowRight className="absolute bottom-6 right-6 size-5 opacity-50 transition-all group-hover:translate-x-1 group-hover:opacity-100" />
                </Link>
            </div>

            <div className="mt-6 flex flex-wrap items-center justify-between gap-4 rounded-2xl border p-6">
                <div>
                    <p className="font-semibold">Need assistance?</p>
                    <p className="mt-0.5 text-sm text-muted-foreground">
                        Our customer service is available Mon – Sun, 7 am to 7 pm
                    </p>
                </div>
                <Link
                    href="/"
                    className={cn(buttonVariants({ size: 'sm' }), 'gap-1.5')}
                >
                    Contact us
                    <ArrowRight className="size-3.5" />
                </Link>
            </div>
        </div>
    );

    /* ── Personal Info ── */
    const memberSince = user?.created_at
        ? new Date(user.created_at).toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
        : null;

    const profileContent = (
        <div className="space-y-6">
            {/* Identity header */}
            <div className="flex flex-col gap-5 rounded-2xl border bg-card p-6 sm:flex-row sm:items-center">
                <div className="flex size-16 shrink-0 items-center justify-center rounded-2xl bg-primary text-xl font-bold text-primary-foreground shadow-sm">
                    {user ? initials(user.name) : '?'}
                </div>
                <div className="min-w-0 flex-1">
                    <h1 className="truncate text-xl font-bold">{user?.name}</h1>
                    <p className="mt-0.5 truncate text-sm text-muted-foreground">{user?.email}</p>
                    <div className="mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground">
                        {memberSince && (
                            <span className="flex items-center gap-1">
                                <CalendarDays className="size-3.5" />
                                Member since {memberSince}
                            </span>
                        )}
                        <span className="flex items-center gap-1">
                            <CalendarDays className="size-3.5" />
                            {bookings.length} booking{bookings.length !== 1 ? 's' : ''}
                        </span>
                        <span className="flex items-center gap-1">
                            <Car className="size-3.5" />
                            {vehicles.length} vehicle{vehicles.length !== 1 ? 's' : ''}
                        </span>
                    </div>
                </div>
                <Button
                    size="sm"
                    variant="outline"
                    className="shrink-0 self-start sm:self-center"
                    onClick={() => navigate('bookings')}
                >
                    View bookings
                </Button>
            </div>

            {/* Profile form */}
            <section className="rounded-2xl border bg-card">
                <div className="flex items-center gap-3 border-b px-6 py-4">
                    <div className="flex size-8 items-center justify-center rounded-lg bg-primary/10">
                        <User className="size-4 text-primary" />
                    </div>
                    <div>
                        <h2 className="font-semibold">Profile Information</h2>
                        <p className="text-xs text-muted-foreground">Update your contact details and preferences</p>
                    </div>
                </div>
                <form onSubmit={submitProfile} className="p-6">
                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="sm:col-span-2">
                            <Field label="Full name" error={profileForm.errors.name}>
                                <div className="relative">
                                    <User className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                                    <Input
                                        name="name"
                                        placeholder="John Smith"
                                        autoComplete="name"
                                        className="pl-9"
                                        value={profileForm.data.name}
                                        onChange={(e) => profileForm.setData('name', e.target.value)}
                                    />
                                </div>
                            </Field>
                        </div>
                        <Field label="Cell" error={profileForm.errors.cell}>
                            <div className="relative">
                                <Phone className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                                <Input
                                    name="cell"
                                    type="tel"
                                    placeholder="(555) 000-0000"
                                    autoComplete="tel"
                                    className="pl-9"
                                    value={profileForm.data.cell}
                                    onChange={(e) => profileForm.setData('cell', formatUSPhone(e.target.value))}
                                />
                            </div>
                        </Field>
                        <Field label="Phone number" error={profileForm.errors.phone}>
                            <div className="relative">
                                <Phone className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                                <Input
                                    name="phone"
                                    type="tel"
                                    placeholder="(555) 000-0000"
                                    autoComplete="tel"
                                    className="pl-9"
                                    value={profileForm.data.phone}
                                    onChange={(e) => profileForm.setData('phone', formatUSPhone(e.target.value))}
                                />
                            </div>
                        </Field>
                        <div className="sm:col-span-2">
                            <Field label="Office / Suite Location" error={profileForm.errors.office_suite}>
                                <Input
                                    name="office_suite"
                                    placeholder="Suite 200, Building B"
                                    autoComplete="address-line2"
                                    value={profileForm.data.office_suite}
                                    onChange={(e) => profileForm.setData('office_suite', e.target.value)}
                                />
                            </Field>
                        </div>
                        <div className="sm:col-span-2">
                            <Field label="Email address" error={profileForm.errors.email}>
                                <div className="relative">
                                    <Mail className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                                    <Input
                                        name="email"
                                        type="email"
                                        placeholder="john@example.com"
                                        autoComplete="email"
                                        className="pl-9"
                                        value={profileForm.data.email}
                                        onChange={(e) => profileForm.setData('email', e.target.value)}
                                    />
                                </div>
                            </Field>
                        </div>
                    </div>
                    <div className="mt-5 flex items-center gap-3 border-t pt-5">
                        <Button type="submit" disabled={profileForm.processing}>
                            Save changes
                        </Button>
                        {profileForm.recentlySuccessful && (
                            <span className="flex items-center gap-1.5 text-sm text-green-600">
                                <CheckCircle2 className="size-4" /> Saved
                            </span>
                        )}
                    </div>
                </form>
            </section>

            {/* Default wash bay */}
            <section className="rounded-2xl border bg-card">
                <div className="flex items-center gap-3 border-b px-6 py-4">
                    <div className="flex size-8 items-center justify-center rounded-lg bg-primary/10">
                        <MapPinHouse className="size-4 text-primary" />
                    </div>
                    <div>
                        <h2 className="font-semibold">Default wash bay</h2>
                        <p className="text-xs text-muted-foreground">
                            Your preferred drop-off location for faster booking
                        </p>
                    </div>
                </div>
                <form onSubmit={submitDefaultLocation} className="p-6">
                    {defaultLocation ? (
                        <div className="mb-4 flex items-start gap-3 rounded-xl border bg-muted/30 p-4">
                            <div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10">
                                <MapPinCheck className="size-4 text-primary" />
                            </div>
                            <div className="min-w-0">
                                <p className="font-medium">{defaultLocation.name}</p>
                                {fmtLocationAddress(defaultLocation) && (
                                    <p className="mt-0.5 text-xs text-muted-foreground">
                                        {fmtLocationAddress(defaultLocation)}
                                    </p>
                                )}
                            </div>
                        </div>
                    ) : (
                        <p className="mb-4 text-sm text-muted-foreground">
                            No default location yet. Pick a wash bay below, or book once and we&apos;ll
                            remember your first site visit.
                        </p>
                    )}

                    <Field label="Preferred location" error={locationForm.errors.location_id}>
                        <NativeSelect
                            value={locationForm.data.location_id}
                            onChange={(e) => locationForm.setData('location_id', e.target.value)}
                            disabled={washBayLocations.length === 0}
                        >
                            <option value="">Select a wash bay…</option>
                            {washBayLocations.map((location) => (
                                <option key={location.id} value={String(location.id)}>
                                    {location.name}
                                    {location.city ? ` — ${location.city}` : ''}
                                </option>
                            ))}
                        </NativeSelect>
                    </Field>

                    {washBayLocations.length === 0 && (
                        <p className="mt-2 text-sm text-muted-foreground">
                            No wash bay locations are available right now.
                        </p>
                    )}

                    <div className="mt-5 flex items-center gap-3 border-t pt-5">
                        <Button
                            type="submit"
                            disabled={
                                locationForm.processing ||
                                !locationForm.data.location_id ||
                                washBayLocations.length === 0
                            }
                        >
                            Save location
                        </Button>
                        {locationForm.recentlySuccessful && (
                            <span className="flex items-center gap-1.5 text-sm text-green-600">
                                <CheckCircle2 className="size-4" /> Saved
                            </span>
                        )}
                    </div>
                </form>
            </section>

            {/* Security / password */}
            <section className="rounded-2xl border bg-card">
                <div className="flex items-center gap-3 border-b px-6 py-4">
                    <div className="flex size-8 items-center justify-center rounded-lg bg-amber-500/10">
                        <ShieldCheck className="size-4 text-amber-600 dark:text-amber-400" />
                    </div>
                    <div>
                        <h2 className="font-semibold">Security</h2>
                        <p className="text-xs text-muted-foreground">Changing your password will sign you out of other devices</p>
                    </div>
                </div>
                <form onSubmit={submitPassword} className="p-6">
                    <div className="grid gap-4 sm:grid-cols-2">
                        <div className="sm:col-span-2">
                            <Field label="Current password" error={passwordForm.errors.current_password}>
                                <div className="relative">
                                    <KeyRound className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                                    <Input
                                        type="password"
                                        placeholder="••••••••"
                                        autoComplete="current-password"
                                        className="pl-9"
                                        value={passwordForm.data.current_password}
                                        onChange={(e) => passwordForm.setData('current_password', e.target.value)}
                                    />
                                </div>
                            </Field>
                        </div>
                        <Field label="New password" error={passwordForm.errors.password}>
                            <Input
                                type="password"
                                placeholder="••••••••"
                                autoComplete="new-password"
                                value={passwordForm.data.password}
                                onChange={(e) => passwordForm.setData('password', e.target.value)}
                            />
                        </Field>
                        <Field label="Confirm new password" error={passwordForm.errors.password_confirmation}>
                            <Input
                                type="password"
                                placeholder="••••••••"
                                autoComplete="new-password"
                                value={passwordForm.data.password_confirmation}
                                onChange={(e) => passwordForm.setData('password_confirmation', e.target.value)}
                            />
                        </Field>
                    </div>
                    <div className="mt-5 flex items-center gap-3 border-t pt-5">
                        <Button type="submit" disabled={passwordForm.processing}>
                            Update password
                        </Button>
                        {passwordForm.recentlySuccessful && (
                            <span className="flex items-center gap-1.5 text-sm text-green-600">
                                <CheckCircle2 className="size-4" /> Updated
                            </span>
                        )}
                    </div>
                </form>
            </section>
        </div>
    );

    /* ── My Bookings ── */
    const sortedBookings = [...bookings].sort(
        (a, b) => new Date(b.scheduled_at).getTime() - new Date(a.scheduled_at).getTime(),
    );
    const q = bookingSearch.toLowerCase().trim();
    const filteredBookings = q
        ? sortedBookings.filter((b) => {
              const vehicle = b.vehicle
                  ? `${b.vehicle.size ?? ''} ${b.vehicle.make} ${b.vehicle.model}`.toLowerCase()
                  : '';
              return (
                  b.uuid.toLowerCase().includes(q) ||
                  (b.package?.name ?? '').toLowerCase().includes(q) ||
                  b.service_status.toLowerCase().includes(q) ||
                  formatDate(b.scheduled_at).toLowerCase().includes(q) ||
                  vehicle.includes(q)
              );
          })
        : sortedBookings;

    const bookingsContent = (
        <div>
            <div className="mb-5 flex items-start justify-between gap-4">
                <div>
                    <h1 className="text-2xl font-bold">My Bookings</h1>
                    {upcomingBookings.length > 0 && (
                        <p className="mt-1 flex items-center gap-1.5 text-sm text-muted-foreground">
                            <span className="inline-block size-1.5 rounded-full bg-primary" />
                            {upcomingBookings.length} upcoming
                        </p>
                    )}
                </div>
                <div className="flex shrink-0 items-center gap-2">
                    {filteredBookings.length > 0 ? (
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={toggleAllBookingsExpanded}
                        >
                            {allBookingsExpanded ? (
                                <>
                                    <Minimize2 className="size-4" />
                                    Collapse all
                                </>
                            ) : (
                                <>
                                    <Maximize2 className="size-4" />
                                    Expand all
                                </>
                            )}
                        </Button>
                    ) : null}
                    <span className="text-sm text-muted-foreground">
                        {bookings.length} total
                    </span>
                </div>
            </div>

            {/* Search */}
            {bookings.length > 0 && (
                <div className="relative mb-5">
                    <Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                    <Input
                        placeholder="Search by date, package, vehicle, status…"
                        value={bookingSearch}
                        onChange={(e) => setBookingSearch(e.target.value)}
                        className="pl-9"
                    />
                    {bookingSearch && (
                        <button
                            type="button"
                            onClick={() => setBookingSearch('')}
                            className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                        >
                            <X className="size-4" />
                        </button>
                    )}
                </div>
            )}

            {bookings.length === 0 ? (
                <div className="flex flex-col items-center gap-4 rounded-2xl border border-dashed py-12 text-center">
                    <CalendarDays className="size-10 text-muted-foreground/40" />
                    <div>
                        <p className="font-medium">No bookings yet</p>
                        <p className="mt-1 text-sm text-muted-foreground">Ready for a clean car?</p>
                    </div>
                    <Link href="/book/location" className={buttonVariants()}>
                        Book a wash now
                    </Link>
                </div>
            ) : filteredBookings.length === 0 ? (
                <div className="flex flex-col items-center gap-3 rounded-2xl border border-dashed py-12 text-center">
                    <Search className="size-10 text-muted-foreground/40" />
                    <div>
                        <p className="font-medium">No results for "{bookingSearch}"</p>
                        <p className="mt-1 text-sm text-muted-foreground">Try a different date, package, or booking number.</p>
                    </div>
                    <button
                        type="button"
                        onClick={() => setBookingSearch('')}
                        className="text-sm text-primary underline-offset-4 hover:underline"
                    >
                        Clear search
                    </button>
                </div>
            ) : (
                <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                    {filteredBookings.map((b) => {
                        const isUpcoming = b.service_status === 'scheduled' || b.service_status === 'in_progress';
                        return (
                            <BookingListCard
                                key={`${b.id}-${bookingExpandRevision}`}
                                booking={b}
                                highlight={isUpcoming}
                                defaultOpen={allBookingsExpanded}
                                onViewDetails={() => openBookingDetail(b.id)}
                                onEditBooking={
                                    b.can_edit && b.service_status === 'scheduled'
                                        ? () => openReschedule(b)
                                        : undefined
                                }
                                editBookingLabel="Reschedule"
                                footer={
                                    isUpcoming && b.can_cancel && b.service_status === 'scheduled' ? (
                                        <Button
                                            size="sm"
                                            variant="ghost"
                                            className="text-destructive hover:text-destructive"
                                            onClick={() => handleCancel(b.id)}
                                        >
                                            <X className="mr-1.5 size-3.5" />
                                            Cancel
                                        </Button>
                                    ) : undefined
                                }
                            />
                        );
                    })}
                    {q && (
                        <p className="text-center text-xs text-muted-foreground">
                            {filteredBookings.length} result{filteredBookings.length !== 1 ? 's' : ''} for "{bookingSearch}"
                        </p>
                    )}
                </div>
            )}
        </div>
    );

    /* ── Booking Detail ── */
    const SERVICE_STEPS = ['Scheduled', 'In Progress', 'Completed'];
    const STATUS_INDEX: Record<string, number> = { scheduled: 0, in_progress: 1, completed: 2 };

    const bookingDetailContent = (
        <div>
            <button
                type="button"
                onClick={() => setSection('bookings')}
                className="mb-4 flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground"
            >
                ← Back to bookings
            </button>
            <h1 className="mb-6 text-2xl font-bold">Booking details</h1>

            {!selectedBooking ? (
                <div className="flex flex-col items-center gap-4 rounded-2xl border border-dashed py-12 text-center">
                    <ClipboardList className="size-10 text-muted-foreground/40" />
                    <div>
                        <p className="font-medium">No booking selected</p>
                        <p className="mt-1 text-sm text-muted-foreground">Select a booking from My Bookings</p>
                    </div>
                    <Button variant="outline" onClick={() => setSection('bookings')}>View my bookings</Button>
                </div>
            ) : (
                <div className="flex flex-col gap-4">
                    {/* Status bar */}
                    <div className="flex flex-wrap items-center gap-x-8 gap-y-3 rounded-2xl border bg-muted/30 px-6 py-4 text-sm">
                        <div>
                            <p className="text-xs text-muted-foreground">Status</p>
                            <StatusBadge status={selectedBooking.service_status} />
                        </div>
                        <div>
                            <p className="text-xs text-muted-foreground">Booking #</p>
                            <p className="font-mono font-medium">{selectedBooking.uuid.slice(0, 8).toUpperCase()}</p>
                        </div>
                        <div>
                            <p className="text-xs text-muted-foreground">Date</p>
                            <p className="font-medium">{formatDate(selectedBooking.scheduled_at)}</p>
                        </div>
                        {selectedBooking.vehicle && (
                            <div>
                                <p className="text-xs text-muted-foreground">Vehicle</p>
                                <p className="font-medium capitalize">{selectedBooking.vehicle.size ?? selectedBooking.vehicle.make}</p>
                                <p className="text-xs text-muted-foreground">{selectedBooking.vehicle.make} {selectedBooking.vehicle.model}</p>
                            </div>
                        )}
                        <div className="ml-auto">
                            <p className="text-xs text-muted-foreground">Total</p>
                            <p className="text-lg font-bold">${(selectedBooking.total / 100).toFixed(2)}</p>
                        </div>
                    </div>

                    {/* Detail card — booking summary style */}
                    <div className="divide-y rounded-2xl border bg-card">

                        {/* SERVICE — fixed location synced, mobile entered manually */}
                        {(() => {
                            const b = selectedBooking;
                            if (b.service_type === 'fixed' && b.location) {
                                const { name, address, city, state, zip } = b.location;
                                const full = [address, city, state, zip].filter(Boolean).join(', ');
                                return (
                                    <div className="flex items-start gap-4 p-5">
                                        <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                            <MapPin className="size-4 text-muted-foreground" />
                                        </div>
                                        <div>
                                            <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Service</p>
                                            <p className="mt-1 font-medium">{name}</p>
                                            {full && <p className="text-sm text-muted-foreground">{full}</p>}
                                        </div>
                                    </div>
                                );
                            }
                            if (b.service_address) {
                                const parts = [b.service_address, b.service_city, b.service_state, b.service_zip].filter(Boolean);
                                return (
                                    <div className="flex items-start gap-4 p-5">
                                        <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                            <MapPin className="size-4 text-muted-foreground" />
                                        </div>
                                        <div>
                                            <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Service</p>
                                            <p className="mt-1 font-medium">Mobile service</p>
                                            <p className="text-sm text-muted-foreground">{parts.join(', ')}</p>
                                        </div>
                                    </div>
                                );
                            }
                            return null;
                        })()}

                        {selectedBooking.vehicle && (
                            <div className="flex items-start gap-4 p-5">
                                <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                    <Car className="size-4 text-muted-foreground" />
                                </div>
                                <div>
                                    <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Vehicle</p>
                                    <p className="mt-1 font-medium capitalize">{selectedBooking.vehicle.size ?? selectedBooking.vehicle.make}</p>
                                    <p className="text-sm text-muted-foreground">{selectedBooking.vehicle.make} {selectedBooking.vehicle.model}</p>
                                </div>
                            </div>
                        )}

                        <div className="flex items-start justify-between gap-4 p-5">
                            <div className="flex items-start gap-4">
                                <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                    <Sparkles className="size-4 text-muted-foreground" />
                                </div>
                                <div>
                                    <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Package</p>
                                    <p className="mt-1 font-medium">{selectedBooking.package?.name ?? 'Car Wash'}</p>
                                </div>
                            </div>
                            <p className="shrink-0 font-semibold">${(selectedBooking.total / 100).toFixed(2)}</p>
                        </div>

                        <div className="flex items-start gap-4 p-5">
                            <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                <CalendarDays className="size-4 text-muted-foreground" />
                            </div>
                            <div>
                                <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Date & Time</p>
                                <p className="mt-1 font-medium">{formatDate(selectedBooking.scheduled_at)}</p>
                                <p className="text-sm text-muted-foreground">{formatTime(selectedBooking.scheduled_at)}</p>
                                {selectedBooking.created_at && (
                                    <p className="mt-1 text-xs text-muted-foreground">
                                        Booked {fmtBooked(selectedBooking.created_at)}
                                    </p>
                                )}
                            </div>
                        </div>

                        <div className="flex items-start justify-between gap-4 p-5">
                            <div className="flex items-start gap-4">
                                <div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted">
                                    <CheckCircle2 className="size-4 text-muted-foreground" />
                                </div>
                                <div>
                                    <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Payment</p>
                                    <div className="mt-1">
                                        <StatusBadge status={selectedBooking.payment_status} />
                                    </div>
                                    {(selectedBooking.balance_due_cents ?? 0) > 0 &&
                                    selectedBooking.payment_url ? (
                                        <div className="mt-3 space-y-2">
                                            <p className="text-sm text-muted-foreground">
                                                Balance due:{' '}
                                                <span className="font-medium text-foreground">
                                                    $
                                                    {(
                                                        (selectedBooking.balance_due_cents ?? 0) /
                                                        100
                                                    ).toFixed(2)}
                                                </span>
                                            </p>
                                            <a
                                                href={selectedBooking.payment_url}
                                                className={cn(
                                                    buttonVariants({ size: 'sm' }),
                                                    'inline-flex gap-1.5',
                                                )}
                                            >
                                                <CreditCard className="size-4" />
                                                Pay balance now
                                            </a>
                                        </div>
                                    ) : null}
                                </div>
                            </div>
                        </div>
                    </div>

                    {/* QR code check-in */}
                    <div className="flex flex-col items-center gap-4 rounded-2xl border bg-card p-6">
                        <div className="rounded-xl border bg-card p-3 shadow-sm">
                            <QRCodeSVG
                                value={`${window.location.origin}/track/${selectedBooking.uuid}`}
                                size={160}
                                level="M"
                                marginSize={1}
                            />
                        </div>
                        <div className="text-center">
                            <p className="font-medium">Check-in QR code</p>
                            <p className="mt-0.5 text-sm text-muted-foreground">
                                Show this at the location to check in instantly
                            </p>
                        </div>
                        <a
                            href={`${window.location.origin}/track/${selectedBooking.uuid}`}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="flex items-center gap-1.5 text-xs text-primary underline-offset-4 hover:underline"
                        >
                            Open tracking page
                            <ExternalLink className="size-3" />
                        </a>
                    </div>

                    {/* Progress */}
                    <div className="rounded-2xl border bg-card p-6">
                        <div className="relative flex justify-between">
                            <div className="absolute left-0 right-0 top-3 -z-10 h-0.5 bg-muted" />
                            {SERVICE_STEPS.map((step, i) => {
                                const currentIdx = STATUS_INDEX[selectedBooking.service_status] ?? -1;
                                const done = i <= currentIdx;
                                const current = i === currentIdx;
                                return (
                                    <div key={step} className="flex flex-col items-center gap-2">
                                        <div className={`flex size-6 items-center justify-center rounded-full text-xs font-bold ${done ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'}`}>
                                            {done ? '✓' : i + 1}
                                        </div>
                                        <span className={`text-xs font-medium ${current ? 'text-foreground' : 'text-muted-foreground'}`}>
                                            {step}
                                        </span>
                                    </div>
                                );
                            })}
                        </div>
                    </div>

                    {/* Actions */}
                    {selectedBooking.service_status === 'scheduled' && (selectedBooking.can_reschedule || selectedBooking.can_cancel) && (
                        <div className="flex flex-wrap gap-3">
                            {selectedBooking.can_reschedule && (
                                <Button variant="outline" onClick={() => openReschedule(selectedBooking)}>
                                    Reschedule
                                </Button>
                            )}
                            {selectedBooking.can_cancel && (
                                <Button
                                    variant="ghost"
                                    className="text-destructive hover:text-destructive"
                                    onClick={() => handleCancel(selectedBooking.id)}
                                >
                                    <X className="mr-1.5 size-4" />
                                    Cancel booking
                                </Button>
                            )}
                        </div>
                    )}
                    {selectedBooking.service_status === 'no_show' && selectedBooking.can_reschedule && (
                        <div className="flex flex-wrap gap-3">
                            <Button onClick={() => openReschedule(selectedBooking)}>
                                Reschedule appointment
                            </Button>
                        </div>
                    )}
                </div>
            )}
        </div>
    );

    /* ── My Vehicles ── */
    const vehiclesContent = (
        <div>
            <div className="mb-6 flex items-center justify-between gap-4">
                <div>
                    <h1 className="text-2xl font-bold">My Vehicles</h1>
                    <p className="mt-1 text-sm text-muted-foreground">
                        {vehicles.length === 0
                            ? 'No vehicles saved yet.'
                            : `${vehicles.length} vehicle${vehicles.length !== 1 ? 's' : ''} on file`}
                    </p>
                </div>
                {!showVehicleForm && (
                    <Button size="sm" variant="outline" onClick={() => setShowVehicleForm(true)}>
                        <Plus className="mr-1.5 size-4" /> Add vehicle
                    </Button>
                )}
            </div>

            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
                {vehicles.map((v) => {
                    const locked = activeVehicleIds.has(v.id);
                    return (
                        <div
                            key={v.id}
                            className={cn(
                                'relative flex flex-col rounded-2xl border bg-card p-5 transition-shadow hover:shadow-sm',
                                v.is_default && 'border-primary/40 ring-1 ring-primary/20',
                            )}
                        >
                            {/* Default badge */}
                            {v.is_default && (
                                <span className="absolute right-4 top-4 flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-primary">
                                    <Star className="size-2.5 fill-primary" />
                                    Default
                                </span>
                            )}

                            {/* Icon */}
                            <div className={cn(
                                'mb-4 flex size-10 items-center justify-center rounded-xl',
                                v.is_default ? 'bg-primary/10' : 'bg-muted',
                            )}>
                                <Car className={cn('size-5', v.is_default ? 'text-primary' : 'text-muted-foreground')} />
                            </div>

                            {/* Info */}
                            <p className="pr-16 font-semibold">{v.year} {v.make} {v.model}</p>
                            <p className="mt-0.5 text-sm capitalize text-muted-foreground">
                                {v.size}{v.color ? ` · ${v.color}` : ''}
                            </p>

                            {/* Actions */}
                            <div className="mt-4 flex items-center justify-between border-t pt-3">
                                {!v.is_default && (
                                    <button
                                        type="button"
                                        onClick={() => handleSetDefault(v.id)}
                                        className="flex items-center gap-1.5 text-xs text-muted-foreground transition-colors hover:text-primary"
                                    >
                                        <Star className="size-3.5" />
                                        Set as default
                                    </button>
                                )}
                                {v.is_default && <span />}

                                {locked ? (
                                    <p
                                        className="flex items-center gap-1.5 text-xs text-muted-foreground"
                                        title="Vehicle has an active booking"
                                    >
                                        <Trash2 className="size-3.5 opacity-40" />
                                        In use
                                    </p>
                                ) : (
                                    <button
                                        type="button"
                                        onClick={() => handleDeleteVehicle(v.id)}
                                        className="flex items-center gap-1.5 text-xs text-muted-foreground transition-colors hover:text-destructive"
                                    >
                                        <Trash2 className="size-3.5" />
                                        Remove
                                    </button>
                                )}
                            </div>
                        </div>
                    );
                })}

                {!showVehicleForm && (
                    <button
                        type="button"
                        onClick={() => setShowVehicleForm(true)}
                        className="flex min-h-[140px] flex-col items-center justify-center gap-2 rounded-2xl border border-dashed text-muted-foreground transition-colors hover:border-primary/50 hover:text-foreground"
                    >
                        <Plus className="size-6" />
                        <span className="text-sm font-medium">Add vehicle</span>
                    </button>
                )}
            </div>

            {showVehicleForm && (
                <form onSubmit={submitVehicle} className="mt-6 rounded-2xl border bg-card p-6">
                    <div className="mb-5 flex items-center gap-3">
                        <div className="flex size-9 items-center justify-center rounded-xl bg-primary/10">
                            <Car className="size-5 text-primary" />
                        </div>
                        <div>
                            <h2 className="font-semibold">Add a vehicle</h2>
                            <p className="text-xs text-muted-foreground">Saved vehicles can be pre-selected when booking</p>
                        </div>
                    </div>
                    <div className="grid gap-4 sm:grid-cols-2">
                        <Field label="Make" error={vehicleForm.errors.make}>
                            <Input placeholder="Toyota" value={vehicleForm.data.make} onChange={(e) => vehicleForm.setData('make', e.target.value)} />
                        </Field>
                        <Field label="Model" error={vehicleForm.errors.model}>
                            <Input placeholder="Camry" value={vehicleForm.data.model} onChange={(e) => vehicleForm.setData('model', e.target.value)} />
                        </Field>
                        <Field label="Year" error={vehicleForm.errors.year}>
                            <Input type="number" value={vehicleForm.data.year} onChange={(e) => vehicleForm.setData('year', parseInt(e.target.value) || vehicleForm.data.year)} />
                        </Field>
                        <Field label="Color (optional)" error={vehicleForm.errors.color}>
                            <Input placeholder="White" value={vehicleForm.data.color} onChange={(e) => vehicleForm.setData('color', e.target.value)} />
                        </Field>
                        <Field label="Vehicle size" error={vehicleForm.errors.size}>
                            <NativeSelect value={vehicleForm.data.size} onChange={(e) => vehicleForm.setData('size', e.target.value)}>
                                <option value="sedan">Sedan</option>
                                <option value="suv">SUV</option>
                                <option value="truck">Truck</option>
                                <option value="van">Van</option>
                                <option value="oversized">Oversized</option>
                            </NativeSelect>
                        </Field>
                    </div>
                    <div className="mt-5 flex gap-3">
                        <Button type="submit" disabled={vehicleForm.processing}>Save vehicle</Button>
                        <Button type="button" variant="ghost" onClick={() => setShowVehicleForm(false)}>Cancel</Button>
                    </div>
                </form>
            )}
        </div>
    );

    /* ── Cancellations ── */
    const cancellationsContent = (
        <div className="flex flex-col gap-8">
            {/* No Show */}
            <div>
                <div className="mb-4 flex items-start justify-between gap-4">
                    <div>
                        <h2 className="text-xl font-bold">Missed Appointments</h2>
                        <p className="mt-0.5 text-sm text-muted-foreground">You can reschedule these at any time.</p>
                    </div>
                    {noShowBookings.length > 0 && (
                        <span className="mt-1.5 text-sm text-muted-foreground">{noShowBookings.length} missed</span>
                    )}
                </div>

                {noShowBookings.length === 0 ? (
                    <div className="flex flex-col items-center gap-4 rounded-2xl border border-dashed py-8 text-center">
                        <RotateCcw className="size-8 text-muted-foreground/40" />
                        <p className="text-sm text-muted-foreground">No missed appointments.</p>
                    </div>
                ) : (
                    <div className="flex flex-col gap-4">
                        {noShowBookings.map((b) => (
                            <div key={b.id} className="rounded-2xl border bg-card p-5">
                                <div className="flex flex-wrap items-start justify-between gap-3">
                                    <div>
                                        <p className="font-semibold">{b.package?.name ?? 'Car Wash'}</p>
                                        <p className="mt-1 text-sm text-muted-foreground">
                                            {formatDate(b.scheduled_at)} · {formatTime(b.scheduled_at)}
                                        </p>
                                        {b.vehicle && (
                                            <p className="mt-0.5 text-sm capitalize text-muted-foreground">
                                                {b.vehicle.size ?? b.vehicle.make} · {b.vehicle.make} {b.vehicle.model}
                                            </p>
                                        )}
                                    </div>
                                    <div className="flex flex-col items-end gap-1.5">
                                        <span className="font-bold">${(b.total / 100).toFixed(2)}</span>
                                        <StatusBadge status={b.service_status} />
                                    </div>
                                </div>
                                <div className="mt-3 flex items-center justify-between border-t pt-3">
                                    <span className="font-mono text-xs text-muted-foreground">{b.uuid.slice(0, 8).toUpperCase()}</span>
                                    {b.can_reschedule && (
                                        <Button size="sm" onClick={() => openReschedule(b)}>
                                            Reschedule
                                        </Button>
                                    )}
                                </div>
                            </div>
                        ))}
                    </div>
                )}
            </div>

            {/* Cancellations */}
            <div>
                <div className="mb-4 flex items-start justify-between gap-4">
                    <h2 className="text-xl font-bold">Cancellations</h2>
                    {cancelledBookings.length > 0 && (
                        <span className="mt-1.5 text-sm text-muted-foreground">{cancelledBookings.length} cancelled</span>
                    )}
                </div>

            {cancelledBookings.length === 0 ? (
                <div className="flex flex-col items-center gap-4 rounded-2xl border border-dashed py-12 text-center">
                    <RotateCcw className="size-10 text-muted-foreground/40" />
                    <div>
                        <p className="font-medium">No cancellations</p>
                        <p className="mt-1 text-sm text-muted-foreground">You have no cancelled appointments.</p>
                    </div>
                </div>
            ) : (
                <div className="flex flex-col gap-4">
                    {cancelledBookings.map((b) => (
                        <div key={b.id} className="rounded-2xl border bg-card p-5">
                            <div className="flex flex-wrap items-start justify-between gap-3">
                                <div>
                                    <p className="font-semibold">{b.package?.name ?? 'Car Wash'}</p>
                                    <p className="mt-1 text-sm text-muted-foreground">
                                        {formatDate(b.scheduled_at)} · {formatTime(b.scheduled_at)}
                                    </p>
                                    {b.vehicle && (
                                        <p className="mt-0.5 text-sm capitalize text-muted-foreground">
                                            {b.vehicle.size ?? b.vehicle.make} · {b.vehicle.make} {b.vehicle.model}
                                        </p>
                                    )}
                                </div>
                                <div className="flex flex-col items-end gap-1.5">
                                    <span className="font-bold">${(b.total / 100).toFixed(2)}</span>
                                    <StatusBadge status={b.service_status} />
                                </div>
                            </div>
                            <div className="mt-3 flex items-center justify-between border-t pt-3">
                                <span className="flex flex-col">
                                    <span className="font-mono text-xs text-muted-foreground">{b.uuid.slice(0, 8).toUpperCase()}</span>
                                    {b.created_at && (
                                        <span className="text-xs text-muted-foreground">
                                            Booked {fmtBooked(b.created_at)}
                                        </span>
                                    )}
                                </span>
                                <button
                                    type="button"
                                    onClick={() => openBookingDetail(b.id)}
                                    className="text-sm font-medium underline underline-offset-2 hover:text-foreground"
                                >
                                    View details
                                </button>
                            </div>
                        </div>
                    ))}
                </div>
            )}
            </div>
        </div>
    );

    /* ── Section map ── */
    const content: Record<Section, React.ReactNode> = {
        overview: overviewContent,
        profile: profileContent,
        bookings: bookingsContent,
        'booking-detail': bookingDetailContent,
        vehicles: vehiclesContent,
        cancellations: cancellationsContent,
    };

    /* ── Render ── */
    return (
        <>
            <Head title="My Account" />

            <div className="flex min-h-screen bg-background text-foreground">
                {/* Desktop sidebar */}
                <aside className="hidden lg:fixed lg:inset-y-0 lg:left-0 lg:z-30 lg:flex lg:w-64 lg:flex-col lg:border-r lg:bg-background">
                    {sidebarContent}
                </aside>

                {/* Mobile sidebar overlay */}
                {sidebarOpen && (
                    <div className="fixed inset-0 z-40 lg:hidden">
                        <div className="absolute inset-0 bg-black/50" onClick={() => setSidebarOpen(false)} />
                        <aside className="absolute inset-y-0 left-0 z-50 flex w-64 flex-col border-r bg-background">
                            {sidebarContent}
                        </aside>
                    </div>
                )}

                {/* Main */}
                <div className="flex flex-1 flex-col lg:pl-64">
                    {/* Mobile top bar */}
                    <header className="sticky top-0 z-20 flex h-14 items-center gap-3 border-b bg-background px-4 lg:hidden">
                        <button
                            type="button"
                            onClick={() => setSidebarOpen(true)}
                            className="rounded-md p-1.5 text-muted-foreground hover:bg-accent"
                        >
                            <Menu className="size-5" />
                        </button>
                        <button type="button" onClick={() => navigate('overview')} className="flex items-center gap-2">
                            <div className="flex size-7 items-center justify-center rounded-lg bg-primary">
                                <Car className="size-3.5 text-primary-foreground" />
                            </div>
                            <span className="text-sm font-bold">{brandName}</span>
                        </button>
                        <div className="ml-auto">
                            <ThemeToggle />
                        </div>
                    </header>

                    <main className="relative flex-1 px-6 py-8 lg:px-10 lg:py-10">
                        {/* Dashed grid background */}
                        <div
                            className="pointer-events-none absolute inset-0 z-0 opacity-10 dark:opacity-[0.07]"
                            style={{
                                backgroundImage: `
                                    linear-gradient(to right, currentColor 1px, transparent 1px),
                                    linear-gradient(to bottom, currentColor 1px, transparent 1px)
                                `,
                                backgroundSize: '20px 20px',
                                maskImage: `
                                    repeating-linear-gradient(to right, black 0px, black 3px, transparent 3px, transparent 8px),
                                    repeating-linear-gradient(to bottom, black 0px, black 3px, transparent 3px, transparent 8px),
                                    radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)
                                `,
                                WebkitMaskImage: `
                                    repeating-linear-gradient(to right, black 0px, black 3px, transparent 3px, transparent 8px),
                                    repeating-linear-gradient(to bottom, black 0px, black 3px, transparent 3px, transparent 8px),
                                    radial-gradient(ellipse 80% 80% at 100% 0%, #000 50%, transparent 90%)
                                `,
                                maskComposite: 'intersect',
                                WebkitMaskComposite: 'source-in',
                            }}
                        />
                        <div
                            className="relative z-10 mx-auto max-w-3xl"
                        >
                            {content[section]}
                        </div>
                    </main>
                </div>
            </div>

            {/* Reschedule dialog */}
            <Dialog open={rescheduleId !== null} onOpenChange={(open) => !open && closeReschedule()}>
                <DialogContent className="sm:max-w-xl">
                    <DialogHeader>
                        <DialogTitle>Reschedule appointment</DialogTitle>
                        <DialogDescription>Pick a new date and time for your service.</DialogDescription>
                    </DialogHeader>
                    <div className="flex flex-col gap-4 py-2">
                        {rescheduleLoading ? (
                            <p className="text-sm text-muted-foreground">Loading available times…</p>
                        ) : (
                            <>
                                <DateStrip
                                    selectedDate={rescheduleDate}
                                    onSelect={(date) => {
                                        setRescheduleDate(date);
                                        setRescheduleTime(null);
                                    }}
                                    availableSlotsByDate={rescheduleSlots}
                                    closedDateRanges={rescheduleClosedRanges}
                                    timezone={timezone}
                                />
                                {rescheduleDate && (
                                    <div className="flex flex-col gap-2">
                                        <Label className="text-sm font-medium">Available times</Label>
                                        <TimeSlotGrid
                                            selectedTime={rescheduleTime}
                                            onSelect={setRescheduleTime}
                                            availableTimes={rescheduleTimesForDay}
                                        />
                                    </div>
                                )}
                            </>
                        )}
                        <div className="flex gap-3">
                            <Button onClick={submitReschedule} disabled={!rescheduleDate || !rescheduleTime}>
                                Confirm new time
                            </Button>
                            <Button variant="outline" onClick={closeReschedule}>Cancel</Button>
                        </div>
                    </div>
                </DialogContent>
            </Dialog>
        </>
    );
}
