"use client";

import React, { useState, useEffect, useCallback } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Database,
  Type,
  Hash,
  Calendar,
  CheckSquare,
  List,
  AlignLeft,
  Code,
  Building,
  File,
  Link2,
  ChevronDown,
  ChevronRight,
  Plus,
  Search,
  X,
} from "lucide-react";
import { TableInfo, WebType } from "@/types/screen";
import { entityJoinApi } from "@/lib/api/entityJoin";
import { tableManagementApi } from "@/lib/api/tableManagement";

interface EntityJoinColumn {
  columnName: string;
  columnLabel: string;
  dataType: string;
  inputType?: string;
  description?: string;
}

interface EntityJoinTable {
  tableName: string;
  currentDisplayColumn: string;
  availableColumns: EntityJoinColumn[];
  // 같은 테이블이 여러 FK로 조인될 수 있으므로 소스 컬럼으로 구분
  joinConfig?: {
    sourceColumn: string;
    [key: string]: unknown;
  };
}

interface TablesPanelProps {
  tables: TableInfo[];
  searchTerm: string;
  onSearchChange: (term: string) => void;
  onDragStart: (e: React.DragEvent, table: TableInfo, column?: any) => void;
  selectedTableName?: string;
  placedColumns?: Set<string>; // 이미 배치된 컬럼명 집합 (tableName.columnName 형식)
  // 테이블 선택 관련 props
  onTableSelect?: (tableName: string) => void; // 테이블 선택 콜백
  showTableSelector?: boolean; // 테이블 선택 UI 표시 여부
}

// 위젯 타입별 아이콘
const getWidgetIcon = (widgetType: WebType) => {
  switch (widgetType) {
    case "text":
    case "email":
    case "tel":
      return <Type className="text-primary h-3 w-3" />;
    case "number":
    case "decimal":
      return <Hash className="h-3 w-3 text-emerald-600" />;
    case "date":
    case "datetime":
      return <Calendar className="h-3 w-3 text-purple-600" />;
    case "select":
    case "dropdown":
      return <List className="h-3 w-3 text-amber-600" />;
    case "textarea":
    case "text_area":
      return <AlignLeft className="h-3 w-3 text-primary" />;
    case "boolean":
    case "checkbox":
      return <CheckSquare className="text-primary h-3 w-3" />;
    case "code":
      return <Code className="text-muted-foreground h-3 w-3" />;
    case "entity":
      return <Building className="h-3 w-3 text-cyan-600" />;
    case "file":
      return <File className="h-3 w-3 text-amber-600" />;
    default:
      return <Type className="h-3 w-3 text-muted-foreground" />;
  }
};

