"use client";

import React from "react";
import { CalendarRange, X } from "lucide-react";

import {
	formatIsoDateDe,
	formatIsoDateRangeLabelDe,
	toDateFromIsoDateYmd,
	toIsoDateYmdFromDate,
	compareIsoDatesYmd,
	normalizeIsoDateYmdOrNull,
} from "@/lib/frontend/search/dateRange";

import { buildDatePresets } from "@/lib/frontend/search/datePresets";

import { Calendar } from "@/components/ui/calendar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@/components/ui/popover";
import { cn } from "@/lib/utils";

const FIELD = Object.freeze({
	FROM: "from",
	TO: "to",
});

function pickInitialActiveField(from, to) {
	if (!from) return FIELD.FROM;
	if (from && !to) return FIELD.TO;
	return FIELD.FROM;
}

function focusById(id) {
	if (typeof document === "undefined") return;
	const el = document.getElementById(id);
	if (el && typeof el.focus === "function") el.focus();
}

function buildDisplayedRange(from, to) {
	const fIso = normalizeIsoDateYmdOrNull(from);
	const tIso = normalizeIsoDateYmdOrNull(to);

	const f = toDateFromIsoDateYmd(fIso);
	const t = toDateFromIsoDateYmd(tIso);

	if (f && t && compareIsoDatesYmd(fIso, tIso) <= 0) {
		return { from: f, to: t };
	}

	if (f) return { from: f, to: undefined };
	if (t) return { from: t, to: undefined };

	return undefined;
}

