/**
 * 다국어 라벨 추출 유틸리티
 * 화면 디자이너의 컴포넌트에서 다국어 처리가 필요한 라벨을 추출합니다.
 */

import { ComponentData } from "@/types/screen";

// 추출된 라벨 타입
export interface ExtractedLabel {
  id: string;
  componentId: string;
  label: string;
  type: "label" | "title" | "button" | "placeholder" | "column" | "filter" | "field" | "tab" | "action";
  parentType?: string;
  parentLabel?: string;
  langKeyId?: number;
  langKey?: string;
}

// 입력 폼 컴포넌트인지 확인
const INPUT_COMPONENT_TYPES = new Set([
  "text-field",
  "number-field",
  "date-field",
  "datetime-field",
  "select-field",
  "checkbox-field",
  "radio-field",
  "textarea-field",
  "file-field",
  "email-field",
  "tel-field",
  "password-field",
  "entity-field",
  "code-field",
  "category-field",
  "input-field",
  "widget",
]);

const isInputComponent = (comp: any): boolean => {
  const compType = comp.componentType || comp.type;
  if (INPUT_COMPONENT_TYPES.has(compType)) return true;
  if (compType === "widget" && comp.widgetType) return true;
  if (comp.inputType || comp.webType) return true;
  return false;
};

// 컬럼 라벨 맵 타입
export type ColumnLabelMap = Record<string, Record<string, string>>;

/**
 * 컴포넌트에서 다국어 라벨 추출
 * @param components 컴포넌트 배열
 * @param columnLabelMap 테이블별 컬럼 라벨 맵 (선택사항)
 * @returns 추출된 라벨 배열
 */
