"use client";

import * as React from "react";
import type { DateRange } from "react-day-picker";
import { format, parse } from "date-fns";
import { enUS } from "date-fns/locale";
import { CalendarRange } from "lucide-react";
import { useTranslation } from "react-i18next";

import { Button, buttonVariants } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";

export type AdminDateRangeCalendarMarkers = {
  /** 本地日历 `yyyy-MM-dd` — 已有账期，不可选 */
  occupiedPeriod?: string[];
  /** 本地日历 `yyyy-MM-dd` */
  pendingActivity?: string[];
  /** 本地日历 `yyyy-MM-dd` — 已有账期内的未结清日 */
  unpaidBill?: string[];
};

function parseYmd(value: string): Date | undefined {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
    return undefined;
  }
  const d = parse(value, "yyyy-MM-dd", new Date());
  return Number.isNaN(d.getTime()) ? undefined : d;
}

function formatYmd(d: Date): string {
  return format(d, "yyyy-MM-dd");
}

function summarize(from: string, to: string, placeholder: string): string {
  const df = parseYmd(from);
  const dt = parseYmd(to);
  if (!df && !dt) {
    return placeholder;
  }
  const a = df ? format(df, "yyyy-MM-dd", { locale: enUS }) : "...";
  const b = dt ? format(dt, "yyyy-MM-dd", { locale: enUS }) : "...";
  return `${a} - ${b}`;
}

/** Range date picker compatible with legacy `yyyy-MM-dd` filter fields. */
export function AdminDateRangeField({
  id,
  label,
  from: fromProp,
  to: toProp,
  onRangeChange,
  placeholder,
  rangeHint,
  calendarMarkers,
  disabled,
}: {
  id: string;
  label?: string;
  from: string;
  to: string;
  onRangeChange: (next: { from: string; to: string }) => void;
  placeholder?: string;
  rangeHint?: string;
  calendarMarkers?: AdminDateRangeCalendarMarkers;
  disabled?: boolean;
}) {
  const { t } = useTranslation(["common"]);
  const [open, setOpen] = React.useState(false);
  const isMobile = useIsMobile();
  const resolvedPlaceholder =
    placeholder ?? t("date.rangePlaceholder", { ns: "common", defaultValue: "Select date range" });

  const selected = React.useMemo((): DateRange | undefined => {
    const df = parseYmd(fromProp);
    const dt = parseYmd(toProp);
    if (!df && !dt) {
      return undefined;
    }
    if (df && !dt) {
      return { from: df };
    }
    if (df && dt) {
      return { from: df, to: dt };
    }
    return dt ? { from: dt } : undefined;
  }, [fromProp, toProp]);

  const hasSelection = Boolean(parseYmd(fromProp) || parseYmd(toProp));
  const defaultMonth = selected?.from ?? selected?.to ?? new Date();

  const pendingActivityDates = React.useMemo(
    () =>
      (calendarMarkers?.pendingActivity ?? [])
        .map((ymd) => parseYmd(ymd))
        .filter((d): d is Date => d instanceof Date),
    [calendarMarkers?.pendingActivity],
  );
  const occupiedPeriodDates = React.useMemo(
    () =>
      (calendarMarkers?.occupiedPeriod ?? [])
        .map((ymd) => parseYmd(ymd))
        .filter((d): d is Date => d instanceof Date),
    [calendarMarkers?.occupiedPeriod],
  );
  const unpaidBillDates = React.useMemo(
    () =>
      (calendarMarkers?.unpaidBill ?? [])
        .map((ymd) => parseYmd(ymd))
        .filter((d): d is Date => d instanceof Date),
    [calendarMarkers?.unpaidBill],
  );

  return (
    <div className="grid gap-1.5">
      {label ? (
        <Label htmlFor={id} className="leading-none">
          {label}
        </Label>
      ) : null}
      <Popover
        modal={false}
        open={open}
        onOpenChange={(next) => {
          setOpen(next);
        }}
      >
        <PopoverTrigger
          type="button"
          id={id}
          disabled={disabled}
          className={cn(
            buttonVariants({ variant: "outline", size: "default" }),
            "h-8 min-h-8 w-full justify-start gap-2 px-2.5 font-normal md:text-sm",
            !hasSelection && "text-muted-foreground",
          )}
        >
          <CalendarRange className="pointer-events-none size-4 shrink-0 opacity-70" aria-hidden />
          <span className="min-w-0 flex-1 truncate text-left">
            {summarize(fromProp, toProp, resolvedPlaceholder)}
          </span>
        </PopoverTrigger>
        <PopoverContent align="start" sideOffset={6} className="w-auto max-w-[calc(100vw-2rem)] min-w-fit p-0">
          {rangeHint ? (
            <p className="text-muted-foreground border-b px-3 py-2 text-xs leading-relaxed">{rangeHint}</p>
          ) : (
            <p className="text-muted-foreground border-b px-3 py-2 text-xs leading-relaxed">
              {t("date.rangeHint", {
                ns: "common",
                defaultValue:
                  "Select a start date, then an end date. For a single day, click the same date twice. Click Done to close.",
              })}
            </p>
          )}
          <Calendar
            mode="range"
            locale={enUS}
            captionLayout="dropdown"
            selected={selected}
            defaultMonth={defaultMonth}
            numberOfMonths={isMobile ? 1 : 2}
            disabled={occupiedPeriodDates}
            modifiers={{
              occupiedPeriod: occupiedPeriodDates,
              pendingActivity: pendingActivityDates,
              unpaidBill: unpaidBillDates,
            }}
            modifiersClassNames={{
              occupiedPeriod:
                "[&>button]:cursor-not-allowed [&>button]:bg-muted/80 [&>button]:text-muted-foreground [&>button]:line-through [&>button]:opacity-70",
              pendingActivity:
                "[&:not([data-disabled=true])>button]:relative [&:not([data-disabled=true])>button]:after:absolute [&:not([data-disabled=true])>button]:after:bottom-0.5 [&:not([data-disabled=true])>button]:after:left-1/2 [&:not([data-disabled=true])>button]:after:size-1 [&:not([data-disabled=true])>button]:after:-translate-x-1/2 [&:not([data-disabled=true])>button]:after:rounded-full [&:not([data-disabled=true])>button]:after:bg-amber-500 [&:not([data-disabled=true])>button]:after:content-['']",
              unpaidBill:
                "[&>button]:relative [&>button]:before:absolute [&>button]:before:top-0.5 [&>button]:before:right-0.5 [&>button]:before:size-1.5 [&>button]:before:rounded-full [&>button]:before:bg-rose-500 [&>button]:before:content-['']",
            }}
            onSelect={(range) => {
              if (!range?.from && !range?.to) {
                onRangeChange({ from: "", to: "" });
                return;
              }
              const nf = range.from ? formatYmd(range.from) : "";
              const nt = range.to ? formatYmd(range.to) : "";
              onRangeChange({ from: nf, to: nt });
            }}
          />
          <div className="flex items-center justify-end gap-2 border-t px-2 py-1.5">
            <Button
              type="button"
              variant="ghost"
              size="xs"
              className="h-7 px-2"
              onClick={() => {
                onRangeChange({ from: "", to: "" });
                setOpen(false);
              }}
            >
              {t("actions.clear", { ns: "common", defaultValue: "Clear" })}
            </Button>
            <Button
              type="button"
              variant="secondary"
              size="xs"
              className="h-7 px-2"
              onClick={() => {
                setOpen(false);
              }}
            >
              {t("actions.done", { ns: "common", defaultValue: "Done" })}
            </Button>
          </div>
        </PopoverContent>
      </Popover>
    </div>
  );
}
