"use client";

import React, { useMemo } from "react";
import { X, Settings2, MessageSquareText, Lock, AlertTriangle, CheckCircle2 } from "lucide-react";
import { checkRuleDependencies } from "@/lib/utils/numberingRuleDeps";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import type { ColumnTypeInfo, TableInfo, SecondLevelMenu } from "./types";
import { INPUT_TYPE_COLORS, INPUT_TYPE_GROUPS, isSystemColumn } from "./types";
import type { ReferenceTableColumn } from "@/lib/api/entityJoin";

export interface ColumnDetailPanelProps {
  column: ColumnTypeInfo | null;
  tables: TableInfo[];
  referenceTableColumns: Record<string, ReferenceTableColumn[]>;
  secondLevelMenus: SecondLevelMenu[];
  numberingRules: any[];
  /** 지금 편집 중인 테이블의 컬럼 목록 — 채번 룰 의존성 검증에 사용 */
  currentTableName?: string;
  currentTableColumns?: Array<{ columnName: string }>;
  /** 누락 컬럼 자동 추가 콜백 — 테이블 타입 관리 페이지에서 컬럼 일괄 INSERT */
  onAddMissingColumns?: (columnNames: string[]) => void;
  onColumnChange: (field: keyof ColumnTypeInfo, value: unknown) => void;
  onClose: () => void;
  onLoadReferenceColumns?: (tableName: string) => void;
  /** 코드 카테고리 옵션 (value, label) */
  codeCategoryOptions?: Array<{ value: string; label: string }>;
  /** 참조 테이블 옵션 (value, label) */
  referenceTableOptions?: Array<{ value: string; label: string }>;
}