export function extractMultilangLabels(
  components: ComponentData[],
  columnLabelMap: ColumnLabelMap = {}
): ExtractedLabel[] {
  const labels: ExtractedLabel[] = [];
  const addedLabels = new Set<string>();

  const addLabel = (
    componentId: string,
    label: string,
    type: ExtractedLabel["type"],
    parentType?: string,
    parentLabel?: string,
    langKeyId?: number,
    langKey?: string
  ) => {
    const key = `${componentId}_${type}_${label}`;
    if (label && label.trim() && !addedLabels.has(key)) {
      addedLabels.add(key);
      labels.push({
        id: key,
        componentId,
        label: label.trim(),
        type,
        parentType,
        parentLabel,
        langKeyId,
        langKey,
      });
    }
  };

  const extractFromComponent = (comp: ComponentData, parentType?: string, parentLabel?: string) => {
    const anyComp = comp as any;
    const config = anyComp.componentConfig || anyComp.config;
    const compType = anyComp.componentType || anyComp.type;
    const compLabel = anyComp.label || anyComp.title || compType;

    // 1. 기본 라벨 - 입력 폼 컴포넌트인 경우에만 추출
    if (isInputComponent(anyComp)) {
      if (anyComp.label && typeof anyComp.label === "string") {
        addLabel(comp.id, anyComp.label, "label", parentType, parentLabel, anyComp.langKeyId, anyComp.langKey);
      }
    }

    // 2. 제목
    if (anyComp.title && typeof anyComp.title === "string") {
      addLabel(comp.id, anyComp.title, "title", parentType, parentLabel);
    }

    // 3. 버튼 텍스트 (componentId에 _button 접미사 추가하여 라벨과 구분)
    if (config?.text && typeof config.text === "string") {
      addLabel(
        `${comp.id}_button`,
        config.text,
        "button",
        parentType,
        parentLabel,
        config.langKeyId,
        config.langKey
      );
    }

    // 4. placeholder
    if (anyComp.placeholder && typeof anyComp.placeholder === "string") {
      addLabel(comp.id, anyComp.placeholder, "placeholder", parentType, parentLabel);
    }

    // 5. 테이블 컬럼 - columnLabelMap에서 한글 라벨 조회
    const tableName = config?.selectedTable || config?.tableName || config?.table || anyComp.tableName;
    if (config?.columns && Array.isArray(config.columns)) {
      config.columns.forEach((col: any, index: number) => {
        const colName = col.columnName || col.field || col.name;
        // columnLabelMap에서 한글 라벨 조회, 없으면 displayName 사용
        const colLabel = columnLabelMap[tableName]?.[colName] || col.displayName || col.label || colName;
        
        if (colLabel && typeof colLabel === "string") {
          addLabel(
            `${comp.id}_col_${index}`,
            colLabel,
            "column",
            compType,
            compLabel,
            col.langKeyId,
            col.langKey
          );
        }
      });
    }

    // 6. 분할 패널 제목 및 컬럼 - columnLabelMap에서 한글 라벨 조회
    // 6-1. 좌측 패널 제목
    if (config?.leftPanel?.title && typeof config.leftPanel.title === "string") {
      addLabel(
        `${comp.id}_left_title`,
        config.leftPanel.title,
        "title",
        compType,
        `${compLabel} (좌측)`,
        config.leftPanel.langKeyId,
        config.leftPanel.langKey
      );
    }
    // 6-2. 우측 패널 제목
    if (config?.rightPanel?.title && typeof config.rightPanel.title === "string") {
      addLabel(
        `${comp.id}_right_title`,
        config.rightPanel.title,
        "title",
        compType,
        `${compLabel} (우측)`,
        config.rightPanel.langKeyId,
        config.rightPanel.langKey
      );
    }
    // 6-3. 좌측 패널 컬럼
    const leftTableName = config?.leftPanel?.selectedTable || config?.leftPanel?.tableName || tableName;
    if (config?.leftPanel?.columns && Array.isArray(config.leftPanel.columns)) {
      config.leftPanel.columns.forEach((col: any, index: number) => {
        const colName = col.columnName || col.field || col.name;
        const colLabel = columnLabelMap[leftTableName]?.[colName] || col.displayName || col.label || colName;
        if (colLabel && typeof colLabel === "string") {
          addLabel(
            `${comp.id}_left_col_${index}`,
            colLabel,
            "column",
            compType,
            `${compLabel} (좌측)`,
            col.langKeyId,
            col.langKey
          );
        }
      });
    }
    const rightTableName = config?.rightPanel?.selectedTable || config?.rightPanel?.tableName || tableName;
    if (config?.rightPanel?.columns && Array.isArray(config.rightPanel.columns)) {
      config.rightPanel.columns.forEach((col: any, index: number) => {
        const colName = col.columnName || col.field || col.name;
        const colLabel = columnLabelMap[rightTableName]?.[colName] || col.displayName || col.label || colName;
        if (colLabel && typeof colLabel === "string") {
          addLabel(
            `${comp.id}_right_col_${index}`,
            colLabel,
            "column",
            compType,
            `${compLabel} (우측)`,
            col.langKeyId,
            col.langKey
          );
        }
      });
    }

    // 6-5. 추가 탭 (additionalTabs) 제목 및 컬럼 - rightPanel.additionalTabs 확인
    const additionalTabs = config?.rightPanel?.additionalTabs || config?.additionalTabs;
    if (additionalTabs && Array.isArray(additionalTabs)) {
      additionalTabs.forEach((tab: any, tabIndex: number) => {
        // 탭 라벨
        if (tab.label && typeof tab.label === "string") {
          addLabel(
            `${comp.id}_addtab_${tabIndex}_label`,
            tab.label,
            "tab",
            compType,
            compLabel,
            tab.langKeyId,
            tab.langKey
          );
        }
        // 탭 제목
        if (tab.title && typeof tab.title === "string") {
          addLabel(
            `${comp.id}_addtab_${tabIndex}_title`,
            tab.title,
            "title",
            compType,
            `${compLabel} (탭: ${tab.label || tabIndex})`,
            tab.titleLangKeyId,
            tab.titleLangKey
          );
        }
        // 탭 컬럼
        const tabTableName = tab.tableName || tab.selectedTable || rightTableName;
        if (tab.columns && Array.isArray(tab.columns)) {
          tab.columns.forEach((col: any, colIndex: number) => {
            const colName = col.columnName || col.field || col.name;
            const colLabel = columnLabelMap[tabTableName]?.[colName] || col.displayName || col.label || colName;
            if (colLabel && typeof colLabel === "string") {
              addLabel(
                `${comp.id}_addtab_${tabIndex}_col_${colIndex}`,
                colLabel,
                "column",
                compType,
                `${compLabel} (탭: ${tab.label || tabIndex})`,
                col.langKeyId,
                col.langKey
              );
            }
          });
        }
      });
    }

    // 7. 검색 필터
    if (config?.filter?.filters && Array.isArray(config.filter.filters)) {
      config.filter.filters.forEach((filter: any, index: number) => {
        if (filter.label && typeof filter.label === "string") {
          addLabel(
            `${comp.id}_filter_${index}`,
            filter.label,
            "filter",
            compType,
            compLabel,
            filter.langKeyId,
            filter.langKey
          );
        }
      });
    }

    // 8. 폼 필드
    if (config?.fields && Array.isArray(config.fields)) {
      config.fields.forEach((field: any, index: number) => {
        if (field.label && typeof field.label === "string") {
          addLabel(
            `${comp.id}_field_${index}`,
            field.label,
            "field",
            compType,
            compLabel,
            field.langKeyId,
            field.langKey
          );
        }
      });
    }

    // 9. 탭
    if (config?.tabs && Array.isArray(config.tabs)) {
      config.tabs.forEach((tab: any, index: number) => {
        if (tab.label && typeof tab.label === "string") {
          addLabel(
            `${comp.id}_tab_${index}`,
            tab.label,
            "tab",
            compType,
            compLabel,
            tab.langKeyId,
            tab.langKey
          );
        }
      });
    }

    // 10. 액션 버튼
    if (config?.actions?.actions && Array.isArray(config.actions.actions)) {
      config.actions.actions.forEach((action: any, index: number) => {
        if (action.label && typeof action.label === "string") {
          addLabel(
            `${comp.id}_action_${index}`,
            action.label,
            "action",
            compType,
            compLabel,
            action.langKeyId,
            action.langKey
          );
        }
      });
    }

    // 11. 집계 위젯 (aggregation-widget) 항목 라벨
    if (compType === "aggregation-widget" && config?.items && Array.isArray(config.items)) {
      config.items.forEach((item: any, index: number) => {
        if (item.columnLabel && typeof item.columnLabel === "string") {
          addLabel(
            `${comp.id}_agg_${item.id || index}`,
            item.columnLabel,
            "label",
            compType,
            compLabel,
            item.labelLangKeyId,
            item.labelLangKey
          );
        }
      });
    }

    // 자식 컴포넌트 재귀 탐색
    if (anyComp.children && Array.isArray(anyComp.children)) {
      anyComp.children.forEach((child: ComponentData) => {
        extractFromComponent(child, compType, compLabel);
      });
    }
  };

  components.forEach((comp) => extractFromComponent(comp));
  return labels;
}

