"use client";

import React, { useState, useEffect, useMemo } from "react";
import { apiClient } from "@/lib/api/client";
import { getCategoryValues } from "@/lib/api/tableCategoryValue";
import { ChevronRight, FolderTree, Loader2, Search, X } from "lucide-react";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";

export interface CategoryColumn {
  tableName: string;
  tableLabel?: string;
  columnName: string;
  columnLabel: string;
  inputType: string;
  valueCount?: number;
}

interface CategoryColumnListProps {
  tableName: string;
  selectedColumn: string | null;
  onColumnSelect: (uniqueKeyOrColumnName: string, columnLabel: string, tableName: string) => void;
  menuObjid?: number;
  /** 대시보드 모드: 테이블 단위 네비만 표시, 선택 시 onTableSelect 호출 */
  selectedTable?: string | null;
  onTableSelect?: (tableName: string) => void;
  /** 컬럼 로드 완료 시 부모에 전달 (Stat Strip 등 계산용) */
  onColumnsLoaded?: (columns: CategoryColumn[]) => void;
}

/**
 * 카테고리 컬럼 목록 (좌측 패널)
 * - 형제 메뉴들의 모든 카테고리 타입 컬럼을 표시 (메뉴 스코프)
 */
export function CategoryColumnList({
  tableName,
  selectedColumn,
  onColumnSelect,
  menuObjid,
  selectedTable = null,
  onTableSelect,
  onColumnsLoaded,
}: CategoryColumnListProps) {
  const [columns, setColumns] = useState<CategoryColumn[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());

  // 검색어로 필터링된 컬럼 목록
  const filteredColumns = useMemo(() => {
    if (!searchQuery.trim()) return columns;
    
    const query = searchQuery.toLowerCase();
    return columns.filter((col) => {
      const columnName = (col.columnName || "").toLowerCase();
      const columnLabel = (col.columnLabel || "").toLowerCase();
      const tableName = (col.tableName || "").toLowerCase();
      const tableLabel = (col.tableLabel || "").toLowerCase();
      
      return columnName.includes(query) || 
             columnLabel.includes(query) || 
             tableName.includes(query) || 
             tableLabel.includes(query);
    });
  }, [columns, searchQuery]);

  // 테이블별로 그룹화된 컬럼 목록
  const groupedColumns = useMemo(() => {
    const groups: { tableName: string; tableLabel: string; columns: CategoryColumn[] }[] = [];
    const groupMap = new Map<string, CategoryColumn[]>();

    for (const col of filteredColumns) {
      const key = col.tableName;
      if (!groupMap.has(key)) {
        groupMap.set(key, []);
      }
      groupMap.get(key)!.push(col);
    }

    for (const [tblName, cols] of groupMap) {
      groups.push({
        tableName: tblName,
        tableLabel: cols[0]?.tableLabel || tblName,
        columns: cols,
      });
    }

    return groups;
  }, [filteredColumns]);

  // 선택된 컬럼이 있는 그룹을 자동 펼침
  useEffect(() => {
    if (!selectedColumn) return;
    const tableName = selectedColumn.split(".")[0];
    if (tableName) {
      setExpandedGroups((prev) => {
        if (prev.has(tableName)) return prev;
        const next = new Set(prev);
        next.add(tableName);
        return next;
      });
    }
  }, [selectedColumn]);

  useEffect(() => {
    // 메뉴 종속 없이 항상 회사 기준으로 카테고리 컬럼 조회
    loadCategoryColumnsByMenu();
  }, [menuObjid, tableName]);

  // tableName 기반으로 카테고리 컬럼 조회
  const loadCategoryColumnsByTable = async () => {
    setIsLoading(true);
    try {
      console.log("🔍 테이블 기반 카테고리 컬럼 조회 시작", { tableName });
      
      // table_type_columns에서 input_type='category'인 컬럼 조회
      const response = await apiClient.get(`/screen-management/tables/${tableName}/columns`);

      console.log("✅ 테이블 컬럼 API 응답:", response.data);

      let allColumns: any[] = [];
      if (response.data.success && response.data.data) {
        allColumns = response.data.data;
      } else if (Array.isArray(response.data)) {
        allColumns = response.data;
      }

      // category 타입 중 자체 카테고리만 필터링 (참조 컬럼 제외)
      const categoryColumns = allColumns.filter(
        (col: any) => (col.inputType === "category" || col.input_type === "category")
          && !col.categoryRef && !col.category_ref
      );

      console.log("✅ 카테고리 컬럼 필터링 완료:", {
        total: allColumns.length,
        categoryCount: categoryColumns.length,
      });

      // 값 개수 조회 (테스트 테이블 사용)
      const columnsWithCount = await Promise.all(
        categoryColumns.map(async (col: any) => {
          const colName = col.columnName || col.column_name;
          const colLabel = col.columnLabel || col.column_label || colName;

          let valueCount = 0;
          try {
            // 테스트 테이블에서 조회
            const treeResponse = await apiClient.get(`/category-tree/test/${tableName}/${colName}`);
            if (treeResponse.data.success && treeResponse.data.data) {
              valueCount = countTreeNodes(treeResponse.data.data);
            }
          } catch (error) {
            console.error(`항목 개수 조회 실패 (${tableName}.${colName}):`, error);
          }

          return {
            tableName,
            tableLabel: tableName,
            columnName: colName,
            columnLabel: colLabel,
            inputType: "category",
            valueCount,
          };
        }),
      );

      setColumns(columnsWithCount);
      onColumnsLoaded?.(columnsWithCount);

      if (columnsWithCount.length > 0 && !selectedColumn) {
        const firstCol = columnsWithCount[0];
        onColumnSelect(`${firstCol.tableName}.${firstCol.columnName}`, firstCol.columnLabel, firstCol.tableName);
      }
    } catch (error) {
      console.error("❌ 테이블 기반 카테고리 컬럼 조회 실패:", error);
      setColumns([]);
      onColumnsLoaded?.([]);
    } finally {
      setIsLoading(false);
    }
  };

  // 트리 노드 수 계산 함수
  const countTreeNodes = (nodes: any[]): number => {
    let count = nodes.length;
    for (const node of nodes) {
      if (node.children && Array.isArray(node.children)) {
        count += countTreeNodes(node.children);
      }
    }
    return count;
  };

  const loadCategoryColumnsByMenu = async () => {
    setIsLoading(true);
    try {
      console.log("🔍 회사 기준 카테고리 컬럼 조회 시작", { menuObjid });
      
      // 회사 기준 카테고리 컬럼 조회 (menuObjid는 선택사항)
      const url = menuObjid 
        ? `/table-management/menu/${menuObjid}/category-columns`
        : `/table-management/category-columns`;
      const response = await apiClient.get(url);

      console.log("✅ 메뉴별 카테고리 컬럼 API 응답:", {
        menuObjid,
        response: response.data,
      });

      let categoryColumns: any[] = [];

      if (response.data.success && response.data.data) {
        categoryColumns = response.data.data;
      } else if (Array.isArray(response.data)) {
        categoryColumns = response.data;
      } else {
        console.warn("⚠️ 예상하지 못한 API 응답 구조:", response.data);
        categoryColumns = [];
      }

      console.log("✅ 카테고리 컬럼 파싱 완료:", {
        count: categoryColumns.length,
        columns: categoryColumns.map((c: any) => ({
          table: c.tableName,
          column: c.columnName,
          label: c.columnLabel,
        })),
      });

      // 각 컬럼의 값 개수 가져오기
      const columnsWithCount = await Promise.all(
        categoryColumns.map(async (col: any) => {
          const colTable = col.tableName;
          const colName = col.columnName;
          const colLabel = col.columnLabel || colName;

          let valueCount = 0;
          try {
            const valuesResult = await getCategoryValues(colTable, colName, false, menuObjid);
            if (valuesResult.success && valuesResult.data) {
              valueCount = valuesResult.data.length;
            }
          } catch (error) {
            console.error(`항목 개수 조회 실패 (${colTable}.${colName}):`, error);
          }

          return {
            tableName: colTable,
            tableLabel: col.tableLabel || colTable, // 테이블 라벨 추가
            columnName: colName,
            columnLabel: colLabel,
            inputType: col.inputType,
            valueCount,
          };
        }),
      );

      // 결과가 0개면 tableName 기반으로 fallback
      if (columnsWithCount.length === 0 && tableName) {
        console.log("⚠️ menuObjid 기반 조회 결과 없음, tableName 기반으로 fallback:", tableName);
        await loadCategoryColumnsByTable();
        return;
      }

      setColumns(columnsWithCount);
      onColumnsLoaded?.(columnsWithCount);

      if (columnsWithCount.length > 0 && !selectedColumn) {
        const firstCol = columnsWithCount[0];
        onColumnSelect(`${firstCol.tableName}.${firstCol.columnName}`, firstCol.columnLabel, firstCol.tableName);
      }
    } catch (error) {
      console.error("❌ 카테고리 컬럼 조회 실패:", error);
      if (tableName) {
        await loadCategoryColumnsByTable();
        return;
      } else {
        setColumns([]);
        onColumnsLoaded?.([]);
      }
    }
    setIsLoading(false);
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12">
        <Loader2 className="text-primary h-6 w-6 animate-spin" />
      </div>
    );
  }

  if (columns.length === 0) {
    return (
      <div className="space-y-3">
        <h3 className="text-lg font-semibold">카테고리 컬럼</h3>
        <div className="bg-muted/50 rounded-lg border p-6 text-center">
          <FolderTree className="text-muted-foreground mx-auto h-8 w-8" />
          <p className="text-muted-foreground mt-2 text-sm">카테고리 타입 컬럼이 없습니다</p>
          <p className="text-muted-foreground mt-1 text-xs">
            테이블 타입 관리에서 컬럼의 입력 타입을 &apos;카테고리&apos;로 설정하세요
          </p>
        </div>
      </div>
    );
  }

  // 대시보드 모드: 테이블 단위 네비만 표시
  if (onTableSelect != null) {
    return (
      <div className="flex h-full flex-col">
        <div className="border-b p-2.5">
          <div className="relative">
            <Search className="text-muted-foreground absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2" />
            <Input
              type="text"
              placeholder="테이블 검색..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="h-8 border-0 bg-transparent pl-8 pr-8 text-xs shadow-none focus-visible:ring-0"
            />
            {searchQuery && (
              <button
                type="button"
                onClick={() => setSearchQuery("")}
                className="text-muted-foreground hover:text-foreground absolute right-2 top-1/2 -translate-y-1/2"
              >
                <X className="h-4 w-4" />
              </button>
            )}
          </div>
        </div>
        <div className="flex-1 space-y-0 overflow-y-auto">
          {filteredColumns.length === 0 && searchQuery ? (
            <div className="text-muted-foreground py-4 text-center text-xs">
              &apos;{searchQuery}&apos;에 대한 검색 결과가 없습니다
            </div>
          ) : null}
          {groupedColumns.map((group) => {
            const totalValues = group.columns.reduce((sum, c) => sum + (c.valueCount ?? 0), 0);
            const isActive = selectedTable === group.tableName;
            return (
              <button
                key={group.tableName}
                type="button"
                onClick={() => onTableSelect(group.tableName)}
                className={cn(
                  "flex w-full items-center gap-2 px-3 py-2.5 text-left transition-colors",
                  isActive
                    ? "border-l-[3px] border-primary bg-primary/5 font-bold text-primary"
                    : "hover:bg-muted/50",
                )}
              >
                <div
                  className="flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-[5px] bg-primary/20 text-primary"
                  aria-hidden
                >
                  <FolderTree className="h-3.5 w-3.5" />
                </div>
                <span className="min-w-0 flex-1 truncate text-xs font-medium">
                  {group.tableLabel || group.tableName}
                </span>
                <span className="bg-muted text-muted-foreground shrink-0 rounded-full px-1.5 py-0.5 text-[9px] font-bold">
                  {group.columns.length}
                </span>
              </button>
            );
          })}
        </div>
      </div>
    );
  }

  return (
    <div className="flex h-full flex-col">
      <div className="shrink-0 space-y-1 px-3 pt-3">
        <h3 className="text-lg font-semibold">카테고리 컬럼</h3>
        <p className="text-muted-foreground text-xs">관리할 카테고리 컬럼을 선택하세요</p>
      </div>

      <div className="shrink-0 px-3 pt-3">
        <div className="relative">
          <Search className="text-muted-foreground absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2" />
          <Input
            type="text"
            placeholder="컬럼 검색..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="h-8 pl-8 pr-8 text-xs"
          />
          {searchQuery && (
            <button
              type="button"
              onClick={() => setSearchQuery("")}
              className="text-muted-foreground hover:text-foreground absolute right-2 top-1/2 -translate-y-1/2"
            >
              <X className="h-4 w-4" />
            </button>
          )}
        </div>
      </div>

      <div className="flex-1 min-h-0 overflow-y-auto space-y-1 px-3 py-3">
        {filteredColumns.length === 0 && searchQuery ? (
          <div className="text-muted-foreground py-4 text-center text-xs">
            &apos;{searchQuery}&apos;에 대한 검색 결과가 없습니다
          </div>
        ) : null}
        {groupedColumns.map((group) => {
          const isExpanded = expandedGroups.has(group.tableName);
          const totalValues = group.columns.reduce((sum, c) => sum + (c.valueCount ?? 0), 0);
          const hasSelectedInGroup = group.columns.some(
            (c) => selectedColumn === `${c.tableName}.${c.columnName}`,
          );

          // 그룹이 1개뿐이면 드롭다운 없이 바로 표시
          if (groupedColumns.length <= 1) {
            return (
              <div key={group.tableName} className="space-y-1.5">
                {group.columns.map((column) => {
                  const uniqueKey = `${column.tableName}.${column.columnName}`;
                  const isSelected = selectedColumn === uniqueKey;
                  return (
                    <div
                      key={uniqueKey}
                      onClick={() => onColumnSelect(uniqueKey, column.columnLabel || column.columnName, column.tableName)}
                      className={`cursor-pointer rounded-lg border px-4 py-2 transition-all ${
                        isSelected ? "border-primary bg-primary/10 shadow-sm" : "hover:bg-muted/50"
                      }`}
                    >
                      <div className="flex items-center gap-2">
                        <FolderTree
                          className={`h-4 w-4 ${isSelected ? "text-primary" : "text-muted-foreground"}`}
                        />
                        <div className="flex-1">
                          <h4 className="text-sm font-semibold">{column.columnLabel || column.columnName}</h4>
                          <p className="text-muted-foreground text-xs">{column.tableLabel || column.tableName}</p>
                        </div>
                        <span className="text-muted-foreground text-xs font-medium">
                          {column.valueCount !== undefined ? `${column.valueCount}개` : "..."}
                        </span>
                      </div>
                    </div>
                  );
                })}
              </div>
            );
          }

          return (
            <div key={group.tableName} className="overflow-hidden rounded-lg border">
              {/* 드롭다운 헤더 */}
              <button
                type="button"
                onClick={() => {
                  setExpandedGroups((prev) => {
                    const next = new Set(prev);
                    if (next.has(group.tableName)) {
                      next.delete(group.tableName);
                    } else {
                      next.add(group.tableName);
                    }
                    return next;
                  });
                }}
                className={`flex w-full items-center gap-2 px-3 py-2 text-left transition-colors ${
                  hasSelectedInGroup ? "bg-primary/5" : "hover:bg-muted/50"
                }`}
              >
                <ChevronRight
                  className={`h-3.5 w-3.5 shrink-0 transition-transform duration-200 ${
                    isExpanded ? "rotate-90" : ""
                  } ${hasSelectedInGroup ? "text-primary" : "text-muted-foreground"}`}
                />
                <span className={`flex-1 text-xs font-semibold ${hasSelectedInGroup ? "text-primary" : ""}`}>
                  {group.tableLabel}
                </span>
                <span className="text-muted-foreground text-[10px]">
                  {group.columns.length}개 컬럼 / {totalValues}개 값
                </span>
              </button>

              {/* 펼쳐진 컬럼 목록 */}
              {isExpanded && (
                <div className="space-y-1 border-t px-2 py-2">
                  {group.columns.map((column) => {
                    const uniqueKey = `${column.tableName}.${column.columnName}`;
                    const isSelected = selectedColumn === uniqueKey;
                    return (
                      <div
                        key={uniqueKey}
                        onClick={() => onColumnSelect(uniqueKey, column.columnLabel || column.columnName, column.tableName)}
                        className={`cursor-pointer rounded-md px-3 py-1.5 transition-all ${
                          isSelected ? "bg-primary/10 font-semibold text-primary" : "hover:bg-muted/50"
                        }`}
                      >
                        <div className="flex items-center gap-2">
                          <FolderTree
                            className={`h-3.5 w-3.5 ${isSelected ? "text-primary" : "text-muted-foreground"}`}
                          />
                          <span className="flex-1 text-xs">{column.columnLabel || column.columnName}</span>
                          <span className="text-muted-foreground text-[10px]">
                            {column.valueCount !== undefined ? `${column.valueCount}개` : "..."}
                          </span>
                        </div>
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