export function ColumnDetailPanel({
  column,
  tables,
  referenceTableColumns,
  numberingRules,
  currentTableName,
  currentTableColumns = [],
  onAddMissingColumns,
  onColumnChange,
  onClose,
  onLoadReferenceColumns,
  codeCategoryOptions = [],
  referenceTableOptions = [],
}: ColumnDetailPanelProps) {
  const [entityTableOpen, setEntityTableOpen] = React.useState(false);
  const [entityColumnOpen, setEntityColumnOpen] = React.useState(false);

  const typeConf = column ? INPUT_TYPE_COLORS[column.inputType || "text"] : null;
  const refColumns = column?.referenceTable
    ? referenceTableColumns[column.referenceTable] ?? []
    : [];

  React.useEffect(() => {
    if (column?.referenceTable && column.referenceTable !== "none") {
      onLoadReferenceColumns?.(column.referenceTable);
    }
  }, [column?.referenceTable, onLoadReferenceColumns]);

  if (!column) return null;

  // 시스템 자동 생성 컬럼은 타입/표시이름 등 일체 편집 불가
  const isSystem = isSystemColumn(column.columnName);

  const refTableOpts = useMemo(() => {
    const hasKorean = (s: string) => /[가-힣]/.test(s);
    const raw = referenceTableOptions.length
      ? [...referenceTableOptions]
      : [
          { value: "none", label: "없음" },
          ...tables.map((t) => ({
            value: t.tableName,
            label:
              t.displayName && t.displayName !== t.tableName
                ? `${t.displayName} (${t.tableName})`
                : t.tableName,
          })),
        ];

    const noneOpt = raw.find((o) => o.value === "none");
    const rest = raw.filter((o) => o.value !== "none");

    rest.sort((a, b) => {
      const aK = hasKorean(a.label);
      const bK = hasKorean(b.label);
      if (aK && !bK) return -1;
      if (!aK && bK) return 1;
      return a.label.localeCompare(b.label, "ko");
    });

    return noneOpt ? [noneOpt, ...rest] : rest;
  }, [referenceTableOptions, tables]);

  return (
    <div className="flex h-full w-full flex-col border-l bg-card">
      {/* 헤더 */}
      <div className="flex flex-shrink-0 items-center justify-between border-b px-4 py-3">
        <div className="flex min-w-0 items-center gap-2">
          {typeConf && (
            <span className={cn("rounded px-2 py-0.5 text-xs", typeConf.bgColor, typeConf.color)}>
              {typeConf.label}
            </span>
          )}
          <span className="truncate font-mono text-sm font-medium">{column.columnName}</span>
        </div>
        <Button type="button" variant="ghost" size="icon" className="h-8 w-8 shrink-0" onClick={onClose} aria-label="닫기">
          <X className="h-4 w-4" />
        </Button>
      </div>

      <div className="flex-1 space-y-4 overflow-y-auto p-4">
        {/* 시스템 자동 생성 컬럼 안내 */}
        {isSystem && (
          <div className="flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 dark:border-amber-900/40 dark:bg-amber-950/20">
            <Lock className="mt-0.5 h-3.5 w-3.5 flex-shrink-0 text-amber-600 dark:text-amber-400" />
            <div className="text-[11px] leading-relaxed text-amber-700 dark:text-amber-300">
              <p className="font-semibold">시스템 자동 생성 컬럼</p>
              <p className="text-[10px] text-amber-600/80 dark:text-amber-400/70">
                테이블 생성 시 자동 부여되며 타입/속성을 수정할 수 없습니다.
              </p>
            </div>
          </div>
        )}

        {/* [섹션 1] 데이터 타입 선택 — 셀렉트 박스 */}
        <section className="space-y-2">
          <div>
            <p className="text-sm font-semibold">이 필드는 어떤 유형인가요?</p>
            <p className="text-xs text-muted-foreground">
              저장 타입 단위. UI 변형(text/textarea 등)은 화면관리에서 선택합니다.
            </p>
          </div>
          <Select
            value={column.inputType || "text"}
            onValueChange={(v) => onColumnChange("inputType", v)}
            disabled={isSystem}
          >
            <SelectTrigger className="h-9 text-sm">
              <SelectValue placeholder="타입 선택" />
            </SelectTrigger>
            <SelectContent>
              {INPUT_TYPE_GROUPS.map((group, gi) => (
                <SelectGroup key={group.groupLabel}>
                  <SelectLabel className="text-[10px] uppercase tracking-wider text-muted-foreground">
                    {group.groupLabel}
                  </SelectLabel>
                  {group.types.map((type) => {
                    const conf = INPUT_TYPE_COLORS[type];
                    if (!conf) return null;
                    return (
                      <SelectItem key={type} value={type} className="text-sm">
                        <span className="flex items-center gap-2">
                          <span
                            className={cn(
                              "inline-flex h-4 w-4 items-center justify-center rounded text-[10px] font-bold",
                              conf.bgColor,
                              conf.color,
                            )}
                          >
                            {conf.iconChar}
                          </span>
                          <span>{conf.label}</span>
                          <span className="text-[10px] text-muted-foreground">· {conf.desc}</span>
                        </span>
                      </SelectItem>
                    );
                  })}
                </SelectGroup>
              ))}
            </SelectContent>
          </Select>
        </section>

        {/* [섹션 2] 타입별 상세 설정 — 시스템 컬럼은 표시하지 않음 */}
        {!isSystem && column.inputType === "entity" && (
          <section className="space-y-3">
            <div className="flex items-center gap-2">
              <Settings2 className="h-4 w-4 text-muted-foreground" />
              <Label className="text-sm font-medium">엔티티 참조</Label>
            </div>

            {/* 참조 테이블 */}
            <div className="space-y-1">
              <Label className="text-[11px] font-medium text-muted-foreground">참조 테이블</Label>
              <Popover open={entityTableOpen} onOpenChange={setEntityTableOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    className="h-9 w-full justify-between text-xs"
                  >
                    {column.referenceTable && column.referenceTable !== "none"
                      ? refTableOpts.find((o) => o.value === column.referenceTable)?.label ?? column.referenceTable
                      : "테이블 선택..."}
                    <ChevronsUpDown className="ml-2 h-3 w-3 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[280px] p-0" align="start">
                  <Command>
                    <CommandInput placeholder="테이블 검색..." className="h-8 text-xs" />
                    <CommandList className="max-h-[200px]">
                      <CommandEmpty className="py-2 text-center text-xs">테이블을 찾을 수 없습니다.</CommandEmpty>
                      <CommandGroup>
                        {refTableOpts.map((opt) => {
                          const hasKorean = opt.value !== "none" && opt.label !== opt.value && !opt.label.startsWith(opt.value);
                          return (
                            <CommandItem
                              key={opt.value}
                              value={`${opt.label} ${opt.value}`}
                              onSelect={() => {
                                onColumnChange("referenceTable", opt.value === "none" ? undefined : opt.value);
                                if (opt.value !== "none") onLoadReferenceColumns?.(opt.value);
                                setEntityTableOpen(false);
                              }}
                              className="text-xs"
                            >
                              <Check
                                className={cn("mr-2 h-3 w-3", column.referenceTable === opt.value ? "opacity-100" : "opacity-0")}
                              />
                              {hasKorean ? (
                                <div className="flex flex-col">
                                  <span className="font-medium">{opt.label.replace(` (${opt.value})`, "")}</span>
                                  <span className="text-[10px] text-muted-foreground">{opt.value}</span>
                                </div>
                              ) : (
                                opt.label
                              )}
                            </CommandItem>
                          );
                        })}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>

            {/* 조인 컬럼 */}
            {column.referenceTable && column.referenceTable !== "none" && (
              <div className="space-y-1">
                <Label className="text-[11px] font-medium text-muted-foreground">조인 컬럼(값)</Label>
                <Popover open={entityColumnOpen} onOpenChange={setEntityColumnOpen}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      disabled={refColumns.length === 0}
                      className="h-9 w-full justify-between text-xs"
                    >
                      {column.referenceColumn && column.referenceColumn !== "none"
                        ? (() => {
                            const matched = refColumns.find((c) => c.columnName === column.referenceColumn);
                            return matched?.displayName && matched.displayName !== column.referenceColumn
                              ? `${matched.displayName} (${column.referenceColumn})`
                              : column.referenceColumn;
                          })()
                        : "컬럼 선택..."}
                      <ChevronsUpDown className="ml-2 h-3 w-3 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[280px] p-0" align="start">
                    <Command>
                      <CommandInput placeholder="컬럼 검색..." className="h-8 text-xs" />
                      <CommandList className="max-h-[200px]">
                        <CommandEmpty className="py-2 text-center text-xs">컬럼을 찾을 수 없습니다.</CommandEmpty>
                        <CommandGroup>
                          <CommandItem
                            value="none"
                            onSelect={() => {
                              onColumnChange("referenceColumn", undefined);
                              setEntityColumnOpen(false);
                            }}
                            className="text-xs"
                          >
                            <Check className={cn("mr-2 h-3 w-3", !column.referenceColumn ? "opacity-100" : "opacity-0")} />
                            선택 안함
                          </CommandItem>
                          {refColumns.map((refCol) => (
                            <CommandItem
                              key={refCol.columnName}
                              value={`${refCol.displayName ?? ""} ${refCol.columnName}`}
                              onSelect={() => {
                                onColumnChange("referenceColumn", refCol.columnName);
                                setEntityColumnOpen(false);
                              }}
                              className="text-xs"
                            >
                              <Check
                                className={cn(
                                  "mr-2 h-3 w-3",
                                  column.referenceColumn === refCol.columnName ? "opacity-100" : "opacity-0",
                                )}
                              />
                              {refCol.displayName && refCol.displayName !== refCol.columnName ? (
                                <div className="flex flex-col">
                                  <span className="font-medium">{refCol.displayName}</span>
                                  <span className="text-[10px] text-muted-foreground">{refCol.columnName}</span>
                                </div>
                              ) : (
                                <span>{refCol.columnName}</span>
                              )}
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>
            )}

            {/* 참조 요약 미니맵 */}
            {column.referenceTable && column.referenceTable !== "none" && column.referenceColumn && (
              <div className="flex items-center gap-2 rounded-md bg-violet-50 px-3 py-2">
                <span className="text-[11px] font-semibold text-violet-600">
                  {(() => {
                    const tbl = refTableOpts.find((o) => o.value === column.referenceTable);
                    return tbl?.label ?? column.referenceTable;
                  })()}
                </span>
                <span className="text-muted-foreground text-[10px]">→</span>
                <span className="text-[11px] font-semibold text-violet-600">
                  {(() => {
                    const col = refColumns.find((c) => c.columnName === column.referenceColumn);
                    return col?.displayName && col.displayName !== column.referenceColumn
                      ? `${col.displayName} (${column.referenceColumn})`
                      : column.referenceColumn;
                  })()}
                </span>
              </div>
            )}
          </section>
        )}

        {!isSystem && column.inputType === "code" && (
          <section className="space-y-2">
            <div className="flex items-center gap-2">
              <Settings2 className="h-4 w-4 text-muted-foreground" />
              <Label className="text-sm font-medium">코드 설정</Label>
            </div>
            <div className="space-y-2">
              <div className="space-y-1.5">
                <Label className="text-xs text-muted-foreground">공통코드 카테고리</Label>
                <Select
                  value={column.codeCategory ?? "none"}
                  onValueChange={(v) => onColumnChange("codeCategory", v === "none" ? undefined : v)}
                >
                  <SelectTrigger className="h-9 text-xs">
                    <SelectValue placeholder="코드 선택" />
                  </SelectTrigger>
                  <SelectContent>
                    {/* "none" 옵션을 항상 첫번째에 두되, codeCategoryOptions 가 이미 "none" 을 포함하면
                        그 라벨을 사용 (key 중복 방지). */}
                    {(() => {
                      const existingNone = codeCategoryOptions.find((o) => o.value === "none");
                      const rest = codeCategoryOptions.filter((o) => o.value !== "none");
                      const noneOpt = existingNone ?? { value: "none", label: "선택 안함" };
                      return [noneOpt, ...rest].map((opt) => (
                        <SelectItem key={opt.value} value={opt.value}>
                          {opt.label}
                        </SelectItem>
                      ));
                    })()}
                  </SelectContent>
                </Select>
              </div>
              {column.codeCategory && column.codeCategory !== "none" && (
                <div className="space-y-1.5">
                  <Label className="text-xs text-muted-foreground">계층 역할</Label>
                  <Select
                    value={column.hierarchyRole ?? "none"}
                    onValueChange={(v) =>
                      onColumnChange("hierarchyRole", v === "none" ? undefined : (v as "large" | "medium" | "small"))
                    }
                  >
                    <SelectTrigger className="h-9 text-xs">
                      <SelectValue placeholder="일반" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="none">일반</SelectItem>
                      <SelectItem value="large">대분류</SelectItem>
                      <SelectItem value="medium">중분류</SelectItem>
                      <SelectItem value="small">소분류</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              )}
            </div>
          </section>
        )}

        {/* 카테고리 타입은 코드와 동작이 동일해 별도 입력 폼을 두지 않음.
            기존 데이터(inputType='category')는 그대로 보존되며, 코드 카테고리 픽커는 코드 타입을 통해 제공. */}

        {!isSystem && column.inputType === "numbering" && (() => {
          // 선택된 룰
          const selectedRule = (numberingRules ?? []).find((r: any) => r.ruleId === column.numberingRuleId) ?? null;
          // 의존성 분석 — 룰이 요구하는 폼 키 vs 현재 테이블 컬럼
          const depCheck = checkRuleDependencies(
            selectedRule,
            currentTableName ?? "",
            currentTableColumns,
          );
          return (
            <section className="space-y-2">
              <div className="flex items-center gap-2">
                <Settings2 className="h-4 w-4 text-muted-foreground" />
                <Label className="text-sm font-medium">채번 규칙</Label>
              </div>
              <div className="space-y-1.5">
                <Label className="text-xs text-muted-foreground">사용할 룰</Label>
                <Select
                  value={column.numberingRuleId ?? "none"}
                  onValueChange={(v) => onColumnChange("numberingRuleId", v === "none" ? undefined : v)}
                >
                  <SelectTrigger className="h-9 text-xs">
                    <SelectValue placeholder="룰 선택" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">선택 안함</SelectItem>
                    {(numberingRules ?? []).map((r: any) => (
                      <SelectItem key={r.ruleId} value={r.ruleId}>
                        <span className="truncate font-medium">{r.ruleName ?? r.ruleId}</span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <p className="text-[10px] leading-snug text-muted-foreground">
                  룰이 없거나 새 룰이 필요하면 <span className="font-medium">시스템 관리 → 시퀀스 관리</span> 에서 등록.
                </p>
              </div>

              {/* 의존성 검증 결과 — 룰을 골랐고 요구 컬럼이 1개 이상일 때만 노출 */}
              {selectedRule && depCheck.required.length > 0 && (
                <div className={cn(
                  "rounded-md border px-3 py-2 text-[11px]",
                  depCheck.missing.length === 0
                    ? "border-emerald-200 bg-emerald-50 dark:border-emerald-900/40 dark:bg-emerald-950/20"
                    : "border-amber-300 bg-amber-50 dark:border-amber-900/40 dark:bg-amber-950/20",
                )}>
                  <div className="flex items-center gap-1.5">
                    {depCheck.missing.length === 0 ? (
                      <>
                        <CheckCircle2 className="h-3.5 w-3.5 text-emerald-600 dark:text-emerald-400" />
                        <span className="font-semibold text-emerald-700 dark:text-emerald-300">
                          이 룰을 사용할 준비 완료
                        </span>
                      </>
                    ) : (
                      <>
                        <AlertTriangle className="h-3.5 w-3.5 text-amber-600 dark:text-amber-400" />
                        <span className="font-semibold text-amber-700 dark:text-amber-300">
                          이 룰을 쓰려면 {depCheck.missing.length}개 컬럼이 더 필요해요
                        </span>
                      </>
                    )}
                  </div>

                  {/* 요구 컬럼 목록 */}
                  <div className="mt-1.5 space-y-0.5">
                    {depCheck.required.map((col) => {
                      const ok = depCheck.satisfied.includes(col);
                      return (
                        <div key={col} className="flex items-center gap-1.5 font-mono text-[10px]">
                          {ok ? (
                            <CheckCircle2 className="h-2.5 w-2.5 flex-shrink-0 text-emerald-600 dark:text-emerald-400" />
                          ) : (
                            <span className="inline-block h-2.5 w-2.5 flex-shrink-0 rounded-full border border-amber-400 bg-amber-100 dark:bg-amber-900/40" />
                          )}
                          <span className={cn(ok ? "text-emerald-700 dark:text-emerald-300" : "text-amber-700 dark:text-amber-300")}>
                            {col}
                          </span>
                          {!ok && <span className="text-[9px] text-amber-600/80 dark:text-amber-400/70">(누락)</span>}
                        </div>
                      );
                    })}
                  </div>

                  {/* 누락 자동 추가 버튼 */}
                  {depCheck.missing.length > 0 && onAddMissingColumns && (
                    <button
                      type="button"
                      onClick={() => onAddMissingColumns(depCheck.missing)}
                      className="mt-2 w-full rounded border border-amber-300 bg-white px-2 py-1 text-[10px] font-medium text-amber-700 transition-colors hover:bg-amber-100 dark:border-amber-700 dark:bg-amber-950/30 dark:text-amber-300 dark:hover:bg-amber-900/40"
                    >
                      누락된 {depCheck.missing.length}개 컬럼을 이 테이블에 추가
                    </button>
                  )}
                </div>
              )}
            </section>
          );
        })()}

        {/* [섹션 3] 코멘트 — PostgreSQL 컬럼 COMMENT 와 동기화.
            화면관리에서 이 값을 기본 라벨로 가져다 쓰고, 거기서 화면별로 재정의 가능. */}
        <section className="space-y-2">
          <div className="flex items-center gap-2">
            <MessageSquareText className="h-4 w-4 text-muted-foreground" />
            <Label className="text-sm font-medium">코멘트</Label>
          </div>
          <Textarea
            value={column.description ?? ""}
            onChange={(e) => onColumnChange("description", e.target.value)}
            placeholder="이 컬럼이 어떤 값인지 한 줄로 설명 (예: 거래처 세금유형 코드)"
            className="min-h-[72px] text-xs"
            rows={3}
            disabled={isSystem}
          />
          <p className="text-[10px] leading-snug text-muted-foreground">
            화면관리에서 이 값을 기본 라벨로 사용합니다. 화면별 라벨은 거기서 별도 수정 가능.
          </p>
        </section>
      </div>
    </div>
  );
}