/**
 * 컴포넌트에서 테이블명 추출
 * @param components 컴포넌트 배열
 * @returns 테이블명 Set
 */
export function extractTableNames(components: ComponentData[]): Set<string> {
  const tableNames = new Set<string>();
  
  const extractTableName = (comp: any) => {
    const config = comp.componentConfig;
    
    // 1. 컴포넌트 직접 tableName
    if (comp.tableName) tableNames.add(comp.tableName);
    
    // 2. componentConfig 직접 tableName
    if (config?.tableName) tableNames.add(config.tableName);
    
    // 3. 테이블 리스트 컴포넌트 - selectedTable (주요!)
    if (config?.selectedTable) tableNames.add(config.selectedTable);
    
    // 4. 테이블 리스트 컴포넌트 - table 속성
    if (config?.table) tableNames.add(config.table);
    
    // 5. 분할 패널의 leftPanel/rightPanel
    if (config?.leftPanel?.tableName) tableNames.add(config.leftPanel.tableName);
    if (config?.rightPanel?.tableName) tableNames.add(config.rightPanel.tableName);
    if (config?.leftPanel?.table) tableNames.add(config.leftPanel.table);
    if (config?.rightPanel?.table) tableNames.add(config.rightPanel.table);
    if (config?.leftPanel?.selectedTable) tableNames.add(config.leftPanel.selectedTable);
    if (config?.rightPanel?.selectedTable) tableNames.add(config.rightPanel.selectedTable);
    
    // 6. 검색 필터의 tableName
    if (config?.filter?.tableName) tableNames.add(config.filter.tableName);
    
    // 7. properties 안의 tableName
    if (comp.properties?.tableName) tableNames.add(comp.properties.tableName);
    if (comp.properties?.selectedTable) tableNames.add(comp.properties.selectedTable);
    
    // 자식 컴포넌트 탐색
    if (comp.children && Array.isArray(comp.children)) {
      comp.children.forEach(extractTableName);
    }
  };
  
  components.forEach(extractTableName);
  return tableNames;
}

/**
 * 다국어 키 매핑 결과를 컴포넌트에 적용
 * @param components 원본 컴포넌트 배열
 * @param mappings 다국어 키 매핑 결과 [{componentId, keyId, langKey}]
 * @returns 업데이트된 컴포넌트 배열
 */
