"use client";

/**
 * TableColumnPalette — 테이블 데이터 연결 탭의 컬럼 팔레트
 *
 * 2단계 플로우:
 * 1. 체크박스로 사용할 컬럼을 중복 선택
 * 2. 선택된 컬럼만 드래그 가능한 칩으로 표시 → 드롭 존에 배치
 */

import React, { useState, useMemo, useEffect } from "react";
import { useDrag } from "react-dnd";
import { Columns, Loader2, ChevronDown, ChevronUp, X } from "lucide-react";

export const TABLE_COLUMN_DND_TYPE = "table-column";

export interface SchemaColumn {
  column_name: string;
  data_type: string;
  is_nullable: string;
}

// ─── 드래그 가능한 선택된 컬럼 칩 ────────────────────────────────────────────

interface DraggableColumnProps {
  column: SchemaColumn;
  placed?: boolean;
  onRemove?: () => void;
}

function DraggableColumn({ column, placed = false, onRemove }: DraggableColumnProps) {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: TABLE_COLUMN_DND_TYPE,
    item: { columnName: column.column_name, dataType: column.data_type },
    canDrag: () => !placed,
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }), [column, placed]);

  return (
    <div
      ref={placed ? undefined : drag}
      className={`relative flex items-center gap-1.5 rounded-lg border px-3 py-2 transition-colors ${
        placed
          ? "cursor-default border-gray-200 bg-gray-100 opacity-50"
          : `cursor-move border-blue-200 bg-blue-50 hover:border-blue-400 hover:bg-blue-100 ${isDragging ? "opacity-50 shadow-lg" : ""}`
      }`}
    >
      <Columns className={`h-3.5 w-3.5 shrink-0 ${placed ? "text-gray-400" : "text-blue-500"}`} />
      <span className={`truncate font-mono text-xs font-medium ${placed ? "text-gray-400 line-through" : "text-blue-700"}`}>
        {column.column_name}
      </span>
      {placed ? (
        <span className="shrink-0 rounded bg-green-100 px-1 py-0.5 text-[9px] text-green-600">배치됨</span>
      ) : (
        <span className="shrink-0 rounded bg-blue-100 px-1 py-0.5 text-[9px] text-blue-500">
          {column.data_type}
        </span>
      )}
      {onRemove && (
        <button
          onClick={(e) => { e.stopPropagation(); onRemove(); }}
          className="absolute -right-1.5 -top-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-gray-400 text-white shadow-sm hover:bg-red-500"
        >
          <X className="h-2.5 w-2.5" />
        </button>
      )}
    </div>
  );
}

// ─── 메인 팔레트 ──────────────────────────────────────────────────────────────

interface TableColumnPaletteProps {
  columns: SchemaColumn[];
  loading?: boolean;
  maxSelectable?: number;
  placedColumns?: Set<string>;
  onColumnRemove?: (columnName: string) => void;
}

