import { Link, usePage } from '@inertiajs/react';
import { useEffect, useState } from 'react';
import { ArrowLeft, CalendarDays, Car, Check, MapPin, Plus, Sparkles, Tag } from 'lucide-react';
import { BookingLiveContext, LiveSummaryPatch } from '@/contexts/booking-live';
import { PublicHeader } from '@/components/public-header';
import { PageShell } from '@/components/layout/page-shell';
import { Button, buttonVariants } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { cn } from '@/lib/utils';
import { dashboard, home, login } from '@/routes';
import type { User as AuthUser } from '@/types/auth';

const WIZARD_STEPS = [
    { label: 'Location', href: '/book/location' },
    { label: 'Vehicle', href: '/book/vehicle' },
    { label: 'Package', href: '/book/package' },
    { label: 'Add-ons', href: '/book/addons' },
    { label: 'Date & Time', href: '/book/datetime' },
    { label: 'Your Info', href: '/book/customer-info' },
    { label: 'Payment', href: '/book/payment' },
] as const;

function currentStepIndex(url: string): number {
    if (url.startsWith('/book/payment')) return 6;
    return WIZARD_STEPS.findIndex((step) => url.startsWith(step.href));
}

type BookingSummary = {
    serviceType: string | null;
    serviceZip: string | null;
    locationName: string | null;
    vehicleSize: string | null;
    vehicleMake: string | null;
    vehicleModel: string | null;
    packageName: string | null;
    packagePrice: number | null;
    addonNames: string[];
    addonsTotal: number;
    discountTotal: number;
    discountLabel: string | null;
    scheduledAt: string | null;
    total: number | null;
};

function formatDateTime(s: string): { date: string; time: string } | null {
    const m = s.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})/);
    if (!m) return null;
    const [, y, mo, d, h, mi] = m.map(Number);
    const dt = new Date(y, mo - 1, d, h, mi);
    return {
        date: dt.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' }),
        time: dt.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }),
    };
}

function SummaryRow({
    icon,
    label,
    children,
    price,
}: {
    icon: React.ReactNode;
    label: string;
    children: React.ReactNode;
    price?: React.ReactNode;
}) {
    return (
        <div className="flex items-start gap-3">
            <div className="mt-0.5 shrink-0 text-primary">{icon}</div>
            <div className="min-w-0 flex-1">
                <p className="mb-0.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                    {label}
                </p>
                {children}
            </div>
            {price && <div className="shrink-0 text-right">{price}</div>}
        </div>
    );
}

