"use client";

/**
 * 계층구조 코드 선택 컴포넌트 (1단계, 2단계, 3단계 셀렉트박스)
 *
 * 2026-05-15 새 마스터-디테일 스키마 기준:
 *   - 그룹의 전체 트리를 한 번에 받아 로컬에서 부모/depth 필터
 *   - 새 스키마 depth 는 2 부터 시작 → "1단계" = depth 2, "2단계" = depth 3, "3단계" = depth 4
 *
 * @example
 * <HierarchicalCodeSelect
 *   categoryCode="PRODUCT_CATEGORY"
 *   maxDepth={3}
 *   value={selectedCode}
 *   onChange={(code) => setSelectedCode(code)}
 * />
 */

import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { getCodeDetailTree } from "@/lib/api/commonCode";
import { Loader2 } from "lucide-react";
import type { CodeDetail } from "@/types/commonCode";

export interface HierarchicalCodeSelectProps {
  /** 그룹 코드 (code_info) — prop 명은 하위 호환 위해 categoryCode 유지 */
  categoryCode: string;
  /** 최대 깊이 (1=tree depth 2, 2=tree depth 3, 3=tree depth 4) */
  maxDepth?: 1 | 2 | 3;
  /** 현재 선택된 코드값 */
  value?: string;
  /** 값 변경 핸들러 */
  onChange?: (codeValue: string, row?: CodeDetail, fullPath?: CodeDetail[]) => void;
  /** 각 단계별 라벨 */
  labels?: [string, string?, string?];
  /** 각 단계별 placeholder */
  placeholders?: [string, string?, string?];
  /** 비활성화 */
  disabled?: boolean;
  /** 필수 입력 */
  required?: boolean;
  /** 메뉴 OBJID (현재 미사용 — 호환용) */
  menuObjid?: number;
  /** 추가 클래스 */
  className?: string;
  /** 인라인 표시 (가로 배열) */
  inline?: boolean;
}

