"use client";

import * as React from "react";
import { format, parseISO } from "date-fns";
import { CalendarDays, X } from "lucide-react";
import type { DateRange } from "react-day-picker";

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

export type DateRangeValue = {
  from?: string;
  to?: string;
};

function parseYmd(value?: string): Date | undefined {
  if (!value?.trim()) return undefined;
  try {
    const parsed = parseISO(value.trim());
    return Number.isNaN(parsed.getTime()) ? undefined : parsed;
  } catch {
    return undefined;
  }
}

function toYmd(date?: Date): string | undefined {
  return date ? format(date, "yyyy-MM-dd") : undefined;
}

function rangeFromValue(value?: DateRangeValue): DateRange | undefined {
  const from = parseYmd(value?.from);
  if (!from) return undefined;
  const to = parseYmd(value?.to);
  return { from, to: to ?? from };
}

function formatRangeLabel(value?: DateRangeValue): string | null {
  const from = parseYmd(value?.from);
  if (!from) return null;
  const to = parseYmd(value?.to);
  if (to && to.toDateString() !== from.toDateString()) {
    return `${format(from, "MMM d, yyyy")} – ${format(to, "MMM d, yyyy")}`;
  }
  return format(from, "MMM d, yyyy");
}

export interface DateRangePickerProps {
  value?: DateRangeValue;
  onChange?: (range: DateRangeValue) => void;
  placeholder?: string;
  className?: string;
  triggerClassName?: string;
  disabled?: boolean;
  numberOfMonths?: number;
  calendarProps?: Omit<
    React.ComponentProps<typeof Calendar>,
    "mode" | "selected" | "onSelect"
  >;
}

export function DateRangePicker({
  value,
  onChange,
  placeholder = "Select date range",
  className,
  triggerClassName,
  disabled,
  numberOfMonths = 2,
  calendarProps,
}: DateRangePickerProps) {
  const [open, setOpen] = React.useState(false);
  const [draft, setDraft] = React.useState<DateRange | undefined>(() =>
    rangeFromValue(value),
  );

  React.useEffect(() => {
    if (!open) {
      setDraft(rangeFromValue(value));
    }
  }, [value, open]);

  const rangeLabel = formatRangeLabel(value);
  const hasValue = Boolean(value?.from);

  const handleApply = () => {
    const from = toYmd(draft?.from);
    const to = toYmd(draft?.to ?? draft?.from);
    if (from) {
      onChange?.({ from, to: to ?? from });
    }
    setOpen(false);
  };

  const handleClear = (e?: React.MouseEvent) => {
    e?.stopPropagation();
    setDraft(undefined);
    onChange?.({ from: undefined, to: undefined });
    setOpen(false);
  };

  return (
    <div className={cn("grid gap-2", className)}>
      <Popover
        open={open}
        onOpenChange={(next) => {
          setOpen(next);
          if (next) setDraft(rangeFromValue(value));
        }}
      >
        <PopoverTrigger asChild>
          <Button
            type="button"
            variant="outline"
            disabled={disabled}
            className={cn(
              "w-full justify-start text-left font-normal",
              !rangeLabel && "text-muted-foreground",
              hasValue && "border-accent/40 text-accent",
              triggerClassName,
            )}
          >
            <CalendarDays className="mr-2 size-4 shrink-0" aria-hidden />
            <span className="truncate" suppressHydrationWarning>
              {rangeLabel ?? placeholder}
            </span>
            {hasValue && (
              <X
                className="ml-auto size-4 shrink-0 opacity-60 hover:opacity-100"
                aria-label="Clear date range"
                onClick={handleClear}
              />
            )}
          </Button>
        </PopoverTrigger>
        <PopoverContent className="w-auto p-0" align="start">
          <Calendar
            mode="range"
            numberOfMonths={numberOfMonths}
            selected={draft}
            onSelect={setDraft}
            captionLayout="dropdown"
            initialFocus
            {...calendarProps}
          />
          <div className="flex items-center justify-between gap-2 border-t p-3">
            <p className="text-xs text-muted-foreground">
              {draft?.from && draft?.to
                ? formatRangeLabel({
                    from: toYmd(draft.from),
                    to: toYmd(draft.to),
                  })
                : draft?.from
                  ? `From ${format(draft.from, "MMM d, yyyy")}`
                  : "Select start and end dates"}
            </p>
            <div className="flex gap-2">
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={() => handleClear()}
              >
                Clear
              </Button>
              <Button
                type="button"
                size="sm"
                disabled={!draft?.from}
                onClick={handleApply}
              >
                Apply
              </Button>
            </div>
          </div>
        </PopoverContent>
      </Popover>
    </div>
  );
}
