"use client";

/**
 * DateInput — YYYY-MM-DD 형식 통일 공용 날짜 입력 컴포넌트
 *
 * 브라우저 `<input type="date">` 는 OS/로케일에 따라 "연도. 월. 일." 등 다른 placeholder 를
 * 보여주는 문제가 있어, text input + Popover Calendar 로 표시·저장을 YYYY-MM-DD 로 통일.
 *
 * - 직접 타이핑: YYYY-MM-DD (8자리 숫자 입력 시 자동으로 - 삽입)
 * - 캘린더 아이콘 클릭 → Popover Calendar 에서 날짜 선택
 * - 항상 onChange 에 'YYYY-MM-DD' 또는 빈 문자열 전달
 */

import React, { useMemo, useState, useEffect, useRef } from "react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Calendar } from "@/components/ui/calendar";
import { Input } from "@/components/ui/input";
import { Calendar as CalendarIcon, X } from "lucide-react";
import { cn } from "@/lib/utils";
import { format, parse, isValid } from "date-fns";

const FMT = "yyyy-MM-dd";

export interface DateInputProps {
  value: string;       // 'YYYY-MM-DD' 또는 ''
  onChange: (v: string) => void;
  disabled?: boolean;
  placeholder?: string;
  className?: string;
  /** sm = h-7 (CompactFilter 행), md = h-9 (다이얼로그 폼) */
  size?: "sm" | "md";
  /** 값이 있을 때 ✕ 노출 (기본 true). 필수 필드는 false. */
  clearable?: boolean;
}

function toDate(v: string): Date | null {
  if (!v) return null;
  const d = parse(v, FMT, new Date());
  return isValid(d) ? d : null;
}

function isCompleteDate(v: string): boolean {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(v)) return false;
  const d = parse(v, FMT, new Date());
  return isValid(d);
}

/** 사용자 타이핑을 8자리 숫자로 받아 YYYY-MM-DD 로 슬라이스 */
function autoFormat(raw: string): string {
  const digits = raw.replace(/\D/g, "").slice(0, 8);
  if (digits.length <= 4) return digits;
  if (digits.length <= 6) return `${digits.slice(0, 4)}-${digits.slice(4)}`;
  return `${digits.slice(0, 4)}-${digits.slice(4, 6)}-${digits.slice(6, 8)}`;
}

export function DateInput({
  value,
  onChange,
  disabled,
  placeholder = "YYYY-MM-DD",
  className,
  size = "md",
  clearable = true,
}: DateInputProps) {
  const [open, setOpen] = useState(false);
  const [text, setText] = useState(value || "");
  const inputRef = useRef<HTMLInputElement>(null);

  // 외부 value 동기화
  useEffect(() => {
    setText(value || "");
  }, [value]);

  const selectedDate = useMemo(() => toDate(value), [value]);
  const invalid = text.length > 0 && !isCompleteDate(text);
  const showClear = clearable && !disabled && !!value;

  const onTextChange = (raw: string) => {
    const formatted = autoFormat(raw);
    setText(formatted);
    if (formatted === "") {
      onChange("");
    } else if (isCompleteDate(formatted)) {
      onChange(formatted);
    }
    // 아직 미완성이면 onChange 호출 안 함 (마지막 유효값 유지)
  };

  const onBlur = () => {
    // 미완성 텍스트는 마지막 유효값으로 복귀
    if (text && !isCompleteDate(text)) setText(value || "");
  };

  const handleCalendarSelect = (d: Date | undefined) => {
    if (!d) { onChange(""); setText(""); }
    else { const v = format(d, FMT); onChange(v); setText(v); }
    setOpen(false);
  };

  const handleClear = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    onChange("");
    setText("");
    inputRef.current?.focus();
  };

  const h = size === "sm" ? "h-7" : "h-9";
  const textCls = size === "sm" ? "text-xs" : "text-sm";

  return (
    <div className={cn("relative inline-flex items-center", className)}>
      <Input
        ref={inputRef}
        type="text"
        inputMode="numeric"
        placeholder={placeholder}
        value={text}
        disabled={disabled}
        onChange={(e) => onTextChange(e.target.value)}
        onBlur={onBlur}
        className={cn(
          h, textCls, "pr-16 w-full",
          invalid && "border-destructive focus-visible:ring-destructive",
        )}
        aria-invalid={invalid || undefined}
      />
      {showClear && (
        <button
          type="button"
          tabIndex={-1}
          aria-label="날짜 지우기"
          onMouseDown={(e) => { e.preventDefault(); e.stopPropagation(); }}
          onClick={handleClear}
          className="absolute right-8 top-1/2 -translate-y-1/2 z-10 inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-muted"
        >
          <X className="h-3.5 w-3.5" />
        </button>
      )}
      <Popover open={open} onOpenChange={setOpen}>
        <PopoverTrigger asChild>
          <button
            type="button"
            disabled={disabled}
            aria-label="캘린더 열기"
            className={cn(
              "absolute right-1 top-1/2 -translate-y-1/2 z-10 inline-flex items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed",
              size === "sm" ? "h-5 w-5" : "h-6 w-6",
            )}
          >
            <CalendarIcon className="h-3.5 w-3.5" />
          </button>
        </PopoverTrigger>
        <PopoverContent className="w-auto p-0" align="end">
          <Calendar
            mode="single"
            selected={selectedDate || undefined}
            onSelect={handleCalendarSelect}
            initialFocus
          />
        </PopoverContent>
      </Popover>
    </div>
  );
}
