"use client";

import React, { useMemo } from "react";
import { MoreHorizontal, Database, Layers, FileStack, Lock } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import type { ColumnTypeInfo, TableInfo } from "./types";
import { INPUT_TYPE_COLORS, getColumnGroup, isSystemColumn } from "./types";
import type { ReferenceTableColumn } from "@/lib/api/entityJoin";

export interface ColumnGridConstraints {
  primaryKey: { columns: string[] };
  indexes: Array<{ columns: string[]; isUnique: boolean }>;
}

export interface ColumnGridProps {
  columns: ColumnTypeInfo[];
  selectedColumn: string | null;
  onSelectColumn: (columnName: string) => void;
  onColumnChange: (columnName: string, field: keyof ColumnTypeInfo, value: unknown) => void;
  constraints: ColumnGridConstraints;
  typeFilter?: string | null;
  getColumnIndexState?: (columnName: string) => { isPk: boolean; hasIndex: boolean };
  onPkToggle?: (columnName: string, checked: boolean) => void;
  onIndexToggle?: (columnName: string, checked: boolean) => void;
  /** 호버 시 한글 라벨 표시용 (Badge title) */
  tables?: TableInfo[];
  referenceTableColumns?: Record<string, ReferenceTableColumn[]>;
}

function getIndexState(
  columnName: string,
  constraints: ColumnGridConstraints,
): { isPk: boolean; hasIndex: boolean } {
  const isPk = constraints.primaryKey.columns.includes(columnName);
  const hasIndex = constraints.indexes.some(
    (idx) => !idx.isUnique && idx.columns.length === 1 && idx.columns[0] === columnName,
  );
  return { isPk, hasIndex };
}

/** 그룹 헤더 라벨 */
const GROUP_LABELS: Record<string, { icon: React.ElementType; label: string }> = {
  basic: { icon: FileStack, label: "기본 정보" },
  reference: { icon: Layers, label: "참조 정보" },
  meta: { icon: Database, label: "메타 정보" },
};