export function TableColumnPalette({ columns, loading, maxSelectable = 0, placedColumns, onColumnRemove }: TableColumnPaletteProps) {
  const [selectedNames, setSelectedNames] = useState<Set<string>>(new Set());
  const [listExpanded, setListExpanded] = useState(false);

  // 이미 배치된 컬럼을 선택 목록에 자동 포함
  useEffect(() => {
    if (!placedColumns || placedColumns.size === 0) return;
    setSelectedNames((prev) => {
      const next = new Set(prev);
      let changed = false;
      placedColumns.forEach((name) => {
        if (!next.has(name)) {
          next.add(name);
          changed = true;
        }
      });
      return changed ? next : prev;
    });
  }, [placedColumns]);

  const isLimitReached = maxSelectable > 0 && selectedNames.size >= maxSelectable;

  const selectedColumns = useMemo(
    () => columns.filter((c) => selectedNames.has(c.column_name)),
    [columns, selectedNames],
  );

  const toggleColumn = (name: string) => {
    setSelectedNames((prev) => {
      const next = new Set(prev);
      if (next.has(name)) {
        next.delete(name);
      } else {
        if (maxSelectable > 0 && next.size >= maxSelectable) return prev;
        next.add(name);
      }
      return next;
    });
  };

  return (
    <div className="space-y-3">
      {/* Step 1: 컬럼 선택 */}
      <div className="rounded-xl border border-border bg-white">
        <button
          onClick={() => setListExpanded(!listExpanded)}
          className="flex w-full items-center justify-between px-4 py-2.5"
        >
          <div className="flex items-center gap-2">
            <span className="text-sm font-bold text-gray-800">
              열 선택
            </span>
            <span className="text-xs font-normal text-muted-foreground">
              {selectedNames.size}{maxSelectable > 0 ? `/${maxSelectable}` : `/${columns.length}`} 선택됨
            </span>
            {maxSelectable > 0 && isLimitReached && (
              <span className="rounded bg-blue-100 px-1.5 py-0.5 text-[10px] font-medium text-blue-600">
                최대
              </span>
            )}
          </div>
          {listExpanded ? (
            <ChevronUp className="h-4 w-4 text-gray-400" />
          ) : (
            <ChevronDown className="h-4 w-4 text-gray-400" />
          )}
        </button>

        {listExpanded && (
          <div className="border-t border-gray-100">
            {loading ? (
              <div className="flex items-center justify-center py-6">
                <Loader2 className="h-4 w-4 animate-spin text-gray-400" />
                <span className="ml-2 text-xs text-gray-500">컬럼 로딩 중...</span>
              </div>
            ) : columns.length === 0 ? (
              <p className="py-4 text-center text-xs text-gray-400">
                레이아웃 탭에서 데이터 소스를 먼저 선택하세요.
              </p>
            ) : (
              <>
                {maxSelectable > 0 && (
                  <div className="border-b border-gray-100 px-4 py-2">
                    <span className="text-[10px] text-gray-400">
                      배치 가능 열 수: {maxSelectable}개
                    </span>
                  </div>
                )}
                <div className="max-h-[200px] overflow-y-auto divide-y divide-gray-50">
                  {columns.map((col) => {
                    const checked = selectedNames.has(col.column_name);
                    const disabled = !checked && isLimitReached;
                    return (
                      <label
                        key={col.column_name}
                        className={`flex items-center gap-3 px-4 py-2 transition-colors ${
                          disabled
                            ? "cursor-not-allowed opacity-40"
                            : "cursor-pointer hover:bg-gray-50"
                        } ${checked ? "bg-blue-50/40" : ""}`}
                      >
                        <input
                          type="checkbox"
                          checked={checked}
                          disabled={disabled}
                          onChange={() => toggleColumn(col.column_name)}
                          className="h-3.5 w-3.5 shrink-0 rounded border-gray-300 text-blue-600 disabled:cursor-not-allowed"
                        />
                        <span
                          className={`font-mono text-xs font-medium ${
                            checked ? "text-blue-700" : "text-gray-700"
                          }`}
                        >
                          {col.column_name}
                        </span>
                        <span className="rounded bg-gray-100 px-1 py-0.5 text-[9px] text-gray-500">
                          {col.data_type}
                        </span>
                        {col.is_nullable === "NO" && (
                          <span className="rounded bg-orange-50 px-1 py-0.5 text-[9px] text-orange-500">
                            NOT NULL
                          </span>
                        )}
                      </label>
                    );
                  })}
                </div>
              </>
            )}
          </div>
        )}
      </div>

      {/* Step 2: 선택된 컬럼 드래그 영역 */}
      {selectedColumns.length > 0 && (
        <div className="rounded-xl border border-border bg-white p-4">
          <div className="mb-3 text-sm font-bold text-gray-800">
            선택된 열
            <span className="ml-2 text-xs font-normal text-muted-foreground">
              드래그하여 아래 표에 배치 ({selectedColumns.length}개)
            </span>
          </div>
          <div className="grid grid-cols-3 gap-2">
            {selectedColumns.map((col) => (
              <DraggableColumn
                key={col.column_name}
                column={col}
                placed={placedColumns?.has(col.column_name)}
                onRemove={() => {
                  setSelectedNames((prev) => {
                    const next = new Set(prev);
                    next.delete(col.column_name);
                    return next;
                  });
                  onColumnRemove?.(col.column_name);
                }}
              />
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