function OrderSummarySidebar({ summary }: { summary: BookingSummary }) {
    const scheduled = summary.scheduledAt ? formatDateTime(summary.scheduledAt) : null;

    const rows = [
        summary.serviceType ? (
            <SummaryRow key="service" icon={<MapPin className="size-4" />} label="Service">
                <p className="text-sm font-medium">
                    {summary.serviceType === 'mobile' ? 'Mobile Service' : 'LOCATION'}
                </p>
                {summary.serviceType === 'mobile' && summary.serviceZip && (
                    <p className="text-xs text-muted-foreground">ZIP: {summary.serviceZip}</p>
                )}
                {summary.serviceType === 'fixed' && summary.locationName && (
                    <p className="text-xs text-muted-foreground">{summary.locationName}</p>
                )}
            </SummaryRow>
        ) : null,

        summary.vehicleSize ? (
            <SummaryRow key="vehicle" icon={<Car className="size-4" />} label="Vehicle">
                <p className="text-sm font-medium uppercase">{summary.vehicleSize}</p>
                {(summary.vehicleMake || summary.vehicleModel) && (
                    <p className="text-xs text-muted-foreground">
                        {[summary.vehicleMake, summary.vehicleModel].filter(Boolean).join(' ')}
                    </p>
                )}
            </SummaryRow>
        ) : null,

        summary.packageName ? (
            <SummaryRow
                key="package"
                icon={<Sparkles className="size-4" />}
                label="Package"
                price={
                    summary.packagePrice !== null ? (
                        <span className="text-sm font-semibold">
                            ${(summary.packagePrice / 100).toFixed(2)}
                        </span>
                    ) : undefined
                }
            >
                <p className="text-sm font-medium">{summary.packageName}</p>
            </SummaryRow>
        ) : null,

        summary.addonNames.length > 0 ? (
            <SummaryRow
                key="addons"
                icon={<Plus className="size-4" />}
                label="Add-ons"
                price={
                    summary.addonsTotal > 0 ? (
                        <span className="text-sm font-medium">
                            +${(summary.addonsTotal / 100).toFixed(2)}
                        </span>
                    ) : undefined
                }
            >
                {summary.addonNames.map((name, i) => (
                    <p key={i} className="text-xs text-muted-foreground">
                        + {name}
                    </p>
                ))}
            </SummaryRow>
        ) : null,

        scheduled ? (
            <SummaryRow key="datetime" icon={<CalendarDays className="size-4" />} label="Date & Time">
                <p className="text-sm font-medium">{scheduled.date}</p>
                <p className="text-xs text-muted-foreground">{scheduled.time}</p>
            </SummaryRow>
        ) : null,

        summary.discountTotal > 0 ? (
            <SummaryRow
                key="discount"
                icon={<Tag className="size-4" />}
                label="Discount"
                price={
                    <span className="text-sm font-medium text-green-600 dark:text-green-500">
                        -${(summary.discountTotal / 100).toFixed(2)}
                    </span>
                }
            >
                <p className="text-sm font-medium">{summary.discountLabel ?? 'Applied'}</p>
            </SummaryRow>
        ) : null,
    ].filter(Boolean);

    if (rows.length === 0) return null;

    return (
        <div className="sticky top-24 rounded-2xl border bg-muted/30 p-4">
            <h3 className="scroll-m-20 border-b pb-2 mb-3 flex items-center gap-2 text-lg uppercase font-semibold tracking-tight first:mt-0">
                <CalendarDays className="size-4 shrink-0 text-primary" />
                Your booking
            </h3>
            <div className="flex flex-col text-sm">
                {rows.map((row, i) => (
                    <div key={i}>
                        {i > 0 && <Separator className="my-3" />}
                        {row}
                    </div>
                ))}

                {summary.total !== null && summary.total > 0 && (
                    <>
                        <Separator className="my-3" />
                        <div className="flex items-center justify-between">
                            <span className="font-semibold">Total</span>
                            <span className="text-base font-bold text-primary">
                                ${(summary.total / 100).toFixed(2)}
                            </span>
                        </div>
                    </>
                )}
            </div>
        </div>
    );
}