export const TablesPanel: React.FC<TablesPanelProps> = ({
  tables,
  searchTerm,
  onDragStart,
  placedColumns = new Set(),
  onTableSelect,
  showTableSelector = false,
}) => {
  // 엔티티 조인 컬럼 상태
  const [entityJoinTables, setEntityJoinTables] = useState<EntityJoinTable[]>([]);
  const [loadingEntityJoins, setLoadingEntityJoins] = useState(false);
  const [expandedJoinTables, setExpandedJoinTables] = useState<Set<string>>(new Set());

  // 전체 테이블 목록 (테이블 선택용)
  const [allTables, setAllTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
  const [loadingAllTables, setLoadingAllTables] = useState(false);
  const [tableSearchTerm, setTableSearchTerm] = useState("");
  const [showTableSelectDropdown, setShowTableSelectDropdown] = useState(false);

  // 시스템 컬럼 목록 (숨김 처리)
  const systemColumns = new Set([
    "id",
    "created_date",
    "updated_date",
    "writer",
    "company_code",
  ]);

  // 전체 테이블 목록 로드
  const loadAllTables = useCallback(async () => {
    if (allTables.length > 0) return; // 이미 로드됨
    
    setLoadingAllTables(true);
    try {
      const response = await tableManagementApi.getTableList();
      if (response.success && response.data) {
        setAllTables(response.data.map((t: any) => ({
          tableName: t.tableName || t.table_name,
          displayName: t.displayName || t.table_label || t.tableName || t.table_name,
        })));
      }
    } catch (error) {
      console.error("테이블 목록 조회 오류:", error);
    } finally {
      setLoadingAllTables(false);
    }
  }, [allTables.length]);

  // 테이블 선택 시 호출
  const handleTableSelect = (tableName: string) => {
    setShowTableSelectDropdown(false);
    setTableSearchTerm("");
    onTableSelect?.(tableName);
  };

  // 필터링된 테이블 목록
  const filteredAllTables = tableSearchTerm
    ? allTables.filter(
        (t) =>
          t.tableName.toLowerCase().includes(tableSearchTerm.toLowerCase()) ||
          t.displayName.toLowerCase().includes(tableSearchTerm.toLowerCase())
      )
    : allTables;

  // 메인 테이블명 추출
  const mainTableName = tables[0]?.tableName;

  // 엔티티 조인 컬럼 로드
  useEffect(() => {
    const fetchEntityJoinColumns = async () => {
      if (!mainTableName) {
        setEntityJoinTables([]);
        return;
      }

      setLoadingEntityJoins(true);
      try {
        const result = await entityJoinApi.getEntityJoinColumns(mainTableName);
        setEntityJoinTables(result.joinTables || []);
        // 기본적으로 모든 조인 테이블 펼치기
        setExpandedJoinTables(new Set(result.joinTables?.map((t) => t.tableName) || []));
      } catch (error) {
        console.error("엔티티 조인 컬럼 조회 오류:", error);
        setEntityJoinTables([]);
      } finally {
        setLoadingEntityJoins(false);
      }
    };

    fetchEntityJoinColumns();
  }, [mainTableName]);

  // 조인 테이블 펼치기/접기 토글
  const toggleJoinTable = (tableName: string) => {
    setExpandedJoinTables((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(tableName)) {
        newSet.delete(tableName);
      } else {
        newSet.add(tableName);
      }
      return newSet;
    });
  };

  // 엔티티 조인 컬럼 드래그 핸들러
  const handleEntityJoinDragStart = (
    e: React.DragEvent,
    joinTable: EntityJoinTable,
    column: EntityJoinColumn,
  ) => {
    // "테이블명.컬럼명" 형식으로 컬럼 정보 생성
    const fullColumnName = `${joinTable.tableName}.${column.columnName}`;

    const columnData = {
      columnName: fullColumnName,
      columnLabel: column.columnLabel || column.columnName,
      dataType: column.dataType,
      widgetType: "text" as WebType,
      isEntityJoin: true,
      entityJoinTable: joinTable.tableName,
      entityJoinColumn: column.columnName,
    };

    // 기존 테이블 정보를 기반으로 가상의 테이블 정보 생성
    const virtualTable: TableInfo = {
      tableName: mainTableName || "",
      tableLabel: tables[0]?.tableLabel || mainTableName || "",
      columns: [columnData],
    };

    onDragStart(e, virtualTable, columnData);
  };

  // 이미 배치된 컬럼과 시스템 컬럼을 제외한 테이블 정보 생성
  const tablesWithAvailableColumns = tables.map((table) => ({
    ...table,
    columns: table.columns.filter((col) => {
      const columnKey = `${table.tableName}.${col.columnName}`;
      // 시스템 컬럼이거나 이미 배치된 컬럼은 제외
      return !systemColumns.has(col.columnName.toLowerCase()) && !placedColumns.has(columnKey);
    }),
  }));

  // 검색어가 있으면 컬럼 필터링
  const filteredTables = tablesWithAvailableColumns
    .map((table) => {
      if (!searchTerm) {
        return table;
      }

      const searchLower = searchTerm.toLowerCase();

      // 테이블명이 검색어와 일치하면 모든 컬럼 표시
      if (
        table.tableName.toLowerCase().includes(searchLower) ||
        (table.tableLabel && table.tableLabel.toLowerCase().includes(searchLower))
      ) {
        return table;
      }

      // 그렇지 않으면 컬럼명/라벨이 검색어와 일치하는 컬럼만 필터링
      const filteredColumns = table.columns.filter(
        (col) =>
          col.columnName.toLowerCase().includes(searchLower) ||
          (col.columnLabel && col.columnLabel.toLowerCase().includes(searchLower)),
      );

      return {
        ...table,
        columns: filteredColumns,
      };
    })
    .filter((table) => table.columns.length > 0); // 컬럼이 있는 테이블만 표시

  return (
    <div className="flex h-full flex-col">
      {/* 테이블 선택 버튼 (메인 테이블이 없을 때 또는 showTableSelector가 true일 때) */}
      {(showTableSelector || tables.length === 0) && (
        <div className="border-b p-3">
          <div className="relative">
            <Button
              variant="outline"
              size="sm"
              className="w-full justify-between"
              onClick={() => {
                setShowTableSelectDropdown(!showTableSelectDropdown);
                if (!showTableSelectDropdown) {
                  loadAllTables();
                }
              }}
            >
              <span className="flex items-center gap-2">
                <Plus className="h-3.5 w-3.5" />
                {tables.length > 0 ? "테이블 추가/변경" : "테이블 선택"}
              </span>
              <ChevronDown className="h-4 w-4" />
            </Button>

            {/* 드롭다운 */}
            {showTableSelectDropdown && (
              <div className="absolute top-full left-0 z-50 mt-1 w-full rounded-md border bg-white shadow-lg">
                {/* 검색 */}
                <div className="border-b p-2">
                  <div className="relative">
                    <Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground/70" />
                    <input
                      type="text"
                      placeholder="테이블 검색..."
                      value={tableSearchTerm}
                      onChange={(e) => setTableSearchTerm(e.target.value)}
                      autoFocus
                      className="w-full rounded-md border px-8 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
                    />
                    {tableSearchTerm && (
                      <button
                        onClick={() => setTableSearchTerm("")}
                        className="absolute right-2 top-1/2 -translate-y-1/2"
                      >
                        <X className="h-3.5 w-3.5 text-muted-foreground/70" />
                      </button>
                    )}
                  </div>
                </div>

                {/* 테이블 목록 */}
                <div className="max-h-60 overflow-y-auto">
                  {loadingAllTables ? (
                    <div className="p-4 text-center text-sm text-muted-foreground">로드 중...</div>
                  ) : filteredAllTables.length === 0 ? (
                    <div className="p-4 text-center text-sm text-muted-foreground">
                      {tableSearchTerm ? "검색 결과 없음" : "테이블 없음"}
                    </div>
                  ) : (
                    filteredAllTables.map((t) => (
                      <button
                        key={t.tableName}
                        onClick={() => handleTableSelect(t.tableName)}
                        className="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-muted"
                      >
                        <Database className="h-3.5 w-3.5 text-primary" />
                        <div className="min-w-0 flex-1">
                          <div className="truncate font-medium">{t.displayName}</div>
                          <div className="truncate text-xs text-muted-foreground">{t.tableName}</div>
                        </div>
                      </button>
                    ))
                  )}
                </div>
              </div>
            )}
          </div>

          {/* 현재 테이블 정보 */}
          {tables.length > 0 && (
            <div className="mt-2 text-xs text-muted-foreground">
              현재: {tables[0]?.tableLabel || tables[0]?.tableName}
            </div>
          )}
        </div>
      )}

      {/* 테이블과 컬럼 평면 목록 */}
      <div className="flex-1 overflow-y-auto p-3">
        <div className="space-y-2">
          {filteredTables.map((table) => (
            <div key={table.tableName} className="space-y-1">
              {/* 테이블 헤더 */}
              <div className="bg-muted/50 flex items-center justify-between rounded-md p-2">
                <div className="flex items-center gap-2">
                  <Database className="text-primary h-3.5 w-3.5" />
                  <span className="text-xs font-semibold">{table.tableLabel || table.tableName}</span>
                  <Badge variant="secondary" className="h-4 px-1.5 text-[10px]">
                    {table.columns.length}개
                  </Badge>
                </div>
              </div>

              {/* 컬럼 목록 (항상 표시) */}
              <div className="space-y-1 pl-2">
                {table.columns.map((column) => (
                  <div
                    key={column.columnName}
                    className="hover:bg-accent/50 flex cursor-grab items-center gap-2 rounded-md p-2 transition-colors"
                    draggable
                    onDragStart={(e) => onDragStart(e, table, column)}
                  >
                      {getWidgetIcon(column.widgetType)}
                      <div className="min-w-0 flex-1">
                      <div
                        className="text-xs font-medium"
                        title={column.columnLabel || column.columnName}
                      >
                        {column.columnLabel || column.columnName}
                      </div>
                    </div>
                    <div className="flex flex-shrink-0 items-center gap-1">
                      <Badge variant="secondary" className="h-4 px-1.5 text-[10px]">
                        {column.widgetType}
                      </Badge>
                      {column.required && (
                        <Badge variant="destructive" className="h-4 px-1 text-[10px]">
                          필수
                        </Badge>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          ))}

          {/* 엔티티 조인 컬럼 섹션 */}
          {entityJoinTables.length > 0 && (
            <div className="mt-4 space-y-2">
              <div className="flex items-center gap-2 px-2 py-1">
                <Link2 className="h-3.5 w-3.5 text-cyan-600" />
                <span className="text-muted-foreground text-xs font-medium">엔티티 조인 컬럼</span>
                <Badge variant="outline" className="h-4 px-1.5 text-[10px]">
                  {entityJoinTables.length}
                </Badge>
              </div>

              {entityJoinTables.map((joinTable, idx) => {
                const uniqueKey = `entity-join-${joinTable.tableName}-${joinTable.joinConfig?.sourceColumn || ''}-${idx}`;
                const isExpanded = expandedJoinTables.has(joinTable.tableName);
                // 검색어로 필터링
                const filteredColumns = searchTerm
                  ? joinTable.availableColumns.filter(
                      (col) =>
                        col.columnName.toLowerCase().includes(searchTerm.toLowerCase()) ||
                        col.columnLabel.toLowerCase().includes(searchTerm.toLowerCase()),
                    )
                  : joinTable.availableColumns;

                // 검색 결과가 없으면 표시하지 않음
                if (searchTerm && filteredColumns.length === 0) {
                  return null;
                }

                return (
                  <div key={uniqueKey} className="space-y-1">
                    {/* 조인 테이블 헤더 */}
                    <div
                      className="flex cursor-pointer items-center justify-between rounded-md bg-cyan-50 p-2 hover:bg-cyan-100"
                      onClick={() => toggleJoinTable(joinTable.tableName)}
                    >
                      <div className="flex items-center gap-2">
                        {isExpanded ? (
                          <ChevronDown className="h-3 w-3 text-cyan-600" />
                        ) : (
                          <ChevronRight className="h-3 w-3 text-cyan-600" />
                        )}
                        <Building className="h-3.5 w-3.5 text-cyan-600" />
                        <span className="text-xs font-semibold text-cyan-800">{joinTable.tableName}</span>
                        <Badge variant="secondary" className="h-4 px-1.5 text-[10px]">
                          {filteredColumns.length}개
                        </Badge>
                      </div>
                    </div>

                    {/* 조인 컬럼 목록 */}
                    {isExpanded && (
                      <div className="space-y-1 pl-4">
                        {filteredColumns.map((column) => {
                          const fullColumnName = `${joinTable.tableName}.${column.columnName}`;
                          const isPlaced = placedColumns.has(fullColumnName);

                          if (isPlaced) return null;

                          return (
                            <div
                              key={column.columnName}
                              className="flex cursor-grab items-center gap-2 rounded-md border border-cyan-200 bg-cyan-50/50 p-2 transition-colors hover:bg-cyan-100"
                              draggable
                              onDragStart={(e) => handleEntityJoinDragStart(e, joinTable, column)}
                              title="읽기 전용 - 조인된 테이블에서 참조"
                            >
                              <Link2 className="h-3 w-3 flex-shrink-0 text-cyan-500" />
                              <div className="min-w-0 flex-1">
                                <div className="text-xs font-medium" title={column.columnLabel || column.columnName}>
                                  {column.columnLabel || column.columnName}
                                </div>
                              </div>
                              <div className="flex flex-shrink-0 items-center gap-1">
                                <Badge variant="secondary" className="h-4 border-input bg-muted px-1 text-[9px] text-muted-foreground">
                                  읽기
                                </Badge>
                                <Badge variant="outline" className="h-4 border-cyan-300 px-1.5 text-[10px]">
                                  {column.inputType || "text"}
                                </Badge>
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          )}

          {/* 로딩 표시 */}
          {loadingEntityJoins && (
            <div className="text-muted-foreground flex items-center justify-center py-4 text-xs">
              엔티티 조인 컬럼 로드 중...
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default TablesPanel;