export function applyMultilangMappings(
  components: ComponentData[],
  mappings: Array<{ componentId: string; keyId: number; langKey: string }>
): ComponentData[] {
  // 매핑을 빠르게 찾기 위한 맵 생성
  const mappingMap = new Map(mappings.map((m) => [m.componentId, m]));

  const updateComponent = (comp: ComponentData): ComponentData => {
    const anyComp = comp as any;
    const config = anyComp.componentConfig || anyComp.config;
    let updated = { ...comp } as any;

    // 기본 컴포넌트 라벨 매핑 확인
    const labelMapping = mappingMap.get(comp.id);
    if (labelMapping) {
      updated.langKeyId = labelMapping.keyId;
      updated.langKey = labelMapping.langKey;
    }

    // 버튼 텍스트 매핑 (componentId_button 형식으로 조회)
    const buttonMapping = mappingMap.get(`${comp.id}_button`);
    if (buttonMapping && config?.text) {
      updated.componentConfig = {
        ...updated.componentConfig,
        langKeyId: buttonMapping.keyId,
        langKey: buttonMapping.langKey,
      };
    }

    // 컬럼 매핑
    if (config?.columns && Array.isArray(config.columns)) {
      const updatedColumns = config.columns.map((col: any, index: number) => {
        const colMapping = mappingMap.get(`${comp.id}_col_${index}`);
        if (colMapping) {
          return { ...col, langKeyId: colMapping.keyId, langKey: colMapping.langKey };
        }
        return col;
      });
      updated.componentConfig = { ...config, columns: updatedColumns };
    }

    // 분할 패널 좌측 제목 매핑
    const leftTitleMapping = mappingMap.get(`${comp.id}_left_title`);
    if (leftTitleMapping && config?.leftPanel?.title) {
      updated.componentConfig = {
        ...updated.componentConfig,
        leftPanel: {
          ...updated.componentConfig?.leftPanel,
          langKeyId: leftTitleMapping.keyId,
          langKey: leftTitleMapping.langKey,
        },
      };
    }

    // 분할 패널 우측 제목 매핑
    const rightTitleMapping = mappingMap.get(`${comp.id}_right_title`);
    if (rightTitleMapping && config?.rightPanel?.title) {
      updated.componentConfig = {
        ...updated.componentConfig,
        rightPanel: {
          ...updated.componentConfig?.rightPanel,
          langKeyId: rightTitleMapping.keyId,
          langKey: rightTitleMapping.langKey,
        },
      };
    }

    // 분할 패널 좌측 컬럼 매핑 (이미 업데이트된 leftPanel 사용)
    const currentLeftPanel = updated.componentConfig?.leftPanel || config?.leftPanel;
    if (currentLeftPanel?.columns && Array.isArray(currentLeftPanel.columns)) {
      const updatedLeftColumns = currentLeftPanel.columns.map((col: any, index: number) => {
        const colMapping = mappingMap.get(`${comp.id}_left_col_${index}`);
        if (colMapping) {
          return { ...col, langKeyId: colMapping.keyId, langKey: colMapping.langKey };
        }
        return col;
      });
      updated.componentConfig = {
        ...updated.componentConfig,
        leftPanel: { ...currentLeftPanel, columns: updatedLeftColumns },
      };
    }

    // 분할 패널 우측 컬럼 매핑 (이미 업데이트된 rightPanel 사용)
    const currentRightPanel = updated.componentConfig?.rightPanel || config?.rightPanel;
    if (currentRightPanel?.columns && Array.isArray(currentRightPanel.columns)) {
      const updatedRightColumns = currentRightPanel.columns.map((col: any, index: number) => {
        const colMapping = mappingMap.get(`${comp.id}_right_col_${index}`);
        if (colMapping) {
          return { ...col, langKeyId: colMapping.keyId, langKey: colMapping.langKey };
        }
        return col;
      });
      updated.componentConfig = {
        ...updated.componentConfig,
        rightPanel: { ...currentRightPanel, columns: updatedRightColumns },
      };
    }

    // 필터 매핑
    if (config?.filter?.filters && Array.isArray(config.filter.filters)) {
      const updatedFilters = config.filter.filters.map((filter: any, index: number) => {
        const filterMapping = mappingMap.get(`${comp.id}_filter_${index}`);
        if (filterMapping) {
          return { ...filter, langKeyId: filterMapping.keyId, langKey: filterMapping.langKey };
        }
        return filter;
      });
      updated.componentConfig = {
        ...updated.componentConfig,
        filter: { ...config.filter, filters: updatedFilters },
      };
    }

    // 폼 필드 매핑
    if (config?.fields && Array.isArray(config.fields)) {
      const updatedFields = config.fields.map((field: any, index: number) => {
        const fieldMapping = mappingMap.get(`${comp.id}_field_${index}`);
        if (fieldMapping) {
          return { ...field, langKeyId: fieldMapping.keyId, langKey: fieldMapping.langKey };
        }
        return field;
      });
      updated.componentConfig = { ...updated.componentConfig, fields: updatedFields };
    }

    // 탭 매핑
    if (config?.tabs && Array.isArray(config.tabs)) {
      const updatedTabs = config.tabs.map((tab: any, index: number) => {
        const tabMapping = mappingMap.get(`${comp.id}_tab_${index}`);
        if (tabMapping) {
          return { ...tab, langKeyId: tabMapping.keyId, langKey: tabMapping.langKey };
        }
        return tab;
      });
      updated.componentConfig = { ...updated.componentConfig, tabs: updatedTabs };
    }

    // 추가 탭 (additionalTabs) 매핑 - rightPanel.additionalTabs 또는 additionalTabs 확인
    const currentRightPanelForAddTabs = updated.componentConfig?.rightPanel || config?.rightPanel;
    const configAdditionalTabs = currentRightPanelForAddTabs?.additionalTabs || config?.additionalTabs;
    if (configAdditionalTabs && Array.isArray(configAdditionalTabs)) {
      const updatedAdditionalTabs = configAdditionalTabs.map((tab: any, tabIndex: number) => {
        let updatedTab = { ...tab };

        // 탭 라벨 매핑
        const labelMapping = mappingMap.get(`${comp.id}_addtab_${tabIndex}_label`);
        if (labelMapping) {
          updatedTab.langKeyId = labelMapping.keyId;
          updatedTab.langKey = labelMapping.langKey;
        }

        // 탭 제목 매핑
        const titleMapping = mappingMap.get(`${comp.id}_addtab_${tabIndex}_title`);
        if (titleMapping) {
          updatedTab.titleLangKeyId = titleMapping.keyId;
          updatedTab.titleLangKey = titleMapping.langKey;
        }

        // 탭 컬럼 매핑
        if (tab.columns && Array.isArray(tab.columns)) {
          updatedTab.columns = tab.columns.map((col: any, colIndex: number) => {
            const colMapping = mappingMap.get(`${comp.id}_addtab_${tabIndex}_col_${colIndex}`);
            if (colMapping) {
              return { ...col, langKeyId: colMapping.keyId, langKey: colMapping.langKey };
            }
            return col;
          });
        }

        return updatedTab;
      });
      
      // rightPanel.additionalTabs에 저장하거나 additionalTabs에 저장
      if (currentRightPanelForAddTabs?.additionalTabs) {
        updated.componentConfig = {
          ...updated.componentConfig,
          rightPanel: { ...currentRightPanelForAddTabs, additionalTabs: updatedAdditionalTabs },
        };
      } else {
        updated.componentConfig = { ...updated.componentConfig, additionalTabs: updatedAdditionalTabs };
      }
    }

    // 액션 버튼 매핑
    if (config?.actions?.actions && Array.isArray(config.actions.actions)) {
      const updatedActions = config.actions.actions.map((action: any, index: number) => {
        const actionMapping = mappingMap.get(`${comp.id}_action_${index}`);
        if (actionMapping) {
          return { ...action, langKeyId: actionMapping.keyId, langKey: actionMapping.langKey };
        }
        return action;
      });
      updated.componentConfig = {
        ...updated.componentConfig,
        actions: { ...config.actions, actions: updatedActions },
      };
    }

    // 집계 위젯 (aggregation-widget) 항목 라벨 매핑
    if (compType === "aggregation-widget" && config?.items && Array.isArray(config.items)) {
      const updatedItems = config.items.map((item: any, index: number) => {
        const itemMapping = mappingMap.get(`${comp.id}_agg_${item.id || index}`);
        if (itemMapping) {
          return {
            ...item,
            labelLangKeyId: itemMapping.keyId,
            labelLangKey: itemMapping.langKey,
          };
        }
        return item;
      });
      updated.componentConfig = {
        ...updated.componentConfig,
        items: updatedItems,
      };
    }

    // 자식 컴포넌트 재귀 처리
    if (anyComp.children && Array.isArray(anyComp.children)) {
      updated.children = anyComp.children.map((child: ComponentData) => updateComponent(child));
    }

    return updated;
  };

  return components.map(updateComponent);
}

