"use client";

/**
 * NumberInput — 숫자 표시 통일 공용 컴포넌트 (RPS 숫자 포맷 정책)
 *
 * - 금액(decimals=2): 1,234.00
 * - 수량(decimals=0): 1,234
 * - 표시: 콤마 + 소수점 자릿수 강제 (blur 시 정규화)
 * - 편집: focus 시 raw 숫자 ("1234.5")로 전환되어 자유 입력 → blur 시 1,234.50 으로 재포맷
 * - onChange 는 항상 number(또는 빈 문자열) 만 부모로 전달
 */

import React, { useEffect, useRef, useState } from "react";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

export interface NumberInputProps {
  value: number | string | null | undefined;
  onChange: (v: number | "") => void;
  decimals?: number;     // 기본 0 (수량). 금액은 2.
  min?: number;
  max?: number;
  disabled?: boolean;
  placeholder?: string;
  className?: string;
  /** "right"=금액·수량 기본, 그 외도 가능 */
  align?: "right" | "left" | "center";
}

function toNumOrEmpty(v: any): number | "" {
  if (v === "" || v == null) return "";
  const n = Number(v);
  return Number.isFinite(n) ? n : "";
}

function formatFor(v: number | "", decimals: number): string {
  if (v === "") return "";
  return v.toLocaleString("ko-KR", {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  });
}

export function NumberInput({
  value,
  onChange,
  decimals = 0,
  min,
  max,
  disabled,
  placeholder,
  className,
  align = "right",
}: NumberInputProps) {
  const num = toNumOrEmpty(value);
  const [focused, setFocused] = useState(false);
  const [draft, setDraft] = useState<string>("");
  const inputRef = useRef<HTMLInputElement>(null);

  // 외부 value 변경 시 draft 동기화 (focus 중 외부 강제 갱신 시도는 무시 — 자연스러운 편집)
  useEffect(() => {
    if (!focused) setDraft("");
  }, [num, focused]);

  const displayValue = focused
    ? draft
    : (num === "" ? "" : formatFor(num, decimals));

  const onFocus = (e: React.FocusEvent<HTMLInputElement>) => {
    setFocused(true);
    setDraft(num === "" ? "" : String(num)); // raw 숫자 (콤마 X)
    // 전체 선택 — 빠른 재입력 편의
    requestAnimationFrame(() => e.target.select());
  };

  const onBlur = () => {
    setFocused(false);
    if (draft.trim() === "") {
      if (num !== "") onChange("");
      return;
    }
    // 콤마/공백 제거 후 숫자화
    const cleaned = draft.replace(/,/g, "").trim();
    let n = Number(cleaned);
    if (!Number.isFinite(n)) {
      // 잘못된 입력 → 이전 값 유지
      return;
    }
    if (decimals === 0) n = Math.floor(n);
    else n = Number(n.toFixed(decimals));
    if (min != null && n < min) n = min;
    if (max != null && n > max) n = max;
    onChange(n);
  };

  const onChangeInner = (e: React.ChangeEvent<HTMLInputElement>) => {
    // 편집 중엔 자유 입력 허용 (콤마·소수점·- 모두 허용 — blur 시 정규화)
    setDraft(e.target.value);
  };

  return (
    <Input
      ref={inputRef}
      type="text"
      inputMode={decimals > 0 ? "decimal" : "numeric"}
      disabled={disabled}
      placeholder={placeholder}
      value={displayValue}
      onFocus={onFocus}
      onBlur={onBlur}
      onChange={onChangeInner}
      className={cn(
        align === "right"  && "text-right",
        align === "center" && "text-center",
        className,
      )}
    />
  );
}
