import { useRef, useState } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import {
    bookingDateKeyAfterDays,
    bookingTodayKey,
} from '@/lib/booking-timezones';
import { cn } from '@/lib/utils';

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

type DateStripProps = {
    selectedDate: Date | null;
    onSelect: (date: Date) => void;
    daysAhead?: number;
    initialOffset?: number;
    availableSlotsByDate?: Record<string, Record<string, number>>;
    closedDateRanges?: ClosedRange[];
    timezone: string;
};

const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

function isSameDay(a: Date, b: Date): boolean {
    return (
        a.getFullYear() === b.getFullYear() &&
        a.getMonth() === b.getMonth() &&
        a.getDate() === b.getDate()
    );
}

function buildDays(daysAhead: number, timezone: string): Date[] {
    const days: Date[] = [];
    const todayKey = bookingTodayKey(timezone);

    for (let i = 0; i < daysAhead; i++) {
        const dateKey = i === 0 ? todayKey : bookingDateKeyAfterDays(i, timezone);
        const [year, month, day] = dateKey.split('-').map(Number);
        days.push(new Date(year, month - 1, day));
    }

    return days;
}

function dayLabel(date: Date, index: number): string {
    if (index === 0) return 'Today';
    if (index === 1) return 'Tomorrow';
    return DAY_NAMES[date.getDay()];
}

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

export function DateStrip({
    selectedDate,
    onSelect,
    daysAhead = 30,
    initialOffset = 0,
    availableSlotsByDate,
    closedDateRanges = [],
    timezone,
}: DateStripProps) {
    const days = buildDays(daysAhead, timezone);
    const [offset, setOffset] = useState(initialOffset);
    const VISIBLE = 7;
    const scrollRef = useRef<HTMLDivElement>(null);

    const canPrev = offset > 0;
    const canNext = offset + VISIBLE < days.length;

    const visibleDays = days.slice(offset, offset + VISIBLE);
    const todayKey = bookingTodayKey(timezone);

    return (
        <div className="flex items-center gap-2">
            <button
                type="button"
                onClick={() => setOffset((o) => Math.max(0, o - 3))}
                disabled={!canPrev}
                className={cn(
                    'flex size-8 shrink-0 items-center justify-center rounded-full border transition-colors',
                    canPrev
                        ? 'border-border bg-background text-foreground hover:bg-accent hover:border-primary'
                        : 'border-border/40 bg-background text-muted-foreground/30 cursor-not-allowed',
                )}
                aria-label="Previous dates"
            >
                <ChevronLeft className="size-4" />
            </button>

            <div ref={scrollRef} className="flex flex-1 gap-1.5 overflow-hidden">
                {visibleDays.map((date, i) => {
                    const globalIndex = offset + i;
                    const dateKey = toDateKeyStrip(date);
                    const isSelected = selectedDate ? isSameDay(date, selectedDate) : false;
                    const isPast = dateKey < todayKey;
                    const slots = availableSlotsByDate?.[dateKey];
                    const hasSlots = slots !== undefined && Object.keys(slots).length > 0;
                    const closedRange = closedDateRanges.find(
                        (r) => dateKey >= r.start_date && dateKey <= r.end_date,
                    );
                    const isClosed = !!closedRange;
                    const isUnavailable = availableSlotsByDate !== undefined && !hasSlots && !isPast;
                    const isDisabled = isPast || (availableSlotsByDate !== undefined && !hasSlots);

                    return (
                        <button
                            key={date.toISOString()}
                            type="button"
                            disabled={isDisabled}
                            onClick={() => !isDisabled && onSelect(date)}
                            className={cn(
                                'flex flex-1 flex-col items-center gap-0.5 rounded-xl border-2 py-2 text-center transition-all',
                                isSelected
                                    ? 'border-primary bg-primary text-primary-foreground shadow-md'
                                    : isPast
                                      ? 'border-border/30 bg-muted/30 text-muted-foreground/40 cursor-not-allowed'
                                      : isClosed
                                        ? 'border-border/30 bg-muted/20 text-muted-foreground/50 cursor-not-allowed'
                                        : isUnavailable
                                          ? 'border-border/30 bg-muted/20 text-muted-foreground/40 cursor-not-allowed'
                                          : 'border-border bg-background text-foreground hover:border-primary/60 hover:bg-primary/5 cursor-pointer',
                            )}
                        >
                            <span className={cn(
                                'text-[10px] font-medium leading-none',
                                isSelected ? 'text-primary-foreground/80' : 'text-muted-foreground',
                            )}>
                                {dayLabel(date, globalIndex)}
                            </span>
                            <span className="text-lg font-bold leading-none">
                                {date.getDate()}
                            </span>
                            {!isSelected && isClosed && (
                                <span className="text-[8px] font-semibold uppercase leading-none tracking-wide text-destructive/70">
                                    Closed
                                </span>
                            )}
                            {!isSelected && !isClosed && isUnavailable && (
                                <span className="text-[8px] leading-none text-muted-foreground/40">—</span>
                            )}
                        </button>
                    );
                })}
            </div>

            <button
                type="button"
                onClick={() => setOffset((o) => Math.min(days.length - VISIBLE, o + 3))}
                disabled={!canNext}
                className={cn(
                    'flex size-8 shrink-0 items-center justify-center rounded-full border transition-colors',
                    canNext
                        ? 'border-border bg-background text-foreground hover:bg-accent hover:border-primary'
                        : 'border-border/40 bg-background text-muted-foreground/30 cursor-not-allowed',
                )}
                aria-label="Next dates"
            >
                <ChevronRight className="size-4" />
            </button>
        </div>
    );
}
