"use client";

import { addDays } from "date-fns";
import * as React from "react";
import { DatePicker } from "@/components/ui/date-picker";
import { Label } from "@/components/ui/label";
import {
	TimePicker,
	TimePickerContent,
	TimePickerHour,
	TimePickerInput,
	TimePickerInputGroup,
	TimePickerLabel,
	TimePickerMinute,
	TimePickerPeriod,
	TimePickerSeparator,
	TimePickerTrigger,
} from "@/components/ui/time-picker";
import { cn } from "@/lib/utils";

function getIs12Hour(locale?: string): boolean {
	const testDate = new Date(2000, 0, 1, 13, 0, 0);
	const formatted = new Intl.DateTimeFormat(locale, {
		hour: "numeric",
	}).format(testDate);

	return /am|pm/i.test(formatted) || !formatted.includes("13");
}

interface FlightTimePickerProps {
	defaultValue: string;
	id: string;
	is12Hour: boolean;
	label: string;
	locale: string | undefined;
}

function FlightTimePicker({
	defaultValue,
	id,
	is12Hour,
	label,
	locale,
}: FlightTimePickerProps) {
	return (
		<TimePicker
			key={`${id}-${locale ?? "default"}`}
			defaultValue={defaultValue}
			locale={locale}
			className="w-28 shrink-0"
		>
			<TimePickerLabel className="sr-only">{label}</TimePickerLabel>
			<TimePickerInputGroup className="bg-background">
				<TimePickerInput id={id} segment="hour" />
				<TimePickerSeparator />
				<TimePickerInput segment="minute" />
				{is12Hour ? (
					<TimePickerInput className="ml-1" segment="period" />
				) : null}
				<TimePickerTrigger aria-label={`Open ${label.toLowerCase()} picker`} />
			</TimePickerInputGroup>
			<TimePickerContent className="max-w-none w-max overflow-hidden p-0">
				<div className="flex">
					<div className="flex flex-col border-r">
						<div className="border-b px-2 py-1.5 text-center text-xs font-semibold text-muted-foreground">
							Hr
						</div>
						<TimePickerHour className="min-w-12 border-none" format="2-digit" />
					</div>
					<div className={cn("flex flex-col", is12Hour && "border-r")}>
						<div className="border-b px-2 py-1.5 text-center text-xs font-semibold text-muted-foreground">
							Min
						</div>
						<TimePickerMinute className="min-w-12 border-none" />
					</div>
					{is12Hour ? (
						<div className="flex flex-col">
							<div className="border-b px-2 py-1.5 text-center text-xs font-semibold text-muted-foreground">
								AM/PM
							</div>
							<TimePickerPeriod className="min-w-14 border-none" />
						</div>
					) : null}
				</div>
			</TimePickerContent>
		</TimePicker>
	);
}

export function CombinedDatePickerDemo() {
	const dateFromId = React.useId();
	const dateToId = React.useId();
	const timeFromId = React.useId();
	const timeToId = React.useId();
	const today = React.useMemo(() => new Date(), []);
	const departureDefault = React.useMemo(() => today, [today]);
	const returnDefault = React.useMemo(() => addDays(today, 7), [today]);
	const [openFrom, setOpenFrom] = React.useState(false);
	const [openTo, setOpenTo] = React.useState(false);
	const [dateFrom, setDateFrom] = React.useState<Date | undefined>(
		departureDefault,
	);
	const [dateTo, setDateTo] = React.useState<Date | undefined>(returnDefault);
	const [monthFrom, setMonthFrom] = React.useState(departureDefault);
	const [monthTo, setMonthTo] = React.useState(returnDefault);
	const [timeLocale, setTimeLocale] = React.useState<string | undefined>(
		undefined,
	);
	const [mounted, setMounted] = React.useState(false);

	React.useEffect(() => {
		setMounted(true);
		setTimeLocale(
			new Intl.DateTimeFormat(undefined, {
				hour: "numeric",
			}).resolvedOptions().locale,
		);
	}, []);

	const is12Hour = mounted ? getIs12Hour(timeLocale) : false;

	return (
		<div className="flex w-full max-w-sm min-w-0 flex-col gap-6">
			<div className="flex items-end gap-4">
				<div className="flex flex-1 flex-col gap-3">
					<Label htmlFor={dateFromId} className="px-1">
						Departure date
					</Label>
					<DatePicker
						id={dateFromId}
						date={dateFrom}
						variant="input"
						open={openFrom}
						onOpenChange={setOpenFrom}
						month={monthFrom}
						onMonthChange={setMonthFrom}
						onSelect={(nextDate) => {
							setDateFrom(nextDate);
							if (nextDate && dateTo && nextDate > dateTo) {
								setDateTo(nextDate);
								setMonthTo(nextDate);
							}
						}}
					/>
				</div>
				<div className="flex flex-col gap-3">
					<FlightTimePicker
						id={timeFromId}
						defaultValue="09:30"
						is12Hour={is12Hour}
						label="Departure time"
						locale={timeLocale}
					/>
				</div>
			</div>
			<div className="flex items-end gap-4">
				<div className="flex flex-1 flex-col gap-3">
					<Label htmlFor={dateToId} className="px-1">
						Return date
					</Label>
					<DatePicker
						id={dateToId}
						date={dateTo}
						variant="input"
						open={openTo}
						onOpenChange={setOpenTo}
						month={monthTo}
						onMonthChange={setMonthTo}
						disabled={dateFrom ? { before: dateFrom } : undefined}
						onSelect={setDateTo}
					/>
				</div>
				<div className="flex flex-col gap-3">
					<FlightTimePicker
						id={timeToId}
						defaultValue="18:30"
						is12Hour={is12Hour}
						label="Return time"
						locale={timeLocale}
					/>
				</div>
			</div>
		</div>
	);
}
