"use client";

import React, { useState, useMemo } from "react";
import { Input } from "@/components/ui/input";
import { ComponentRegistry } from "@/lib/registry/ComponentRegistry";
import { ComponentDefinition, ComponentCategory } from "@/types/component";
import {
  Search, Package, Layers, Palette, Zap, Database, GripVertical,
  Table2, BarChart3, Type, Minus, LayoutGrid, TextCursorInput, SlidersHorizontal,
  ListFilter, Workflow, Map, CalendarRange, ClipboardCheck, Warehouse, GitBranch,
  Truck, CircleDot, Boxes,
} from "lucide-react";
import { TableInfo, ColumnInfo } from "@/types/screen";

interface ComponentsPanelProps {
  className?: string;
  // 테이블 관련 props
  tables?: TableInfo[];
  searchTerm?: string;
  onSearchChange?: (value: string) => void;
  onTableDragStart?: (e: React.DragEvent, table: TableInfo, column?: ColumnInfo) => void;
  selectedTableName?: string;
  placedColumns?: Set<string>; // 이미 배치된 컬럼명 집합
  // 테이블 선택 관련 props
  onTableSelect?: (tableName: string) => void; // 테이블 선택 콜백
  showTableSelector?: boolean; // 테이블 선택 UI 표시 여부 (기본: 테이블 없으면 표시)
}