export default function BookingWizardLayout({ children }: { children: React.ReactNode }) {
    const page = usePage();
    const { url } = page;
    const props = page.props as Record<string, unknown>;
    const bookingSummary = props.bookingSummary as BookingSummary | undefined;
    const authUser = (props.auth as { user?: AuthUser } | undefined)?.user ?? null;
    const isStaff = ['admin', 'manager', 'technician'].includes(
        (authUser?.role as string | undefined) ?? '',
    );
    const isComplete = url.startsWith('/book/complete');
    const activeStep = currentStepIndex(url);
    const showSidebar = !isComplete && activeStep > 0;

    const [livePatch, setLivePatch] = useState<LiveSummaryPatch>({});

    // Reset live patch on every page navigation so stale overrides don't bleed across steps
    useEffect(() => { setLivePatch({}); }, [url]);

    const mergedSummary: BookingSummary | undefined = bookingSummary
        ? (() => {
              const s = { ...bookingSummary };
              if (livePatch.packageName !== undefined) s.packageName = livePatch.packageName;
              if (livePatch.packagePrice !== undefined) s.packagePrice = livePatch.packagePrice;
              if (livePatch.addonNames !== undefined) s.addonNames = livePatch.addonNames;
              if (livePatch.addonsTotal !== undefined) s.addonsTotal = livePatch.addonsTotal;
              if (livePatch.discountTotal !== undefined) s.discountTotal = livePatch.discountTotal;
              if (livePatch.discountLabel !== undefined) s.discountLabel = livePatch.discountLabel;
              if (
                  livePatch.packagePrice !== undefined
                  || livePatch.addonsTotal !== undefined
                  || livePatch.discountTotal !== undefined
              ) {
                  s.total = Math.max(0, (s.packagePrice ?? 0) + s.addonsTotal - s.discountTotal);
              }
              return s;
          })()
        : undefined;

    return (
        <BookingLiveContext.Provider value={{ setPatch: setLivePatch }}>
        <div className="min-h-screen bg-muted/30">
            {/* Header */}
            <header className="sticky top-0 z-10 border-b bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/80">
                <PageShell width="wide" className="py-4">
                    <PublicHeader />
                </PageShell>
            </header>

            {/* Step progress bar */}
            {!isComplete && activeStep >= 0 && (
                <div className="border-b bg-background">
                    <PageShell width="wide" className="py-4">
                        {/* Mobile: compact progress + label */}
                        <div className="flex flex-col gap-2 md:hidden">
                            <div className="flex items-center justify-between text-sm text-muted-foreground">
                                <span className="font-medium text-foreground">
                                    {WIZARD_STEPS[activeStep]?.label}
                                </span>
                                <span>
                                    Step {activeStep + 1} of {WIZARD_STEPS.length}
                                </span>
                            </div>
                            <div className="flex gap-1">
                                {WIZARD_STEPS.map((_, index) => (
                                    <div
                                        key={index}
                                        className={cn(
                                            'h-1.5 flex-1 rounded-full transition-colors',
                                            index < activeStep
                                                ? 'bg-primary'
                                                : index === activeStep
                                                  ? 'bg-primary/70'
                                                  : 'bg-muted',
                                        )}
                                    />
                                ))}
                            </div>
                        </div>

                        {/* Desktop: numbered step circles */}
                        <div className="hidden md:flex items-center gap-0">
                            {WIZARD_STEPS.map((step, index) => {
                                const isCompleted = index < activeStep;
                                const isCurrent = index === activeStep;
                                const isLast = index === WIZARD_STEPS.length - 1;

                                const circle = (
                                    <div className="flex flex-col items-center gap-1.5">
                                        <div
                                            className={cn(
                                                'flex size-8 items-center justify-center rounded-full border-2 text-xs font-semibold transition-all',
                                                isCompleted &&
                                                    'border-primary bg-primary text-primary-foreground',
                                                isCurrent &&
                                                    'border-primary bg-primary/10 text-primary',
                                                !isCompleted &&
                                                    !isCurrent &&
                                                    'border-muted-foreground/30 bg-background text-muted-foreground',
                                            )}
                                        >
                                            {isCompleted ? (
                                                <Check className="size-4" strokeWidth={2.5} />
                                            ) : (
                                                index + 1
                                            )}
                                        </div>
                                        <span
                                            className={cn(
                                                'text-xs font-medium whitespace-nowrap',
                                                isCurrent
                                                    ? 'text-primary'
                                                    : isCompleted
                                                      ? 'text-foreground'
                                                      : 'text-muted-foreground',
                                            )}
                                        >
                                            {step.label}
                                        </span>
                                    </div>
                                );

                                return (
                                    <div key={step.href} className="flex items-center">
                                        {isCompleted ? (
                                            <Link
                                                href={step.href}
                                                className="transition-opacity hover:opacity-75"
                                                title={`Go back to ${step.label}`}
                                            >
                                                {circle}
                                            </Link>
                                        ) : (
                                            circle
                                        )}
                                        {!isLast && (
                                            <div
                                                className={cn(
                                                    'mb-5 h-0.5 w-8 shrink-0 transition-colors lg:w-12',
                                                    index < activeStep
                                                        ? 'bg-primary'
                                                        : 'bg-muted',
                                                )}
                                            />
                                        )}
                                    </div>
                                );
                            })}
                        </div>
                    </PageShell>
                </div>
            )}

            {/* Content */}
            <PageShell width="wide" className="py-6 md:py-10">
                <div className={cn('flex items-start gap-8', showSidebar ? 'lg:flex-row' : '')}>
                    {/* Main content */}
                    <div className="min-w-0 flex-1">
                        {/* Back nav — shown on steps 2–7 */}
                        {!isComplete && activeStep > 0 && (
                            <div className="mb-4">
                                <Link
                                    href={WIZARD_STEPS[activeStep - 1].href}
                                    className="inline-flex items-center gap-1.5 text-sm text-muted-foreground transition-colors hover:text-foreground"
                                >
                                    <ArrowLeft className="size-4" />
                                    Back to {WIZARD_STEPS[activeStep - 1].label}
                                </Link>
                            </div>
                        )}
                        {children}
                    </div>

                    {/* Order summary sidebar — steps 2–7 on desktop */}
                    {showSidebar && mergedSummary && (
                        <div className="hidden w-72 shrink-0 lg:block">
                            <OrderSummarySidebar summary={mergedSummary} />
                        </div>
                    )}
                </div>
            </PageShell>
        </div>
        </BookingLiveContext.Provider>
    );
}
