"use client";

/**
 * UnifiedRepeater 컴포넌트
 *
 * 렌더링 모드:
 * - inline: 현재 테이블 컬럼 직접 입력
 * - modal: 엔티티 선택 (FK 저장) + 추가 입력 컬럼
 * 
 * RepeaterTable 및 ItemSelectionModal 재사용
 */

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Plus, Columns } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  UnifiedRepeaterConfig,
  UnifiedRepeaterProps,
  RepeaterColumnConfig as UnifiedColumnConfig,
  DEFAULT_REPEATER_CONFIG,
} from "@/types/unified-repeater";
import { apiClient } from "@/lib/api/client";

// modal-repeater-table 컴포넌트 재사용
import { RepeaterTable } from "@/lib/registry/components/modal-repeater-table/RepeaterTable";
import { ItemSelectionModal } from "@/lib/registry/components/modal-repeater-table/ItemSelectionModal";
import { RepeaterColumnConfig } from "@/lib/registry/components/modal-repeater-table/types";

// 전역 UnifiedRepeater 등록 (buttonActions에서 사용)
declare global {
  interface Window {
    __unifiedRepeaterInstances?: Set<string>;
  }
}

export const UnifiedRepeater: React.FC<UnifiedRepeaterProps> = ({
  config: propConfig,
  parentId,
  data: initialData,
  onDataChange,
  onRowClick,
  className,
}) => {
  // 설정 병합
  const config: UnifiedRepeaterConfig = useMemo(
    () => ({
      ...DEFAULT_REPEATER_CONFIG,
      ...propConfig,
      dataSource: { ...DEFAULT_REPEATER_CONFIG.dataSource, ...propConfig.dataSource },
      features: { ...DEFAULT_REPEATER_CONFIG.features, ...propConfig.features },
      modal: { ...DEFAULT_REPEATER_CONFIG.modal, ...propConfig.modal },
    }),
    [propConfig],
  );

  // 상태
  const [data, setData] = useState<any[]>(initialData || []);
  const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set());
  const [modalOpen, setModalOpen] = useState(false);
  const [equalizeWidthsTrigger, setEqualizeWidthsTrigger] = useState(0);
  
  // 소스 테이블 컬럼 라벨 매핑
  const [sourceColumnLabels, setSourceColumnLabels] = useState<Record<string, string>>({});
  
  // 현재 테이블 컬럼 정보 (inputType 매핑용)
  const [currentTableColumnInfo, setCurrentTableColumnInfo] = useState<Record<string, any>>({});
  
  // 동적 데이터 소스 상태
  const [activeDataSources, setActiveDataSources] = useState<Record<string, string>>({});

  const isModalMode = config.renderMode === "modal";

  // 전역 리피터 등록
  useEffect(() => {
    const tableName = config.dataSource?.tableName;
    if (tableName) {
      if (!window.__unifiedRepeaterInstances) {
        window.__unifiedRepeaterInstances = new Set();
      }
      window.__unifiedRepeaterInstances.add(tableName);
    }

    return () => {
      if (tableName && window.__unifiedRepeaterInstances) {
        window.__unifiedRepeaterInstances.delete(tableName);
      }
    };
  }, [config.dataSource?.tableName]);

  // 저장 이벤트 리스너
  useEffect(() => {
    const handleSaveEvent = async (event: CustomEvent) => {
      const tableName = config.dataSource?.tableName;
      const eventParentId = event.detail?.parentId;
      const mainFormData = event.detail?.mainFormData;
      
      if (!tableName || data.length === 0) {
        return;
      }

      try {
        // 테이블 유효 컬럼 조회
        let validColumns: Set<string> = new Set();
        try {
          const columnsResponse = await apiClient.get(`/table-management/tables/${tableName}/columns`);
          const columns = columnsResponse.data?.data?.columns || columnsResponse.data?.columns || columnsResponse.data || [];
          validColumns = new Set(columns.map((col: any) => col.columnName || col.column_name || col.name));
        } catch {
          console.warn("테이블 컬럼 정보 조회 실패");
        }
        
        for (let i = 0; i < data.length; i++) {
          const row = data[i];
          
          // 내부 필드 제거
          const cleanRow = Object.fromEntries(
            Object.entries(row).filter(([key]) => !key.startsWith("_"))
          );

          // 메인 폼 데이터 병합
          const { id: _mainId, ...mainFormDataWithoutId } = mainFormData || {};
          const mergedData = {
            ...mainFormDataWithoutId,
            ...cleanRow,
          };

          // 유효하지 않은 컬럼 제거
          const filteredData: Record<string, any> = {};
          for (const [key, value] of Object.entries(mergedData)) {
            if (validColumns.size === 0 || validColumns.has(key)) {
              filteredData[key] = value;
            }
          }
          
          await apiClient.post(`/table-management/tables/${tableName}/add`, filteredData);
        }

        console.log("UnifiedRepeater 저장 완료:", data.length, "건");
      } catch (error) {
        console.error("UnifiedRepeater 저장 실패:", error);
        throw error;
      }
    };

    window.addEventListener("repeaterSave" as any, handleSaveEvent);
    return () => {
      window.removeEventListener("repeaterSave" as any, handleSaveEvent);
    };
  }, [data, config.dataSource?.tableName, parentId]);

  // 현재 테이블 컬럼 정보 로드
  useEffect(() => {
    const loadCurrentTableColumnInfo = async () => {
      const tableName = config.dataSource?.tableName;
      if (!tableName) return;

      try {
        const response = await apiClient.get(`/table-management/tables/${tableName}/columns`);
        const columns = response.data?.data?.columns || response.data?.columns || response.data || [];
        
        const columnMap: Record<string, any> = {};
        columns.forEach((col: any) => {
          const name = col.columnName || col.column_name || col.name;
          columnMap[name] = {
            inputType: col.inputType || col.input_type || col.webType || "text",
            displayName: col.displayName || col.display_name || col.label || name,
            detailSettings: col.detailSettings || col.detail_settings,
          };
        });
        setCurrentTableColumnInfo(columnMap);
      } catch (error) {
        console.error("컬럼 정보 로드 실패:", error);
      }
    };
    loadCurrentTableColumnInfo();
  }, [config.dataSource?.tableName]);

  // 소스 테이블 컬럼 라벨 로드 (modal 모드)
  useEffect(() => {
    const loadSourceColumnLabels = async () => {
      const sourceTable = config.dataSource?.sourceTable;
      if (!isModalMode || !sourceTable) return;

      try {
        const response = await apiClient.get(`/table-management/tables/${sourceTable}/columns`);
        const columns = response.data?.data?.columns || response.data?.columns || response.data || [];
        
        const labels: Record<string, string> = {};
        columns.forEach((col: any) => {
          const name = col.columnName || col.column_name || col.name;
          labels[name] = col.displayName || col.display_name || col.label || name;
        });
        setSourceColumnLabels(labels);
      } catch (error) {
        console.error("소스 컬럼 라벨 로드 실패:", error);
      }
    };
    loadSourceColumnLabels();
  }, [config.dataSource?.sourceTable, isModalMode]);

  // UnifiedColumnConfig → RepeaterColumnConfig 변환
  const repeaterColumns: RepeaterColumnConfig[] = useMemo(() => {
    const displayColumns: RepeaterColumnConfig[] = [];
    
    // 모달 표시 컬럼 추가 (읽기 전용)
    if (isModalMode && config.modal?.sourceDisplayColumns) {
      config.modal.sourceDisplayColumns.forEach((col) => {
        const key = typeof col === "string" ? col : col.key;
        const label = typeof col === "string" ? sourceColumnLabels[col] || col : col.label || sourceColumnLabels[key] || key;
        
        if (key && key !== "none") {
          displayColumns.push({
            field: `_display_${key}`,
            label,
            type: "text",
            editable: false,
            calculated: true,
          });
        }
      });
    }
    
    // 입력 컬럼 추가
    const inputColumns = config.columns.map((col: UnifiedColumnConfig): RepeaterColumnConfig => {
      const colInfo = currentTableColumnInfo[col.key];
      const inputType = col.inputType || colInfo?.inputType || "text";
      
      let type: "text" | "number" | "date" | "select" = "text";
      if (inputType === "number" || inputType === "decimal") type = "number";
      else if (inputType === "date" || inputType === "datetime") type = "date";
      else if (inputType === "code") type = "select";
      
      return {
        field: col.key,
        label: col.title || colInfo?.displayName || col.key,
        type,
        editable: col.editable !== false,
        width: col.width === "auto" ? undefined : col.width,
        required: false,
      };
    });
    
    return [...displayColumns, ...inputColumns];
  }, [config.columns, config.modal?.sourceDisplayColumns, isModalMode, sourceColumnLabels, currentTableColumnInfo]);

  // 데이터 변경 핸들러
  const handleDataChange = useCallback((newData: any[]) => {
    setData(newData);
    onDataChange?.(newData);
  }, [onDataChange]);

  // 행 변경 핸들러
  const handleRowChange = useCallback((index: number, newRow: any) => {
    const newData = [...data];
    newData[index] = newRow;
    setData(newData);
    onDataChange?.(newData);
  }, [data, onDataChange]);

  // 행 삭제 핸들러
  const handleRowDelete = useCallback((index: number) => {
    const newData = data.filter((_, i) => i !== index);
    setData(newData);
    onDataChange?.(newData);
    
    // 선택 상태 업데이트
    const newSelected = new Set<number>();
    selectedRows.forEach((i) => {
      if (i < index) newSelected.add(i);
      else if (i > index) newSelected.add(i - 1);
    });
    setSelectedRows(newSelected);
  }, [data, selectedRows, onDataChange]);

  // 일괄 삭제 핸들러
  const handleBulkDelete = useCallback(() => {
    const newData = data.filter((_, index) => !selectedRows.has(index));
    setData(newData);
    onDataChange?.(newData);
    setSelectedRows(new Set());
  }, [data, selectedRows, onDataChange]);

  // 행 추가 (inline 모드)
  const handleAddRow = useCallback(() => {
    if (isModalMode) {
      setModalOpen(true);
    } else {
      const newRow: any = { _id: `new_${Date.now()}` };
      config.columns.forEach((col) => {
        newRow[col.key] = "";
      });
      const newData = [...data, newRow];
      setData(newData);
      onDataChange?.(newData);
    }
  }, [isModalMode, config.columns, data, onDataChange]);

  // 모달에서 항목 선택
  const handleSelectItems = useCallback((items: Record<string, unknown>[]) => {
    const fkColumn = config.dataSource?.foreignKey;
    const refKey = config.dataSource?.referenceKey || "id";
    
    const newRows = items.map((item) => {
      const row: any = { _id: `new_${Date.now()}_${Math.random()}` };
      
      // FK 값 저장
      if (fkColumn && item[refKey]) {
        row[fkColumn] = item[refKey];
      }
      
      // 표시용 데이터 저장
      if (config.modal?.sourceDisplayColumns) {
        config.modal.sourceDisplayColumns.forEach((col) => {
          const key = typeof col === "string" ? col : col.key;
          if (key && key !== "none") {
            row[`_display_${key}`] = item[key] || "";
          }
        });
      }
      
      // 입력 컬럼 초기화
      config.columns.forEach((col) => {
        if (row[col.key] === undefined) {
          row[col.key] = "";
        }
      });
      
      return row;
    });
    
    const newData = [...data, ...newRows];
    setData(newData);
    onDataChange?.(newData);
    setModalOpen(false);
  }, [config.dataSource?.foreignKey, config.dataSource?.referenceKey, config.modal?.sourceDisplayColumns, config.columns, data, onDataChange]);

  // 소스 컬럼 목록 (모달용)
  const sourceColumns = useMemo(() => {
    if (!config.modal?.sourceDisplayColumns) return [];
    return config.modal.sourceDisplayColumns
      .map((col) => typeof col === "string" ? col : col.key)
      .filter((key) => key && key !== "none");
  }, [config.modal?.sourceDisplayColumns]);

  return (
    <div className={cn("space-y-4", className)}>
      {/* 헤더 영역 */}
      <div className="flex justify-between items-center">
        <div className="flex items-center gap-2">
          <span className="text-sm text-muted-foreground">
            {data.length > 0 && `${data.length}개 항목`}
            {selectedRows.size > 0 && ` (${selectedRows.size}개 선택됨)`}
          </span>
          {repeaterColumns.length > 0 && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => setEqualizeWidthsTrigger((prev) => prev + 1)}
              className="h-7 text-xs px-2"
              title="컬럼 너비 균등 분배"
            >
              <Columns className="h-3.5 w-3.5 mr-1" />
              균등 분배
            </Button>
          )}
        </div>
        <div className="flex gap-2">
          {selectedRows.size > 0 && (
            <Button
              variant="destructive"
              onClick={handleBulkDelete}
              className="h-8 text-xs sm:h-10 sm:text-sm"
            >
              선택 삭제 ({selectedRows.size})
            </Button>
          )}
          <Button
            onClick={handleAddRow}
            className="h-8 text-xs sm:h-10 sm:text-sm"
          >
            <Plus className="h-4 w-4 mr-2" />
            {isModalMode ? (config.modal?.buttonText || "검색") : "추가"}
          </Button>
        </div>
      </div>

      {/* Repeater 테이블 */}
      <RepeaterTable
        columns={repeaterColumns}
        data={data}
        onDataChange={handleDataChange}
        onRowChange={handleRowChange}
        onRowDelete={handleRowDelete}
        activeDataSources={activeDataSources}
        onDataSourceChange={(field, optionId) => {
          setActiveDataSources((prev) => ({ ...prev, [field]: optionId }));
        }}
        selectedRows={selectedRows}
        onSelectionChange={setSelectedRows}
        equalizeWidthsTrigger={equalizeWidthsTrigger}
      />

      {/* 항목 선택 모달 (modal 모드) */}
      {isModalMode && (
        <ItemSelectionModal
          open={modalOpen}
          onOpenChange={setModalOpen}
          sourceTable={config.dataSource?.sourceTable || ""}
          sourceColumns={sourceColumns}
          sourceSearchFields={config.modal?.searchFields || sourceColumns}
          multiSelect={config.features?.multiSelect ?? true}
          modalTitle={config.modal?.title || "항목 검색"}
          alreadySelected={data}
          uniqueField={config.dataSource?.referenceKey || "id"}
          onSelect={handleSelectItems}
          columnLabels={sourceColumnLabels}
        />
      )}
    </div>
  );
};

UnifiedRepeater.displayName = "UnifiedRepeater";

export default UnifiedRepeater;