export function ColumnGrid({
  columns,
  selectedColumn,
  onSelectColumn,
  onColumnChange,
  constraints,
  typeFilter = null,
  getColumnIndexState: externalGetIndexState,
  onPkToggle,
  onIndexToggle,
  tables,
  referenceTableColumns,
}: ColumnGridProps) {
  const getIdxState = useMemo(
    () => externalGetIndexState ?? ((name: string) => getIndexState(name, constraints)),
    [constraints, externalGetIndexState],
  );

  /** typeFilter 적용 후 그룹별로 정렬 */
  const filteredAndGrouped = useMemo(() => {
    const filtered =
      typeFilter != null ? columns.filter((c) => (c.inputType || "text") === typeFilter) : columns;
    const groups = { basic: [] as ColumnTypeInfo[], reference: [] as ColumnTypeInfo[], meta: [] as ColumnTypeInfo[] };
    for (const col of filtered) {
      const group = getColumnGroup(col);
      groups[group].push(col);
    }
    return groups;
  }, [columns, typeFilter]);

  const totalFiltered =
    filteredAndGrouped.basic.length + filteredAndGrouped.reference.length + filteredAndGrouped.meta.length;

  const GRID_TEMPLATE = "3px minmax(180px,1fr) minmax(160px,1.4fr) 90px 124px 28px";

  return (
    <div className="flex flex-1 min-h-0 flex-col overflow-hidden">
      {/* 컬럼 헤더 — 컴팩트 */}
      <div
        className="grid flex-shrink-0 items-center gap-2 border-b bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground"
        style={{ gridTemplateColumns: GRID_TEMPLATE }}
      >
        <span />
        <span>라벨 · 컬럼명</span>
        <span>참조 / 기본값</span>
        <span>타입</span>
        <span className="text-center">PK · NN · IDX · UQ</span>
        <span />
      </div>

      <div className="flex-1 min-h-0 overflow-y-auto">
        {totalFiltered === 0 ? (
          <div className="flex items-center justify-center py-12 text-sm text-muted-foreground">
            {typeFilter ? "해당 타입의 컬럼이 없습니다." : "컬럼이 없습니다."}
          </div>
        ) : (
          (["basic", "reference", "meta"] as const).map((groupKey) => {
            const list = filteredAndGrouped[groupKey];
            if (list.length === 0) return null;
            const { icon: Icon, label } = GROUP_LABELS[groupKey];
            return (
              <div key={groupKey} className="py-1">
                {/* 그룹 헤더 — 한 줄 컴팩트 */}
                <div className="sticky top-0 z-10 flex items-center gap-1.5 border-b border-border/50 bg-background/95 px-3 py-1 backdrop-blur">
                  <Icon className="h-3 w-3 text-muted-foreground" />
                  <span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                    {label}
                  </span>
                  <Badge variant="secondary" className="h-4 px-1 text-[10px]">
                    {list.length}
                  </Badge>
                </div>
                <div className="divide-y divide-border/40">
                {list.map((column) => {
                  const typeConf = INPUT_TYPE_COLORS[column.inputType || "text"] || INPUT_TYPE_COLORS.text;
                  const idxState = getIdxState(column.columnName);
                  const isSelected = selectedColumn === column.columnName;
                  const isLocked = isSystemColumn(column.columnName);

                  return (
                    <div
                      key={column.columnName}
                      role="button"
                      tabIndex={0}
                      onClick={() => onSelectColumn(column.columnName)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter" || e.key === " ") {
                          e.preventDefault();
                          onSelectColumn(column.columnName);
                        }
                      }}
                      className={cn(
                        "group grid h-9 cursor-pointer items-center gap-2 px-3 transition-colors",
                        "hover:bg-muted/40",
                        isSelected && "bg-primary/5 ring-1 ring-inset ring-primary/30",
                        isLocked && "bg-muted/20",
                      )}
                      style={{ gridTemplateColumns: GRID_TEMPLATE }}
                    >
                      {/* 3px 색상바 (타입별 진한 색) */}
                      <div className={cn("h-5 w-[3px] rounded-full", typeConf.barColor)} />

                      {/* 라벨 + 컬럼명 — 시스템 컬럼이면 자물쇠 아이콘 표시 */}
                      <div className="flex min-w-0 items-baseline gap-1.5">
                        {isLocked && (
                          <Lock
                            className="h-2.5 w-2.5 flex-shrink-0 self-center text-muted-foreground/70"
                            aria-label="시스템 자동 생성 컬럼"
                          />
                        )}
                        {column.displayName && column.displayName !== column.columnName ? (
                          <>
                            <span className={cn("truncate text-[12px] font-medium leading-tight", isLocked && "text-muted-foreground")}>
                              {column.displayName}
                            </span>
                            <span className="truncate font-mono text-[10px] text-muted-foreground leading-tight">
                              {column.columnName}
                            </span>
                          </>
                        ) : (
                          <span className={cn("truncate font-mono text-[12px] font-medium leading-tight", isLocked && "text-muted-foreground")}>
                            {column.columnName}
                          </span>
                        )}
                      </div>

                      {/* 참조/설정 칩 — 한 줄 nowrap, 넘치면 잘림 */}
                      <div className="flex min-w-0 items-center gap-1 overflow-hidden text-[11px]">
                        {column.inputType === "entity" && column.referenceTable && column.referenceTable !== "none" ? (
                          <>
                            <Badge
                              variant="outline"
                              className="h-4 truncate px-1 text-[10px] font-normal"
                              title={
                                tables
                                  ? (() => {
                                      const t = tables.find((tb) => tb.tableName === column.referenceTable);
                                      return t?.displayName && t.displayName !== t.tableName
                                        ? `${t.displayName} (${column.referenceTable})`
                                        : column.referenceTable;
                                    })()
                                  : column.referenceTable
                              }
                            >
                              {column.referenceTable}
                            </Badge>
                            <span className="text-muted-foreground text-[10px]">→</span>
                            <Badge
                              variant="outline"
                              className="h-4 truncate px-1 text-[10px] font-normal"
                              title={
                                referenceTableColumns?.[column.referenceTable]
                                  ? (() => {
                                      const refCols = referenceTableColumns[column.referenceTable];
                                      const c = refCols.find((rc) => rc.columnName === (column.referenceColumn ?? ""));
                                      return c?.displayName && c.displayName !== c.columnName
                                        ? `${c.displayName} (${column.referenceColumn})`
                                        : column.referenceColumn ?? "—";
                                    })()
                                  : column.referenceColumn ?? "—"
                              }
                            >
                              {column.referenceColumn || "—"}
                            </Badge>
                          </>
                        ) : column.inputType === "code" ? (
                          <span className="truncate text-muted-foreground">
                            {column.codeCategory ?? "—"}{column.defaultValue ? ` · ${column.defaultValue}` : ""}
                          </span>
                        ) : column.inputType === "numbering" && column.numberingRuleId ? (
                          <Badge variant="outline" className="h-4 truncate px-1 text-[10px] font-normal">
                            {column.numberingRuleId}
                          </Badge>
                        ) : column.defaultValue ? (
                          <span className="truncate text-muted-foreground">{column.defaultValue}</span>
                        ) : (
                          <span className="text-muted-foreground/40">—</span>
                        )}
                      </div>

                      {/* 타입 뱃지 — 컴팩트 */}
                      <div className={cn("inline-flex h-5 items-center gap-1 self-center justify-self-start rounded border px-1.5 text-[10px]", typeConf.bgColor, typeConf.color)}>
                        <span className="inline-block h-1 w-1 rounded-full bg-current opacity-70" />
                        {typeConf.label}
                      </div>

                      {/* PK / NN / IDX / UQ (클릭 토글) — 시스템 컬럼은 잠금(읽기 전용) */}
                      <div className="flex flex-nowrap items-center justify-center gap-0.5">
                        <button
                          type="button"
                          disabled={isLocked}
                          className={cn(
                            "h-5 w-7 rounded border text-[9px] font-bold transition-colors disabled:cursor-not-allowed disabled:opacity-60",
                            idxState.isPk
                              ? "border-blue-200 bg-blue-50 text-blue-600"
                              : "border-border/50 text-muted-foreground/40 hover:border-blue-200 hover:text-blue-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            if (isLocked) return;
                            onPkToggle?.(column.columnName, !idxState.isPk);
                          }}
                          title={isLocked ? "시스템 컬럼 — 수정 불가" : "Primary Key 토글"}
                        >
                          PK
                        </button>
                        <button
                          type="button"
                          disabled={isLocked}
                          className={cn(
                            "h-5 w-7 rounded border text-[9px] font-bold transition-colors disabled:cursor-not-allowed disabled:opacity-60",
                            column.isNullable === "NO"
                              ? "border-amber-200 bg-amber-50 text-amber-600"
                              : "border-border/50 text-muted-foreground/40 hover:border-amber-200 hover:text-amber-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            if (isLocked) return;
                            onColumnChange(column.columnName, "isNullable", column.isNullable === "NO" ? "YES" : "NO");
                          }}
                          title={isLocked ? "시스템 컬럼 — 수정 불가" : "Not Null 토글"}
                        >
                          NN
                        </button>
                        <button
                          type="button"
                          disabled={isLocked}
                          className={cn(
                            "h-5 w-7 rounded border text-[9px] font-bold transition-colors disabled:cursor-not-allowed disabled:opacity-60",
                            idxState.hasIndex
                              ? "border-emerald-200 bg-emerald-50 text-emerald-600"
                              : "border-border/50 text-muted-foreground/40 hover:border-emerald-200 hover:text-emerald-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            if (isLocked) return;
                            onIndexToggle?.(column.columnName, !idxState.hasIndex);
                          }}
                          title={isLocked ? "시스템 컬럼 — 수정 불가" : "Index 토글"}
                        >
                          IDX
                        </button>
                        <button
                          type="button"
                          disabled={isLocked}
                          className={cn(
                            "h-5 w-7 rounded border text-[9px] font-bold transition-colors disabled:cursor-not-allowed disabled:opacity-60",
                            column.isUnique === "YES"
                              ? "border-violet-200 bg-violet-50 text-violet-600"
                              : "border-border/50 text-muted-foreground/40 hover:border-violet-200 hover:text-violet-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            if (isLocked) return;
                            onColumnChange(column.columnName, "isUnique", column.isUnique === "YES" ? "NO" : "YES");
                          }}
                          title={isLocked ? "시스템 컬럼 — 수정 불가" : "Unique 토글"}
                        >
                          UQ
                        </button>
                      </div>

                      <div className="flex items-center justify-center">
                        <Button
                          type="button"
                          variant="ghost"
                          size="icon"
                          className="h-6 w-6 opacity-0 transition-opacity group-hover:opacity-100"
                          onClick={(e) => {
                            e.stopPropagation();
                            onSelectColumn(column.columnName);
                          }}
                          aria-label="상세 설정"
                        >
                          <MoreHorizontal className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    </div>
                  );
                })}
                </div>
              </div>
            );
          })
        )}
      </div>
    </div>
  );
}
