"use client";

import React, { useMemo } from "react";
import { MoreHorizontal, Database, Layers, FileStack } 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 } 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;

  return (
    <div className="flex flex-1 flex-col overflow-hidden">
      <div
        className="grid flex-shrink-0 items-center border-b bg-muted/50 px-4 py-2 text-xs font-semibold text-foreground"
        style={{ gridTemplateColumns: "4px 140px 1fr 100px 160px 40px" }}
      >
        <span />
        <span>라벨 · 컬럼명</span>
        <span>참조/설정</span>
        <span>타입</span>
        <span className="text-center">PK / NN / IDX / UQ</span>
        <span />
      </div>

      <div className="flex-1 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="space-y-1 py-2">
                <div className="flex items-center gap-2 border-b border-border/60 px-4 pb-1.5">
                  <Icon className="h-4 w-4 text-muted-foreground" />
                  <span className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                    {label}
                  </span>
                  <Badge variant="secondary" className="text-xs">
                    {list.length}
                  </Badge>
                </div>
                {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;

                  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(
                        "grid min-h-12 cursor-pointer items-center gap-2 rounded-md border px-4 py-2 transition-colors",
                        "grid-cols-[4px_140px_1fr_100px_160px_40px]",
                        "bg-card border-transparent hover:border-border hover:shadow-sm",
                        isSelected && "border-primary/30 bg-primary/5 shadow-sm",
                      )}
                    >
                      {/* 4px 색상바 (타입별 진한 색) */}
                      <div className={cn("h-full min-h-8 w-1 rounded-full", typeConf.barColor)} />

                      {/* 라벨 + 컬럼명 (한글라벨 (영어명) 동시 표시) */}
                      <div className="min-w-0">
                        <div className="truncate text-sm font-medium">
                          {column.displayName && column.displayName !== column.columnName
                            ? `${column.displayName} (${column.columnName})`
                            : column.columnName}
                        </div>
                      </div>

                      {/* 참조/설정 칩 */}
                      <div className="flex min-w-0 flex-wrap gap-1">
                        {column.inputType === "entity" && column.referenceTable && column.referenceTable !== "none" && (
                          <>
                            <Badge
                              variant="outline"
                              className="text-xs 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-xs">→</span>
                            <Badge
                              variant="outline"
                              className="text-xs 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="text-muted-foreground truncate text-xs">
                            {column.codeCategory ?? "—"} · {column.defaultValue ?? ""}
                          </span>
                        )}
                        {column.inputType === "numbering" && column.numberingRuleId && (
                          <Badge variant="outline" className="text-xs font-normal">
                            {column.numberingRuleId}
                          </Badge>
                        )}
                        {column.inputType !== "entity" &&
                          column.inputType !== "code" &&
                          column.inputType !== "numbering" &&
                          (column.defaultValue ? (
                            <span className="text-muted-foreground truncate text-xs">{column.defaultValue}</span>
                          ) : (
                            <span className="text-muted-foreground/60 text-xs">—</span>
                          ))}
                      </div>

                      {/* 타입 뱃지 */}
                      <div className={cn("rounded-md border px-2 py-0.5 text-xs", typeConf.bgColor, typeConf.color)}>
                        <span className="mr-1 inline-block h-1.5 w-1.5 rounded-full bg-current opacity-70" />
                        {typeConf.label}
                      </div>

                      {/* PK / NN / IDX / UQ (클릭 토글) */}
                      <div className="flex flex-wrap items-center justify-center gap-1">
                        <button
                          type="button"
                          className={cn(
                            "rounded border px-1.5 py-0.5 text-[10px] font-bold transition-colors",
                            idxState.isPk
                              ? "border-blue-200 bg-blue-50 text-blue-600"
                              : "border-border text-muted-foreground/40 hover:border-blue-200 hover:text-blue-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            onPkToggle?.(column.columnName, !idxState.isPk);
                          }}
                          title="Primary Key 토글"
                        >
                          PK
                        </button>
                        <button
                          type="button"
                          className={cn(
                            "rounded border px-1.5 py-0.5 text-[10px] font-bold transition-colors",
                            column.isNullable === "NO"
                              ? "border-amber-200 bg-amber-50 text-amber-600"
                              : "border-border text-muted-foreground/40 hover:border-amber-200 hover:text-amber-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            onColumnChange(column.columnName, "isNullable", column.isNullable === "NO" ? "YES" : "NO");
                          }}
                          title="Not Null 토글"
                        >
                          NN
                        </button>
                        <button
                          type="button"
                          className={cn(
                            "rounded border px-1.5 py-0.5 text-[10px] font-bold transition-colors",
                            idxState.hasIndex
                              ? "border-emerald-200 bg-emerald-50 text-emerald-600"
                              : "border-border text-muted-foreground/40 hover:border-emerald-200 hover:text-emerald-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            onIndexToggle?.(column.columnName, !idxState.hasIndex);
                          }}
                          title="Index 토글"
                        >
                          IDX
                        </button>
                        <button
                          type="button"
                          className={cn(
                            "rounded border px-1.5 py-0.5 text-[10px] font-bold transition-colors",
                            column.isUnique === "YES"
                              ? "border-violet-200 bg-violet-50 text-violet-600"
                              : "border-border text-muted-foreground/40 hover:border-violet-200 hover:text-violet-400",
                          )}
                          onClick={(e) => {
                            e.stopPropagation();
                            onColumnChange(column.columnName, "isUnique", column.isUnique === "YES" ? "NO" : "YES");
                          }}
                          title="Unique 토글"
                        >
                          UQ
                        </button>
                      </div>

                      <div className="flex items-center justify-center">
                        <Button
                          type="button"
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={(e) => {
                            e.stopPropagation();
                            onSelectColumn(column.columnName);
                          }}
                          aria-label="상세 설정"
                        >
                          <MoreHorizontal className="h-4 w-4" />
                        </Button>
                      </div>
                    </div>
                  );
                })}
              </div>
            );
          })
        )}
      </div>
    </div>
  );
}
