"use client";

import {
	Button,
	Input,
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@mdxui/primitives";
import { Calendar } from "@mdxui/primitives/calendar";
import { cn } from "@mdxui/primitives/lib/utils";
import { format } from "date-fns";
import { Calendar as CalendarIcon, X } from "lucide-react";
import * as React from "react";
import { parseNaturalLanguageDate } from "./parser";
import type { SmartDateTimePickerProps } from "./types";

export function SmartDateTimePicker({
	value,
	onChange,
	placeholder = "Enter a date or time...",
	includeTime = false,
	minDate,
	maxDate,
	className,
	disabled,
}: SmartDateTimePickerProps) {
	const [inputValue, setInputValue] = React.useState("");
	const [isOpen, setIsOpen] = React.useState(false);
	const [parseError, setParseError] = React.useState(false);
	const inputRef = React.useRef<HTMLInputElement>(null);

	React.useEffect(() => {
		if (value) {
			setInputValue(
				includeTime
					? format(value, "MMM dd, yyyy HH:mm")
					: format(value, "MMM dd, yyyy"),
			);
		} else {
			setInputValue("");
		}
	}, [value, includeTime]);

	const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
		const newValue = e.target.value;
		setInputValue(newValue);
		setParseError(false);

		if (!newValue.trim()) {
			onChange?.(undefined);
			return;
		}

		// Try to parse on each change
		const parsed = parseNaturalLanguageDate(newValue);
		if (parsed) {
			// Check bounds
			if (minDate && parsed.date < minDate) {
				setParseError(true);
				return;
			}
			if (maxDate && parsed.date > maxDate) {
				setParseError(true);
				return;
			}
			onChange?.(parsed.date);
		}
	};

	const handleInputBlur = () => {
		if (!inputValue.trim()) {
			onChange?.(undefined);
			setParseError(false);
			return;
		}

		const parsed = parseNaturalLanguageDate(inputValue);
		if (parsed) {
			setInputValue(
				includeTime
					? format(parsed.date, "MMM dd, yyyy HH:mm")
					: format(parsed.date, "MMM dd, yyyy"),
			);
			setParseError(false);
		} else {
			setParseError(true);
		}
	};

	const handleCalendarSelect = (date: Date | undefined) => {
		if (date) {
			// Preserve time if includeTime is true and we have an existing value
			if (includeTime && value) {
				date.setHours(value.getHours());
				date.setMinutes(value.getMinutes());
			}
			onChange?.(date);
			setIsOpen(false);
		}
	};

	const handleClear = () => {
		setInputValue("");
		onChange?.(undefined);
		setParseError(false);
		inputRef.current?.focus();
	};

	const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.key === "Enter") {
			e.preventDefault();
			handleInputBlur();
			inputRef.current?.blur();
		} else if (e.key === "Escape") {
			handleClear();
		}
	};

	return (
		<div className={cn("relative", className)}>
			<div className="relative flex items-center gap-2">
				<div className="relative flex-1">
					<Input
						ref={inputRef}
						type="text"
						value={inputValue}
						onChange={handleInputChange}
						onBlur={handleInputBlur}
						onKeyDown={handleKeyDown}
						placeholder={placeholder}
						disabled={disabled}
						className={cn(
							"pr-20",
							parseError &&
								"border-destructive focus-visible:ring-destructive/20",
						)}
						aria-invalid={parseError}
					/>
					<div className="absolute inset-y-0 right-0 flex items-center gap-1 pr-2">
						{inputValue && (
							<Button
								type="button"
								variant="ghost"
								size="icon-sm"
								onClick={handleClear}
								disabled={disabled}
								className="size-6"
							>
								<X className="size-3" />
							</Button>
						)}
						<Popover open={isOpen} onOpenChange={setIsOpen}>
							<PopoverTrigger asChild>
								<Button
									type="button"
									variant="ghost"
									size="icon-sm"
									disabled={disabled}
									className="size-6"
								>
									<CalendarIcon className="size-3" />
								</Button>
							</PopoverTrigger>
							<PopoverContent className="w-auto p-0" align="end">
								<Calendar
									mode="single"
									selected={value}
									onSelect={handleCalendarSelect}
									disabled={(date: Date) => {
										if (minDate && date < minDate) return true;
										if (maxDate && date > maxDate) return true;
										return false;
									}}
								/>
							</PopoverContent>
						</Popover>
					</div>
				</div>
			</div>
			{parseError && (
				<p className="mt-1 text-xs text-destructive">
					Unable to parse date. Try formats like "tomorrow", "2024-12-25", or
					"in 3 days"
				</p>
			)}
			{!parseError && inputValue && value && (
				<p className="mt-1 text-xs text-muted-foreground">
					Parsed as: {format(value, includeTime ? "PPpp" : "PPP")}
				</p>
			)}
		</div>
	);
}