export function ComponentsPanel({
  className,
  tables = [],
  searchTerm = "",
  onSearchChange,
  onTableDragStart,
  selectedTableName,
  placedColumns,
  onTableSelect,
  showTableSelector = true,
}: ComponentsPanelProps) {
  const [searchQuery, setSearchQuery] = useState("");

  // 레지스트리에서 모든 컴포넌트 조회
  const allComponents = useMemo(() => {
    const components = ComponentRegistry.getAllComponents();
    // ★ 새 생성 경로는 canonical 'table' (displayMode='table').
    //   v2-table-list 는 옛 저장 화면 호환 hard blocker 로 자동 등록되지만
    //   팔레트에는 hidden 처리한다 (아래 hiddenComponents 참고).
    return components;
  }, []);

  // ── 기본 컴포넌트 (v2 하드코딩) ──
  const basicV2Components = useMemo(
    () =>
      [
        {
          id: "v2-repeater",
          name: "데이터 조회/선택",
          description: "다른 테이블에서 데이터를 조회하고 선택하여 전달",
          category: "data" as ComponentCategory,
          tags: ["조회", "선택", "전달", "모달", "repeater"],
          default_size: { width: 600, height: 300 },
        },
      ] as unknown as ComponentDefinition[],
    [],
  );

  // ── 고급 컴포넌트 (도메인 특화) ──
  const advancedComponents = useMemo(
    () =>
      [
        {
          id: "v2-bom-tree",
          name: "BOM 트리",
          description: "자재 구성을 계층 트리로 조회",
          category: "data" as ComponentCategory,
          tags: ["bom", "tree", "계층", "제조"],
          default_size: { width: 900, height: 600 },
        },
        {
          id: "v2-bom-item-editor",
          name: "BOM 편집",
          description: "하위 자재를 트리 구조로 추가/편집/삭제",
          category: "data" as ComponentCategory,
          tags: ["bom", "tree", "편집", "제조"],
          default_size: { width: 900, height: 400 },
        },
      ] as unknown as ComponentDefinition[],
    [],
  );

  // 레거시 호환 (기존 코드에서 v2Components 참조하는 곳용)
  const v2Components = useMemo(
    () => [...basicV2Components, ...advancedComponents],
    [basicV2Components, advancedComponents],
  );

  // 카테고리별 컴포넌트 그룹화
  const componentsByCategory = useMemo(() => {
    // 숨길 컴포넌트 ID 목록
    const hiddenComponents = [
      // 기본 입력 6종 (text-input/number-input/date-input/select-basic/
      // checkbox-basic/textarea-basic) — Phase E 에서 canonical input 으로 흡수, 등록/폴더 모두 삭제.
      // canonical input 으로 대체됨 (Phase D.4)
      "image-widget", // → canonical input (type='file', format='image')
      "file-upload", // → canonical input (type='file', format='file')
      "entity-search-input", // → canonical input (entity 모드)
      "autocomplete-search-input", // → canonical input (autocomplete 모드)
      // DataFlow 전용 (일반 화면에서 불필요)
      "mail-recipient-selector",
      // 현재 사용 안함
      "repeater-field-group",
      // v2-repeater로 통합됨
      "simple-repeater-table", // → v2-repeater (inline 모드)
      "modal-repeater-table", // → v2-repeater (modal 모드)
      // 특수 업무용 컴포넌트 (일반 화면에서 불필요)
      "tax-invoice-list", // 세금계산서 전용
      "customer-item-mapping", // 고객-품목 매핑 전용
      // card-display는 별도 컴포넌트로 유지
      // canonical input 으로 통합됨 (Phase D.4)
      "image-display", // → canonical input (type='file', format='image')
      // 공통코드관리로 통합 예정
      "category-manager", // → 공통코드관리 기능으로 통합 예정
      // 분할 패널 정리
      "screen-split-panel", // 화면 임베딩 방식은 사용하지 않음
      // 미완성/미사용 컴포넌트 (기존 화면 호환성 유지, 새 추가만 막음)
      "accordion-basic", // 아코디언 컴포넌트
      "conditional-container", // 조건부 컨테이너
      "universal-form-modal", // 범용 폼 모달
      // v2-media — Phase D.4 에서 canonical input 으로 흡수, 폴더/렌더러 삭제.
      // 플로우 위젯 숨김 처리
      "flow-widget",
      // 선택 항목 상세입력 - 거래처 품목 추가 등에서 사용
      "selected-items-detail-input", // → 데이터 조회/선택 으로 대체
      // 연관 데이터 버튼 - v2-repeater로 대체 가능
      "related-data-buttons",
      // ===== V2로 대체된 기존 컴포넌트 (v2 버전만 사용) =====
      "button-primary", // → v2-button-primary
      "split-panel-layout", // → v2-split-panel-layout
      // aggregation-widget: 폴더/Renderer 삭제 (2026-05-19). ComponentRegistry 에 없음 — hidden 처리 불필요
      "table-list", // legacy hidden — 새 생성 경로는 canonical 'table'
      "text-display", // → v2-text-display
      "divider-line", // → v2-divider-line
      // ★ 2026-04-11 통합 컴포넌트(Phase A-1): 구분선 3종 → `divider`
      "v2-divider-line", // → divider
      "v2-split-line", // → divider (drag-resize 기능은 다음 Phase)
      // ★ 2026-04-11 통합 컴포넌트(Phase A-2): 제목/텍스트 2종 → `title`
      "v2-text-display", // → title
      // text-display 는 아래 기존 항목에서 이미 숨김 처리됨
      // ★ 2026-04-11 통합 컴포넌트(Phase A-3): 버튼 → `button`
      "v2-button-primary", // → button
      // button-primary 는 아래 기존 항목에서 이미 숨김 처리됨
      // related-data-buttons 는 기존에 이미 숨김
      // ★ 2026-04-11 통합 컴포넌트(Phase A-4): 검색 필터 → `search`
      "v2-table-search-widget", // → search
      // table-search-widget, autocomplete-search-input 은 기존에 이미 숨김
      // ★ 2026-04-11 통합 컴포넌트(Phase B-1): 필드 입력 20+종 → `input`
      // (V2 입력/선택은 Phase D.2 에서 완전 폐기 — 등록/생성 경로 자체 삭제, hidden 목록에 둘 필요 없음)
      "v2-category-manager", // → input (type='select', 추후 category 특화)
      // v2-file-upload / v2-media / v2-numbering-rule 는 Phase D.4 / D.5 / 2026-05-11
      // 폐기. 폴더/렌더러 삭제 — hidden 목록에 둘 필요 없음.
      "v2-location-swap-selector", // → input (type='entity')
      // 아래 legacy 들은 이미 상단 섹션에서 hidden / 또는 Phase E·F.1 에서 폴더 삭제:
      //   text-input, number-input, date-input, textarea-basic, select-basic, checkbox-basic
      //   radio-basic, toggle-switch (Phase F.1)
      //   image-widget, entity-search-input, autocomplete-search-input, file-upload (일부)
      // ★ 2026-04-11 통합 컴포넌트(Phase B-2): 통계/KPI → `stats`
      // v2-aggregation-widget / v2-status-count: 폴더/Renderer 삭제 (2026-05-19).
      //   ComponentRegistry 에 없음 — hidden list 에 둘 필요 없음. 옛 저장 화면은
      //   DynamicComponentRenderer.LEGACY_TO_UNIFIED 로 canonical `stats` 라우팅.
      // card-display 는 기존 상단에서 이미 숨김
      // form 컴포넌트는 롤백됨 (2026-04-11): 3뷰 탭 구조로 처리 예정.
      "field-example-1", // legacy form-layout 의 실제 id (숨김 유지)
      // ★ 2026-04-11 통합 컴포넌트(Phase C-1): 데이터 테이블 → `table`
      "v2-table-list", // → table (displayMode='table')
      "v2-split-panel-layout", // → table (displayMode='split')
      // table-list, split-panel-layout, split-panel-layout2, modal-repeater-table,
      // simple-repeater-table, tax-invoice-list, pivot-grid 는 기존 상단에서 이미 숨김
      // ★ 2026-04-11 통합 컴포넌트(Phase C-2): 컨테이너 → `container`
      // v2-tabs-widget / v2-section-card / v2-section-paper / section-card / section-paper / tabs / tabs-widget:
      //   폴더/Renderer 삭제 (2026-05-19). ComponentRegistry 에 없음 — hidden 처리 불필요.
      //   옛 저장 화면은 DynamicComponentRenderer.LEGACY_TO_UNIFIED 로 canonical `container` 라우팅.
      "v2-repeat-container", // → container (containerType='repeater')
      "v2-repeater", // → container (containerType='repeater')
      // accordion-basic, conditional-container, repeat-container, repeat-screen-modal,
      // repeater-field-group, screen-split-panel 는 기존 상단에서 이미 숨김
      // numbering-rule: 폐기 (2026-05-11)
      "split-panel-layout2", // → table (displayMode='split') Phase E 통합
      "location-swap-selector", // → v2-location-swap-selector
      "rack-structure", // → v2-rack-structure
      "v2-repeater", // → v2-repeater (아래 v2Components에서 별도 처리)
      "repeat-container", // → v2-repeat-container
      "repeat-screen-modal", // → v2-repeat-screen-modal
      "table-search-widget", // → v2-table-search-widget
    ];

    return {
      input: allComponents.filter((c) => c.category === ComponentCategory.INPUT && !hiddenComponents.includes(c.id)),
      action: allComponents.filter((c) => c.category === ComponentCategory.ACTION && !hiddenComponents.includes(c.id)),
      display: allComponents.filter(
        (c) => c.category === ComponentCategory.DISPLAY && !hiddenComponents.includes(c.id),
      ),
      data: allComponents.filter((c) => c.category === ComponentCategory.DATA && !hiddenComponents.includes(c.id)),
      layout: allComponents.filter((c) => c.category === ComponentCategory.LAYOUT && !hiddenComponents.includes(c.id)),
      utility: allComponents.filter(
        (c) => c.category === ComponentCategory.UTILITY && !hiddenComponents.includes(c.id),
      ),
      v2: v2Components,
    };
  }, [allComponents, v2Components]);

  // 카테고리별 검색 필터링
  const getFilteredComponents = (category: keyof typeof componentsByCategory) => {
    let components = componentsByCategory[category];

    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      components = components.filter(
        (component: ComponentDefinition) =>
          component.name.toLowerCase().includes(query) ||
          component.description.toLowerCase().includes(query) ||
          component.tags?.some((tag: string) => tag.toLowerCase().includes(query)),
      );
    }

    return components;
  };

  // ── INVYONE 컴포넌트별 아이콘 매핑 ──
  const getComponentIcon = (id: string, category: string) => {
    const s = 14;
    const icons: Record<string, React.ReactNode> = {
      table: <Table2 size={s} />,
      "v2-table-list": <Table2 size={s} />,
      stats: <BarChart3 size={s} />,
      title: <Type size={s} />,
      divider: <Minus size={s} />,
      container: <LayoutGrid size={s} />,
      input: <TextCursorInput size={s} />,
      button: <Zap size={s} />,
      search: <ListFilter size={s} />,
      "v2-repeater": <SlidersHorizontal size={s} />,
      "v2-bom-tree": <Boxes size={s} />,
      "v2-bom-item-editor": <Boxes size={s} />,
      "v2-approval-step": <ClipboardCheck size={s} />,
      map: <Map size={s} />,
      "v2-shipping-plan-editor": <Truck size={s} />,
      "v2-timeline-scheduler": <CalendarRange size={s} />,
      "v2-rack-structure": <Warehouse size={s} />,
      "v2-process-work-standard": <Workflow size={s} />,
      "v2-item-routing": <GitBranch size={s} />,
    };
    if (icons[id]) return icons[id];
    // 카테고리 폴백
    switch (category) {
      case "data": return <Database size={s} />;
      case "display": return <Palette size={s} />;
      case "action": return <Zap size={s} />;
      case "layout": return <Layers size={s} />;
      default: return <CircleDot size={s} />;
    }
  };

  // getCategoryIcon 제거됨 — getComponentIcon 으로 대체

  // 드래그 시작 핸들러
  //
  // ★ 2026-04-11 버그 픽스:
  //   handleComponentDrop (ScreenDesigner.tsx) 이 component.defaultSize,
  //   component.defaultConfig, component.webType (camelCase) 로 접근하지만
  //   ComponentDefinition 은 default_size / default_config / web_type
  //   (snake_case) 로 저장한다. 격자 스냅이 켜진 상태에서 이 불일치 때문에
  //   drop 함수가 TypeError 로 중단되어 컴포넌트 배치가 전혀 안 됐음.
  //   여기서 camelCase 별칭을 함께 주입해서 호환.
  const handleDragStart = (e: React.DragEvent<HTMLDivElement>, component: ComponentDefinition) => {
    const dragData = {
      type: "component",
      component: {
        ...component,
        // snake_case → camelCase 별칭 (handleComponentDrop 호환)
        defaultSize: component.default_size,
        defaultConfig: component.default_config,
        webType: component.web_type,
      },
    };
    e.dataTransfer.setData("application/json", JSON.stringify(dragData));
    e.dataTransfer.effectAllowed = "copy";
  };

  // ── 카테고리별 컬러 클래스 ──
  const getCategoryAccent = (cat: string) => {
    switch (cat) {
      case "data": return "inv-cat-data";
      case "display": return "inv-cat-display";
      case "action": return "inv-cat-action";
      case "layout": return "inv-cat-layout";
      case "input": return "inv-cat-input";
      case "utility": return "inv-cat-utility";
      default: return "inv-cat-default";
    }
  };

  // ── INVYONE 컴포넌트 카드 ──
  const renderComponentCard = (component: ComponentDefinition) => (
    <div
      key={component.id}
      draggable
      onDragStart={(e) => {
        handleDragStart(e, component);
        e.currentTarget.style.opacity = "0.5";
      }}
      onDragEnd={(e) => {
        e.currentTarget.style.opacity = "1";
      }}
      className={`inv-comp-card ${getCategoryAccent(component.category)}`}
      title={component.description}
    >
      <div className="inv-comp-icon">
        {getComponentIcon(component.id, component.category)}
      </div>
      <span className="inv-comp-name">{component.name}</span>
      <GripVertical size={10} className="inv-comp-grip" />
    </div>
  );

  // 빈 상태 렌더링
  const renderEmptyState = () => (
    <div className="text-muted-foreground flex h-20 items-center justify-center text-center text-[0.6rem]">
      검색 결과 없음
    </div>
  );

  // ── 기본/고급 ID 분류 ──
  const BASIC_IDS = new Set([
    "table", "search", "input", "button", "stats", "chart", "card-list", "grouped-table",
    "title", "divider", "container",
    "v2-repeater",
  ]);
  const ADVANCED_IDS = new Set([
    "v2-bom-tree", "v2-bom-item-editor", "v2-approval-step",
    "map", "v2-shipping-plan-editor", "v2-timeline-scheduler",
    "v2-rack-structure", "v2-process-work-standard", "v2-item-routing",
  ]);

  const allFiltered = useMemo(() => {
    const all = [
      ...getFilteredComponents("v2"),
      ...getFilteredComponents("action"),
      ...getFilteredComponents("display"),
      ...getFilteredComponents("data"),
      ...getFilteredComponents("layout"),
      ...getFilteredComponents("input"),
      ...getFilteredComponents("utility"),
    ];
    return {
      basic: all.filter((c) => BASIC_IDS.has(c.id)),
      advanced: all.filter((c) => ADVANCED_IDS.has(c.id)),
    };
  }, [searchQuery, componentsByCategory]);

  // 테이블 컬럼을 드래그 가능한 칩으로 렌더
  const selectedTable = tables?.find(
    (t: any) => (t.tableName || t.table_name) === selectedTableName,
  );
  const tableColumns = (selectedTable as any)?.columns || [];

  return (
    <div className={`inv-panel-root ${className || ""}`}>
      {/* 검색 */}
      <div className="inv-search-wrap">
        <Search size={12} className="inv-search-icon" />
        <Input
          placeholder="검색..."
          value={searchQuery}
          onChange={(e) => {
            const value = e.target.value;
            setSearchQuery(value);
            if (onSearchChange) onSearchChange(value);
          }}
          className="inv-search-input"
        />
      </div>

      {/* 단일 스크롤 영역 */}
      <div className="inv-panel-scroll">

        {/* ── 테이블 컬럼 (선택된 테이블이 있을 때만) ── */}
        {selectedTableName && (
          <details open className="inv-section">
            <summary className="inv-section-header">
              <Database size={11} />
              <span className="flex-1">{selectedTableName}</span>
              <span className="inv-section-count">{tableColumns.length}</span>
            </summary>
            <div className="inv-column-list">
              {tableColumns.length > 0 ? (
                tableColumns.map((col: any) => {
                  const colName = col.columnName || col.column_name;
                  const colLabel = col.columnLabel || col.column_label || col.displayName || colName;
                  const isPlaced = placedColumns?.has(colName);
                  const dataType = (col.dataType || col.data_type || "").toLowerCase();
                  let tag = "TXT";
                  if (dataType.includes("int") || dataType.includes("numeric") || dataType.includes("decimal")) tag = "NUM";
                  else if (dataType.includes("date") || dataType.includes("time")) tag = "DATE";
                  else if (dataType.includes("bool")) tag = "BOOL";

                  return (
                    <div
                      key={colName}
                      draggable={!isPlaced}
                      onDragStart={(e) => {
                        if (isPlaced || !selectedTable) return;
                        onTableDragStart?.(e, selectedTable as any, col);
                      }}
                      className={`inv-col-row ${isPlaced ? "placed" : ""}`}
                      data-type={tag}
                    >
                      <span className="inv-col-tag">{tag}</span>
                      <span className="inv-col-name" title={colName}>{colLabel}</span>
                      {isPlaced && <span className="inv-col-placed">배치됨</span>}
                    </div>
                  );
                })
              ) : (
                <div className="text-muted-foreground py-2 text-center text-[0.6rem]">
                  컬럼 없음
                </div>
              )}
            </div>
            {/* 테이블 변경 */}
            {showTableSelector && tables && tables.length > 1 && (
              <select
                value={selectedTableName || ""}
                onChange={(e) => onTableSelect?.(e.target.value)}
                className="inv-table-select"
              >
                {tables.map((t: any) => (
                  <option key={t.tableName || t.table_name} value={t.tableName || t.table_name}>
                    {t.tableLabel || t.table_label || t.tableName || t.table_name}
                  </option>
                ))}
              </select>
            )}
          </details>
        )}

        {/* ── 컴포넌트 ── */}
        <div className="inv-section">
          <div className="inv-section-header inv-section-static">
            <Package size={11} />
            <span>컴포넌트</span>
          </div>
          <div className="inv-comp-list">
            {allFiltered.basic.length > 0
              ? allFiltered.basic.map(renderComponentCard)
              : renderEmptyState()}
          </div>
        </div>

        {/* ── 더보기 ── */}
        {allFiltered.advanced.length > 0 && (
          <details className="inv-section inv-more-section">
            <summary className="inv-more-toggle">
              <span>더보기</span>
              <span className="inv-more-count">{allFiltered.advanced.length}</span>
            </summary>
            <div className="inv-comp-list">
              {allFiltered.advanced.map(renderComponentCard)}
            </div>
          </details>
        )}
      </div>
    </div>
  );
}