export function HierarchicalCodeSelect({
  categoryCode,
  maxDepth = 3,
  value,
  onChange,
  labels = ["1단계", "2단계", "3단계"],
  placeholders = ["선택하세요", "선택하세요", "선택하세요"],
  disabled = false,
  required = false,
  className = "",
  inline = false,
}: HierarchicalCodeSelectProps) {
  const [allRows, setAllRows] = useState<CodeDetail[]>([]);
  const [loading, setLoading] = useState(false);

  const [selected1, setSelected1] = useState<string>("");
  const [selected2, setSelected2] = useState<string>("");
  const [selected3, setSelected3] = useState<string>("");

  // 트리 전체 로드
  useEffect(() => {
    if (!categoryCode) {
      setAllRows([]);
      return;
    }
    let cancelled = false;
    setLoading(true);
    getCodeDetailTree({ code_info: categoryCode, is_active: true })
      .then((res) => {
        if (!cancelled) setAllRows(res.data || []);
      })
      .catch((err) => {
        console.error("계층 코드 로드 실패:", err);
        if (!cancelled) setAllRows([]);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [categoryCode]);

  // depth=2 = 1단계, depth=3 = 2단계, depth=4 = 3단계
  const level1Options = useMemo(
    () => allRows.filter((r) => (r.depth ?? 2) === 2),
    [allRows],
  );

  const level2Options = useMemo(() => {
    if (!selected1) return [];
    const parent = allRows.find((r) => r.code_value === selected1 && (r.depth ?? 2) === 2);
    if (!parent) return [];
    return allRows.filter(
      (r) => (r.depth ?? 2) === 3 && r.parent_detail_id === parent.code_detail_id,
    );
  }, [allRows, selected1]);

  const level3Options = useMemo(() => {
    if (!selected2) return [];
    const parent = allRows.find((r) => r.code_value === selected2 && (r.depth ?? 2) === 3);
    if (!parent) return [];
    return allRows.filter(
      (r) => (r.depth ?? 2) === 4 && r.parent_detail_id === parent.code_detail_id,
    );
  }, [allRows, selected2]);

  // value prop 으로 역추적
  useEffect(() => {
    if (!value || allRows.length === 0) {
      return;
    }
    const target = allRows.find((r) => r.code_value === value);
    if (!target) return;

    const depth = target.depth ?? 2;
    if (depth === 2) {
      setSelected1(value);
      setSelected2("");
      setSelected3("");
    } else if (depth === 3) {
      const parent = allRows.find((r) => r.code_detail_id === target.parent_detail_id);
      setSelected1(parent?.code_value || "");
      setSelected2(value);
      setSelected3("");
    } else if (depth === 4) {
      const parent2 = allRows.find((r) => r.code_detail_id === target.parent_detail_id);
      const parent1 = parent2
        ? allRows.find((r) => r.code_detail_id === parent2.parent_detail_id)
        : undefined;
      setSelected1(parent1?.code_value || "");
      setSelected2(parent2?.code_value || "");
      setSelected3(value);
    }
  }, [value, allRows]);

  const handle1 = useCallback(
    (v: string) => {
      setSelected1(v);
      setSelected2("");
      setSelected3("");
      if (maxDepth === 1 && onChange) {
        const row = level1Options.find((r) => r.code_value === v);
        onChange(v, row, row ? [row] : []);
      }
    },
    [maxDepth, onChange, level1Options],
  );

  const handle2 = useCallback(
    (v: string) => {
      setSelected2(v);
      setSelected3("");
      if (maxDepth === 2 && onChange) {
        const row1 = level1Options.find((r) => r.code_value === selected1);
        const row2 = level2Options.find((r) => r.code_value === v);
        const path = [row1, row2].filter(Boolean) as CodeDetail[];
        onChange(v, row2, path);
      }
    },
    [maxDepth, onChange, level1Options, level2Options, selected1],
  );

  const handle3 = useCallback(
    (v: string) => {
      setSelected3(v);
      if (onChange) {
        const row1 = level1Options.find((r) => r.code_value === selected1);
        const row2 = level2Options.find((r) => r.code_value === selected2);
        const row3 = level3Options.find((r) => r.code_value === v);
        const path = [row1, row2, row3].filter(Boolean) as CodeDetail[];
        onChange(v, row3, path);
      }
    },
    [onChange, level1Options, level2Options, level3Options, selected1, selected2],
  );

  const containerClass = inline ? "flex flex-wrap gap-4 items-end" : "space-y-4";
  const selectItemClass = inline ? "flex-1 min-w-[150px] space-y-1" : "space-y-1";

  return (
    <div className={`${containerClass} ${className}`}>
      {/* 1단계 */}
      <div className={selectItemClass}>
        <Label className="text-xs font-medium">
          {labels[0]}
          {required && <span className="ml-1 text-destructive">*</span>}
        </Label>
        <Select value={selected1} onValueChange={handle1} disabled={disabled || loading}>
          <SelectTrigger className="h-9 text-sm">
            {loading ? (
              <div className="flex items-center gap-2">
                <Loader2 className="h-3 w-3 animate-spin" />
                <span className="text-muted-foreground">로딩 중...</span>
              </div>
            ) : (
              <SelectValue placeholder={placeholders[0]} />
            )}
          </SelectTrigger>
          <SelectContent>
            {level1Options.map((row) => (
              <SelectItem key={String(row.code_detail_id)} value={row.code_value}>
                {row.code_name || row.code_value}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {maxDepth >= 2 && (
        <div className={selectItemClass}>
          <Label className="text-xs font-medium">{labels[1] || "2단계"}</Label>
          <Select
            value={selected2}
            onValueChange={handle2}
            disabled={disabled || loading || !selected1}
          >
            <SelectTrigger className="h-9 text-sm">
              <SelectValue
                placeholder={
                  selected1 ? placeholders[1] || "선택하세요" : "1단계를 먼저 선택하세요"
                }
              />
            </SelectTrigger>
            <SelectContent>
              {level2Options.length === 0 && selected1 ? (
                <div className="px-2 py-1.5 text-sm text-muted-foreground">
                  하위 항목이 없습니다
                </div>
              ) : (
                level2Options.map((row) => (
                  <SelectItem key={String(row.code_detail_id)} value={row.code_value}>
                    {row.code_name || row.code_value}
                  </SelectItem>
                ))
              )}
            </SelectContent>
          </Select>
        </div>
      )}

      {maxDepth >= 3 && (
        <div className={selectItemClass}>
          <Label className="text-xs font-medium">{labels[2] || "3단계"}</Label>
          <Select
            value={selected3}
            onValueChange={handle3}
            disabled={disabled || loading || !selected2}
          >
            <SelectTrigger className="h-9 text-sm">
              <SelectValue
                placeholder={
                  selected2 ? placeholders[2] || "선택하세요" : "2단계를 먼저 선택하세요"
                }
              />
            </SelectTrigger>
            <SelectContent>
              {level3Options.length === 0 && selected2 ? (
                <div className="px-2 py-1.5 text-sm text-muted-foreground">
                  하위 항목이 없습니다
                </div>
              ) : (
                level3Options.map((row) => (
                  <SelectItem key={String(row.code_detail_id)} value={row.code_value}>
                    {row.code_name || row.code_value}
                  </SelectItem>
                ))
              )}
            </SelectContent>
          </Select>
        </div>
      )}
    </div>
  );
}

export default HierarchicalCodeSelect;