export default function SearchDateRangePicker({
	from,
	to,
	onDateRangeChange,
	isSubmitting,
}) {
	const [open, setOpen] = React.useState(false);
	const [activeField, setActiveField] = React.useState(() =>
		pickInitialActiveField(from, to)
	);

	const fromBtnId = React.useId();
	const toBtnId = React.useId();

	const fromDate = React.useMemo(() => toDateFromIsoDateYmd(from), [from]);
	const toDate = React.useMemo(() => toDateFromIsoDateYmd(to), [to]);

	const now = React.useMemo(() => new Date(), []);
	const presets = React.useMemo(() => buildDatePresets({ now }), [now]);

	// Calendar month anchor (controlled) so we can keep UX stable when switching fields.
	const [month, setMonth] = React.useState(() => fromDate || toDate || now);

	// When popover opens: pick a sensible active field and month anchor.
	React.useEffect(() => {
		if (!open) return;

		const nextActive = pickInitialActiveField(from, to);
		setActiveField(nextActive);

		const nextMonth =
			nextActive === FIELD.FROM
				? fromDate || toDate || now
				: toDate || fromDate || now;

		setMonth(nextMonth);

		queueMicrotask(() => {
			focusById(nextActive === FIELD.FROM ? fromBtnId : toBtnId);
		});
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [open]);

	const label = formatIsoDateRangeLabelDe({ from, to }) || "Zeitraum";
	const fromLabel = formatIsoDateDe(from) || "Startdatum";
	const toLabel = formatIsoDateDe(to) || "Enddatum";

	const canClearBoth = Boolean((from || to) && !isSubmitting);
	const canClearFrom = Boolean(from && !isSubmitting);
	const canClearTo = Boolean(to && !isSubmitting);

	const activeBlue =
		"border-blue-600 bg-blue-50 dark:border-blue-900 dark:bg-blue-950";

	const fromYear = 2000;
	const toYear = now.getFullYear() + 1;

	// Show the selected range visually (works for presets too).
	const displayedRange = React.useMemo(() => {
		return buildDisplayedRange(from, to);
	}, [from, to]);

	function commit(nextFrom, nextTo) {
		if (typeof onDateRangeChange !== "function") return;
		onDateRangeChange({ from: nextFrom, to: nextTo });
	}

	function setActive(field) {
		setActiveField(field);

		const nextMonth =
			field === FIELD.FROM ? fromDate || month : toDate || month;

		if (nextMonth) setMonth(nextMonth);

		queueMicrotask(() => {
			focusById(field === FIELD.FROM ? fromBtnId : toBtnId);
		});
	}

	function clearFrom() {
		if (!canClearFrom) return;

		commit(null, to ?? null);

		setActiveField(FIELD.FROM);
		setMonth(toDate || now);

		queueMicrotask(() => focusById(fromBtnId));
	}

	function clearTo() {
		if (!canClearTo) return;

		commit(from ?? null, null);

		setActiveField(FIELD.TO);
		setMonth(fromDate || now);

		queueMicrotask(() => focusById(toBtnId));
	}

	function clearBoth() {
		if (!canClearBoth) return;

		commit(null, null);

		setActiveField(FIELD.FROM);
		setMonth(now);

		queueMicrotask(() => focusById(fromBtnId));
	}

	function applyPreset(preset) {
		if (!preset?.from || !preset?.to) return;

		commit(preset.from, preset.to);

		// Keep popover open so the user immediately sees the range highlighted.
		setActiveField(FIELD.TO);

		const nextMonth = toDateFromIsoDateYmd(preset.from) || now;
		setMonth(nextMonth);

		queueMicrotask(() => focusById(toBtnId));
	}

	function handleDayClick(day) {
		if (!(day instanceof Date) || Number.isNaN(day.getTime())) return;

		const iso = toIsoDateYmdFromDate(day);
		if (!iso) return;

		if (activeField === FIELD.FROM) {
			commit(iso, to ?? null);

			// After selecting FROM, auto-switch to TO (fast range building).
			setActiveField(FIELD.TO);
			setMonth(day);

			queueMicrotask(() => focusById(toBtnId));
			return;
		}

		// TO
		commit(from ?? null, iso);
		setMonth(day);

		// Keep popover open; closing is user-controlled (click outside).
	}

	return (
		<div className="grid gap-2">
			<Label>Zeitraum</Label>

			<Popover open={open} onOpenChange={setOpen}>
				<PopoverTrigger asChild>
					<Button
						type="button"
						variant="outline"
						disabled={isSubmitting}
						title="Zeitraum auswählen"
						className="justify-between"
					>
						<span className="truncate">{label}</span>
						<CalendarRange className="h-4 w-4 opacity-70" />
					</Button>
				</PopoverTrigger>

				{/* w-fit keeps the popover as compact as the 2-month calendar */}
				<PopoverContent align="start" className="w-fit p-0">
					<div className="p-3 space-y-3">
						{/* Presets (wrap + compact) */}
						<div className="space-y-2">
							<p className="text-xs text-muted-foreground">Schnellwahl</p>

							<div className="flex flex-wrap gap-2">
								{presets.map((p) => (
									<Badge key={p.key} variant="secondary" asChild>
										<button
											type="button"
											className="cursor-pointer select-none hover:opacity-90"
											disabled={isSubmitting}
											onClick={() => applyPreset(p)}
											title={`Schnellwahl: ${p.label}`}
										>
											{p.label}
										</button>
									</Badge>
								))}
							</div>
						</div>

						{/* Von / Bis controls */}
						<div className="grid grid-cols-2 gap-3">
							<div className="grid gap-2">
								<Label>Von</Label>
								<div className="relative">
									<Button
										id={fromBtnId}
										type="button"
										variant="outline"
										size="sm"
										disabled={isSubmitting}
										onClick={() => setActive(FIELD.FROM)}
										className={cn(
											"w-full justify-between pr-10",
											activeField === FIELD.FROM ? activeBlue : ""
										)}
										title="Startdatum auswählen"
									>
										<span className="truncate">{fromLabel}</span>
									</Button>

									{canClearFrom ? (
										<button
											type="button"
											className="absolute right-2 top-1/2 -translate-y-1/2 inline-flex h-6 w-6 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted/60 hover:text-foreground"
											onClick={(e) => {
												e.preventDefault();
												e.stopPropagation();
												clearFrom();
											}}
											aria-label="Startdatum löschen"
											title="Startdatum löschen"
										>
											<X className="h-4 w-4" />
										</button>
									) : null}
								</div>
							</div>

							<div className="grid gap-2">
								<Label>Bis</Label>
								<div className="relative">
									<Button
										id={toBtnId}
										type="button"
										variant="outline"
										size="sm"
										disabled={isSubmitting}
										onClick={() => setActive(FIELD.TO)}
										className={cn(
											"w-full justify-between pr-10",
											activeField === FIELD.TO ? activeBlue : ""
										)}
										title="Enddatum auswählen"
									>
										<span className="truncate">{toLabel}</span>
									</Button>

									{canClearTo ? (
										<button
											type="button"
											className="absolute right-2 top-1/2 -translate-y-1/2 inline-flex h-6 w-6 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted/60 hover:text-foreground"
											onClick={(e) => {
												e.preventDefault();
												e.stopPropagation();
												clearTo();
											}}
											aria-label="Enddatum löschen"
											title="Enddatum löschen"
										>
											<X className="h-4 w-4" />
										</button>
									) : null}
								</div>
							</div>
						</div>

						{/* Calendar: 2 months + range highlight */}
						<Calendar
							mode="range"
							captionLayout="dropdown"
							fromYear={fromYear}
							toYear={toYear}
							numberOfMonths={2}
							pagedNavigation
							month={month}
							onMonthChange={setMonth}
							selected={displayedRange}
							onDayClick={(day) => handleDayClick(day)}
							initialFocus
						/>

						<div className="flex justify-end gap-2 pt-1">
							<Button
								type="button"
								variant="outline"
								size="sm"
								disabled={!canClearBoth}
								onClick={clearBoth}
								title="Zeitraum entfernen"
							>
								Zurücksetzen
							</Button>
						</div>

						<div className="text-xs text-muted-foreground">
							Tipp: Für einen einzelnen Tag setzen Sie <strong>Von</strong> und{" "}
							<strong>Bis</strong> auf dasselbe Datum.
						</div>
					</div>
				</PopoverContent>
			</Popover>
		</div>
	);
}
