import { router } from '@inertiajs/react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import adminLocations from '@/routes/admin/locations';

type Mode = 'single' | 'range';
type Phase = 'start' | 'end';

const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const YEAR_RANGE = Array.from({ length: 6 }, (_, i) => new Date().getFullYear() + i);

function toDateKey(d: Date): string {
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

function formatDisplay(dateKey: string): string {
    const [y, m, d] = dateKey.split('-').map(Number);
    return `${MONTHS[m - 1].slice(0, 3)} ${d}, ${y}`;
}

function buildCalendarCells(year: number, month: number): { dateKey: string; isCurrentMonth: boolean; isWeekend: boolean }[] {
    const firstDay = new Date(year, month, 1).getDay();
    const daysInMonth = new Date(year, month + 1, 0).getDate();
    const daysInPrevMonth = new Date(year, month, 0).getDate();
    const cells: { dateKey: string; isCurrentMonth: boolean; isWeekend: boolean }[] = [];

    for (let d = firstDay - 1; d >= 0; d--) {
        const date = new Date(year, month - 1, daysInPrevMonth - d);
        const dow = date.getDay();
        cells.push({ dateKey: toDateKey(date), isCurrentMonth: false, isWeekend: dow === 0 || dow === 6 });
    }
    for (let d = 1; d <= daysInMonth; d++) {
        const date = new Date(year, month, d);
        const dow = date.getDay();
        cells.push({ dateKey: toDateKey(date), isCurrentMonth: true, isWeekend: dow === 0 || dow === 6 });
    }
    const remaining = 42 - cells.length;
    for (let d = 1; d <= remaining; d++) {
        const date = new Date(year, month + 1, d);
        const dow = date.getDay();
        cells.push({ dateKey: toDateKey(date), isCurrentMonth: false, isWeekend: dow === 0 || dow === 6 });
    }
    return cells;
}

function CalendarGrid({
    year,
    month,
    startDate,
    endDate,
    onSelect,
    todayKey,
}: {
    year: number;
    month: number;
    startDate: string | null;
    endDate: string | null;
    onSelect: (dateKey: string) => void;
    todayKey: string;
}) {
    const cells = buildCalendarCells(year, month);

    return (
        <div>
            <div className="mb-1 grid grid-cols-7 text-center text-xs font-medium text-muted-foreground">
                {['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'].map((d) => (
                    <div key={d} className="py-1">
                        {d}
                    </div>
                ))}
            </div>
            <div className="grid grid-cols-7 gap-y-0.5">
                {cells.map(({ dateKey, isCurrentMonth, isWeekend }) => {
                    const isStart = dateKey === startDate;
                    const isEnd = dateKey === endDate;
                    const isSelected = isStart || isEnd;
                    const isInRange =
                        startDate && endDate && dateKey > startDate && dateKey < endDate;
                    const isPast = dateKey < todayKey;

                    return (
                        <button
                            key={dateKey}
                            type="button"
                            disabled={isPast}
                            onClick={() => !isPast && onSelect(dateKey)}
                            className={[
                                'mx-auto flex size-9 items-center justify-center rounded-full text-sm transition-colors',
                                !isCurrentMonth && 'text-muted-foreground/40',
                                isPast && 'cursor-not-allowed opacity-40',
                                isCurrentMonth && isWeekend && !isSelected && !isInRange && !isPast
                                    ? 'bg-amber-50 text-amber-900 hover:bg-amber-100 dark:bg-amber-950/30 dark:text-amber-200'
                                    : '',
                                isSelected
                                    ? 'bg-primary text-primary-foreground hover:bg-primary/90'
                                    : '',
                                isInRange && !isSelected
                                    ? 'rounded-none bg-primary/10 text-foreground'
                                    : '',
                                !isSelected && !isInRange && !isPast && isCurrentMonth && !isWeekend
                                    ? 'hover:bg-accent hover:text-foreground'
                                    : '',
                            ]
                                .filter(Boolean)
                                .join(' ')}
                        >
                            {new Date(dateKey + 'T00:00:00').getDate()}
                        </button>
                    );
                })}
            </div>
        </div>
    );
}

type Props = {
    open: boolean;
    onClose: () => void;
    locationId: number;
};

export function CustomScheduleModal({ open, onClose, locationId }: Props) {
    const today = new Date();
    const todayKey = toDateKey(today);

    const [mode, setMode] = useState<Mode>('single');
    const [phase, setPhase] = useState<Phase>('start');
    const [calYear, setCalYear] = useState(today.getFullYear());
    const [calMonth, setCalMonth] = useState(today.getMonth());
    const [startDate, setStartDate] = useState<string | null>(null);
    const [endDate, setEndDate] = useState<string | null>(null);
    const [label, setLabel] = useState('');
    const [saving, setSaving] = useState(false);

    const reset = () => {
        setMode('single');
        setPhase('start');
        setStartDate(null);
        setEndDate(null);
        setLabel('');
        setSaving(false);
    };

    const handleClose = () => {
        reset();
        onClose();
    };

    const prevMonth = () => {
        if (calMonth === 0) { setCalMonth(11); setCalYear((y) => y - 1); }
        else setCalMonth((m) => m - 1);
    };

    const nextMonth = () => {
        if (calMonth === 11) { setCalMonth(0); setCalYear((y) => y + 1); }
        else setCalMonth((m) => m + 1);
    };

    const handleSelect = (dateKey: string) => {
        if (mode === 'single') {
            setStartDate(dateKey);
            setEndDate(dateKey);
        } else {
            if (phase === 'start') {
                setStartDate(dateKey);
                setEndDate(null);
                setPhase('end');
            } else {
                if (dateKey < startDate!) {
                    setStartDate(dateKey);
                    setEndDate(startDate);
                } else {
                    setEndDate(dateKey);
                }
                setPhase('start');
            }
        }
    };

    const canSave = mode === 'single' ? !!startDate : !!(startDate && endDate);

    const handleSave = () => {
        if (!canSave) return;
        setSaving(true);
        router.post(
            adminLocations.closedDates.store.url(locationId),
            {
                start_date: startDate,
                end_date: endDate ?? startDate,
                label: label.trim() || null,
            },
            {
                onSuccess: () => { handleClose(); },
                onFinish: () => setSaving(false),
            },
        );
    };

    const pickLabel = mode === 'single'
        ? 'Pick a Date'
        : phase === 'start' ? 'Pick a Start Date' : 'Pick an End Date';

    return (
        <Dialog open={open} onOpenChange={(v) => !v && handleClose()}>
            <DialogContent className="max-w-sm p-0 gap-0 overflow-hidden">
                <DialogHeader className="px-5 pt-5 pb-4">
                    <DialogTitle className="text-xl font-semibold">Custom schedule</DialogTitle>
                </DialogHeader>

                <div className="border-t" />

                {/* Mode + date pills */}
                <div className="flex items-center gap-2 px-4 py-3 flex-wrap">
                    <select
                        value={mode}
                        onChange={(e) => {
                            setMode(e.target.value as Mode);
                            setStartDate(null);
                            setEndDate(null);
                            setPhase('start');
                        }}
                        className={[
                            'h-9 rounded-full border border-input bg-background px-3 text-sm font-medium focus:outline-none focus:ring-1 focus:ring-ring',
                            mode === 'single' ? 'w-full' : '',
                        ].join(' ')}
                    >
                        <option value="single">Single Day</option>
                        <option value="range">Date Range</option>
                    </select>

                    {mode === 'range' && (
                        <>
                            <span className="h-9 flex items-center rounded-full border border-input bg-background px-3 text-sm font-medium text-foreground whitespace-nowrap">
                                {startDate ? formatDisplay(startDate) : 'Pick a Start'}
                            </span>
                            <span className="h-9 flex items-center rounded-full border border-input bg-muted/50 px-3 text-sm text-muted-foreground whitespace-nowrap">
                                {endDate ? formatDisplay(endDate) : 'Pick an End'}
                            </span>
                        </>
                    )}
                </div>

                <div className="border-t" />

                {/* Calendar header */}
                <div className="flex items-center justify-between px-4 pt-4 pb-2">
                    <span className="text-sm font-semibold">{pickLabel}</span>
                    <div className="flex items-center gap-1">
                        <select
                            value={calMonth}
                            onChange={(e) => setCalMonth(Number(e.target.value))}
                            className="h-8 rounded-md border border-input bg-background px-2 text-sm focus:outline-none"
                        >
                            {MONTHS.map((m, i) => <option key={m} value={i}>{m}</option>)}
                        </select>
                        <select
                            value={calYear}
                            onChange={(e) => setCalYear(Number(e.target.value))}
                            className="h-8 rounded-md border border-input bg-background px-2 text-sm focus:outline-none"
                        >
                            {YEAR_RANGE.map((y) => <option key={y} value={y}>{y}</option>)}
                        </select>
                        <button
                            type="button"
                            onClick={prevMonth}
                            className="inline-flex size-8 items-center justify-center rounded-md hover:bg-accent"
                        >
                            <ChevronLeft className="size-4" />
                        </button>
                        <button
                            type="button"
                            onClick={nextMonth}
                            className="inline-flex size-8 items-center justify-center rounded-md hover:bg-accent"
                        >
                            <ChevronRight className="size-4" />
                        </button>
                    </div>
                </div>

                <div className="px-4 pb-4">
                    <CalendarGrid
                        year={calYear}
                        month={calMonth}
                        startDate={startDate}
                        endDate={endDate}
                        onSelect={handleSelect}
                        todayKey={todayKey}
                    />
                </div>

                {/* Optional label */}
                <div className="border-t px-4 py-3">
                    <Input
                        placeholder="Holiday name (optional, e.g. Christmas)"
                        value={label}
                        onChange={(e) => setLabel(e.target.value)}
                        className="text-sm"
                    />
                </div>

                <div className="border-t px-4 py-4">
                    <Button
                        variant="outline"
                        className="w-full text-primary border-primary hover:bg-primary/5 hover:text-primary font-medium"
                        disabled={!canSave || saving}
                        onClick={handleSave}
                    >
                        {saving ? 'Saving…' : 'Set as Day Off'}
                    </Button>
                </div>
            </DialogContent>
        </Dialog>
    );
}
