/**
 * 컴포넌트 ID로 해당 컴포넌트의 ConfigPanel을 동적으로 로드하는 유틸리티
 */

import React from "react";
import type { ConfigPanelContext } from "@/lib/registry/components/common/ConfigPanelTypes";

// 컴포넌트별 ConfigPanel 동적 import 맵
const CONFIG_PANEL_MAP: Record<string, () => Promise<any>> = {
  // ========== V2 컴포넌트 ==========
  "v2-input": () => import("@/components/v2/config-panels/V2FieldConfigPanel"),
  "v2-select": () => import("@/components/v2/config-panels/V2FieldConfigPanel"),
  "v2-date": () => import("@/components/v2/config-panels/V2DateConfigPanel"),
  "v2-list": () => import("@/components/v2/config-panels/V2ListConfigPanel"),
  "v2-media": () => import("@/components/v2/config-panels/V2MediaConfigPanel"),
  "v2-biz": () => import("@/components/v2/config-panels/V2BizConfigPanel"),
  "v2-group": () => import("@/components/v2/config-panels/V2GroupConfigPanel"),
  "v2-hierarchy": () => import("@/components/v2/config-panels/V2HierarchyConfigPanel"),
  "v2-layout": () => import("@/components/v2/config-panels/V2LayoutConfigPanel"),
  "v2-repeater": () => import("@/components/v2/config-panels/V2RepeaterConfigPanel"),

  // ========== 기본 입력 컴포넌트 ==========
  "text-input": () => import("@/lib/registry/components/text-input/TextInputConfigPanel"),
  "number-input": () => import("@/lib/registry/components/number-input/NumberInputConfigPanel"),
  "date-input": () => import("@/lib/registry/components/date-input/DateInputConfigPanel"),
  "textarea-basic": () => import("@/lib/registry/components/textarea-basic/TextareaBasicConfigPanel"),
  "select-basic": () => import("@/lib/registry/components/select-basic/SelectBasicConfigPanel"),
  "checkbox-basic": () => import("@/lib/registry/components/checkbox-basic/CheckboxBasicConfigPanel"),
  "radio-basic": () => import("@/lib/registry/components/radio-basic/RadioBasicConfigPanel"),
  "toggle-switch": () => import("@/lib/registry/components/toggle-switch/ToggleSwitchConfigPanel"),
  "file-upload": () => import("@/lib/registry/components/file-upload/FileUploadConfigPanel"),
  "slider-basic": () => import("@/lib/registry/components/slider-basic/SliderBasicConfigPanel"),
  "test-input": () => import("@/lib/registry/components/test-input/TestInputConfigPanel"),

  // ========== 버튼 ==========
  "button-primary": () => import("@/components/screen/config-panels/ButtonConfigPanel"),
  "v2-button-primary": () => import("@/components/screen/config-panels/ButtonConfigPanel"),

  // ========== 표시 컴포넌트 ==========
  "text-display": () => import("@/lib/registry/components/text-display/TextDisplayConfigPanel"),
  "v2-text-display": () => import("@/lib/registry/components/v2-text-display/TextDisplayConfigPanel"),
  "image-display": () => import("@/lib/registry/components/image-display/ImageDisplayConfigPanel"),
  "divider-line": () => import("@/lib/registry/components/divider-line/DividerLineConfigPanel"),
  "v2-divider-line": () => import("@/lib/registry/components/v2-divider-line/DividerLineConfigPanel"),
  "image-widget": () => import("@/lib/registry/components/image-widget/ImageWidgetConfigPanel"),

  // ========== 레이아웃/컨테이너 ==========
  "accordion-basic": () => import("@/lib/registry/components/accordion-basic/AccordionBasicConfigPanel"),
  "card-display": () => import("@/lib/registry/components/card-display/CardDisplayConfigPanel"),
  "v2-card-display": () => import("@/lib/registry/components/v2-card-display/CardDisplayConfigPanel"),
  "section-card": () => import("@/lib/registry/components/section-card/SectionCardConfigPanel"),
  "v2-section-card": () => import("@/lib/registry/components/v2-section-card/SectionCardConfigPanel"),
  "section-paper": () => import("@/lib/registry/components/section-paper/SectionPaperConfigPanel"),
  "v2-section-paper": () => import("@/lib/registry/components/v2-section-paper/SectionPaperConfigPanel"),
  "split-panel-layout": () => import("@/lib/registry/components/split-panel-layout/SplitPanelLayoutConfigPanel"),
  "v2-split-panel-layout": () => import("@/lib/registry/components/v2-split-panel-layout/SplitPanelLayoutConfigPanel"),
  "split-panel-layout2": () => import("@/lib/registry/components/split-panel-layout2/SplitPanelLayout2ConfigPanel"),
  "screen-split-panel": () => import("@/lib/registry/components/screen-split-panel/ScreenSplitPanelConfigPanel"),
  "conditional-container": () => import("@/lib/registry/components/conditional-container/ConditionalContainerConfigPanel"),
  "v2-split-line": () => import("@/lib/registry/components/v2-split-line/SplitLineConfigPanel"),

  // ========== 테이블/리스트 ==========
  "table-list": () => import("@/lib/registry/components/table-list/TableListConfigPanel"),
  "v2-table-list": () => import("@/lib/registry/components/v2-table-list/TableListConfigPanel"),
  "pivot-grid": () => import("@/lib/registry/components/pivot-grid/PivotGridConfigPanel"),
  "v2-pivot-grid": () => import("@/lib/registry/components/v2-pivot-grid/PivotGridConfigPanel"),
  "table-search-widget": () => import("@/lib/registry/components/table-search-widget/TableSearchWidgetConfigPanel"),
  "v2-table-search-widget": () => import("@/lib/registry/components/v2-table-search-widget/TableSearchWidgetConfigPanel"),
  "tax-invoice-list": () => import("@/lib/registry/components/tax-invoice-list/TaxInvoiceListConfigPanel"),

  // ========== 리피터/반복 ==========
  "repeat-container": () => import("@/lib/registry/components/repeat-container/RepeatContainerConfigPanel"),
  "v2-repeat-container": () => import("@/lib/registry/components/v2-repeat-container/RepeatContainerConfigPanel"),
  "repeater-field-group": () => import("@/components/webtypes/config/RepeaterConfigPanel"),
  "simple-repeater-table": () => import("@/lib/registry/components/simple-repeater-table/SimpleRepeaterTableConfigPanel"),
  "modal-repeater-table": () => import("@/lib/registry/components/modal-repeater-table/ModalRepeaterTableConfigPanel"),
  "repeat-screen-modal": () => import("@/lib/registry/components/repeat-screen-modal/RepeatScreenModalConfigPanel"),
  "related-data-buttons": () => import("@/lib/registry/components/related-data-buttons/RelatedDataButtonsConfigPanel"),

  // ========== 검색/선택 ==========
  "autocomplete-search-input": () => import("@/lib/registry/components/autocomplete-search-input/AutocompleteSearchInputConfigPanel"),
  "entity-search-input": () => import("@/lib/registry/components/entity-search-input/EntitySearchInputConfigPanel"),
  "selected-items-detail-input": () => import("@/lib/registry/components/selected-items-detail-input/SelectedItemsDetailInputConfigPanel"),
  "customer-item-mapping": () => import("@/lib/registry/components/customer-item-mapping/CustomerItemMappingConfigPanel"),
  "mail-recipient-selector": () => import("@/lib/registry/components/mail-recipient-selector/MailRecipientSelectorConfigPanel"),
  "location-swap-selector": () => import("@/lib/registry/components/location-swap-selector/LocationSwapSelectorConfigPanel"),
  "v2-location-swap-selector": () => import("@/lib/registry/components/v2-location-swap-selector/LocationSwapSelectorConfigPanel"),

  // ========== 특수 컴포넌트 ==========
  "flow-widget": () => import("@/components/screen/config-panels/FlowWidgetConfigPanel"),
  "tabs-widget": () => import("@/components/screen/config-panels/TabsConfigPanel"),
  "v2-tabs-widget": () => import("@/components/screen/config-panels/TabsConfigPanel"),
  "tabs": () => import("@/components/screen/config-panels/TabsConfigPanel"),
  "v2-tabs": () => import("@/components/screen/config-panels/TabsConfigPanel"),
  "map": () => import("@/lib/registry/components/map/MapConfigPanel"),
  "rack-structure": () => import("@/lib/registry/components/rack-structure/RackStructureConfigPanel"),
  "v2-rack-structure": () => import("@/lib/registry/components/v2-rack-structure/RackStructureConfigPanel"),
  "aggregation-widget": () => import("@/lib/registry/components/aggregation-widget/AggregationWidgetConfigPanel"),
  "v2-aggregation-widget": () => import("@/lib/registry/components/v2-aggregation-widget/AggregationWidgetConfigPanel"),
  "numbering-rule": () => import("@/lib/registry/components/numbering-rule/NumberingRuleConfigPanel"),
  "v2-numbering-rule": () => import("@/lib/registry/components/v2-numbering-rule/NumberingRuleConfigPanel"),
  "category-manager": () => import("@/lib/registry/components/category-manager/CategoryManagerConfigPanel"),
  "universal-form-modal": () => import("@/lib/registry/components/universal-form-modal/UniversalFormModalConfigPanel"),
  "v2-process-work-standard": () => import("@/lib/registry/components/v2-process-work-standard/ProcessWorkStandardConfigPanel"),

  // ========== V2 BOM 컴포넌트 ==========
  "v2-bom-item-editor": () => import("@/components/v2/config-panels/V2BomItemEditorConfigPanel"),
  "v2-bom-tree": () => import("@/components/v2/config-panels/V2BomTreeConfigPanel"),

  // ========== 레거시 위젯 (component/onUpdateProperty props 사용) ==========
  "card": () => import("@/components/screen/config-panels/CardConfigPanel"),
  "dashboard": () => import("@/components/screen/config-panels/DashboardConfigPanel"),
  "stats": () => import("@/components/screen/config-panels/StatsCardConfigPanel"),
  "stats-card": () => import("@/components/screen/config-panels/StatsCardConfigPanel"),
  "progress": () => import("@/components/screen/config-panels/ProgressBarConfigPanel"),
  "progress-bar": () => import("@/components/screen/config-panels/ProgressBarConfigPanel"),
  "chart": () => import("@/components/screen/config-panels/ChartConfigPanel"),
  "chart-basic": () => import("@/components/screen/config-panels/ChartConfigPanel"),
  "alert": () => import("@/components/screen/config-panels/AlertConfigPanel"),
  "alert-info": () => import("@/components/screen/config-panels/AlertConfigPanel"),
  "badge": () => import("@/components/screen/config-panels/BadgeConfigPanel"),
  "badge-status": () => import("@/components/screen/config-panels/BadgeConfigPanel"),
};

const configPanelCache = new Map<string, React.ComponentType<any>>();

/**
 * 컴포넌트 ID로 ConfigPanel 컴포넌트를 동적으로 로드
 */
export async function getComponentConfigPanel(componentId: string): Promise<React.ComponentType<any> | null> {
  if (configPanelCache.has(componentId)) {
    return configPanelCache.get(componentId)!;
  }

  const importFn = CONFIG_PANEL_MAP[componentId];
  if (!importFn) {
    return null;
  }

  try {
    const module = await importFn();

    // 모듈에서 ConfigPanel 컴포넌트 추출 (우선순위):
    // 1차: PascalCase 변환된 이름 (예: text-input -> TextInputConfigPanel)
    // 2차: v2- 접두사 제거 후 PascalCase (예: v2-table-list -> TableListConfigPanel)
    // 3차: *ConfigPanel로 끝나는 첫 번째 named export
    // 4차: default export
    const pascalCaseName = `${toPascalCase(componentId)}ConfigPanel`;
    const baseComponentId = componentId.startsWith("v2-") ? componentId.slice(3) : componentId;
    const basePascalCaseName = `${toPascalCase(baseComponentId)}ConfigPanel`;

    const findConfigPanelExport = () => {
      for (const key of Object.keys(module)) {
        if (key.endsWith("ConfigPanel") && typeof module[key] === "function") {
          return module[key];
        }
      }
      return null;
    };

    const ConfigPanelComponent =
      module[pascalCaseName] ||
      module[basePascalCaseName] ||
      findConfigPanelExport() ||
      module.default;

    if (!ConfigPanelComponent) {
      console.error(`컴포넌트 "${componentId}"의 ConfigPanel을 모듈에서 찾을 수 없습니다.`);
      return null;
    }

    configPanelCache.set(componentId, ConfigPanelComponent);
    return ConfigPanelComponent;
  } catch (error) {
    console.error(`컴포넌트 "${componentId}"의 ConfigPanel 로드 실패:`, error);
    return null;
  }
}

export function hasComponentConfigPanel(componentId: string): boolean {
  return componentId in CONFIG_PANEL_MAP;
}

export function getSupportedConfigPanelComponents(): string[] {
  return Object.keys(CONFIG_PANEL_MAP);
}

function toPascalCase(str: string): string {
  return str
    .split("-")
    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
    .join("");
}

/**
 * 컴포넌트 설정 패널을 렌더링하는 React 컴포넌트
 */
export interface ComponentConfigPanelProps {
  componentId: string;
  config: Record<string, any>;
  onChange: (config: Record<string, any>) => void;
  screenTableName?: string;
  tableColumns?: any[];
  tables?: any[];
  menuObjid?: number;
  allComponents?: any[];
  currentComponent?: any;
  componentType?: string;
}

export const DynamicComponentConfigPanel: React.FC<ComponentConfigPanelProps> = ({
  componentId,
  config,
  onChange,
  screenTableName,
  tableColumns,
  tables,
  menuObjid,
  allComponents,
  currentComponent,
  componentType,
}) => {
  const [ConfigPanelComponent, setConfigPanelComponent] = React.useState<React.ComponentType<any> | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [selectedTableColumns, setSelectedTableColumns] = React.useState(tableColumns);
  const [allTablesList, setAllTablesList] = React.useState<any[]>([]);
  const [sourceTableColumns, setSourceTableColumns] = React.useState<any[]>([]);
  const [targetTableColumns, setTargetTableColumns] = React.useState<any[]>([]);

  React.useEffect(() => {
    let mounted = true;
    async function loadConfigPanel() {
      try {
        setLoading(true);
        setError(null);
        const component = await getComponentConfigPanel(componentId);
        if (mounted) {
          setConfigPanelComponent(() => component);
          setLoading(false);
        }
      } catch (err) {
        if (mounted) {
          setError(err instanceof Error ? err.message : String(err));
          setLoading(false);
        }
      }
    }
    loadConfigPanel();
    return () => { mounted = false; };
  }, [componentId]);

  React.useEffect(() => {
    setSelectedTableColumns(tableColumns);
  }, [tableColumns]);

  // repeater-field-group / selected-items-detail-input에서 전체 테이블 목록 로드
  React.useEffect(() => {
    if (componentId === "repeater-field-group" || componentId === "selected-items-detail-input") {
      const loadAllTables = async () => {
        try {
          const { tableManagementApi } = await import("@/lib/api/tableManagement");
          const response = await tableManagementApi.getTableList();
          if (response.success && response.data) {
            setAllTablesList(response.data);
          }
        } catch (_) {
          // 전체 테이블 목록 로드 실패 시 무시
        }
      };
      loadAllTables();
    }
  }, [componentId]);

  // selected-items-detail-input: 초기 sourceTable/targetTable 컬럼 로드
  React.useEffect(() => {
    if (componentId !== "selected-items-detail-input") return;

    const loadColumns = async (tableName: string, setter: React.Dispatch<React.SetStateAction<any[]>>, includeCodeCategory?: boolean) => {
      try {
        const { tableTypeApi } = await import("@/lib/api/screen");
        const columnsResponse = await tableTypeApi.getColumns(tableName);
        const columns = (columnsResponse || []).map((col: any) => ({
          columnName: col.columnName || col.column_name,
          columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
          dataType: col.dataType || col.data_type || col.dbType,
          inputType: col.inputType || col.input_type,
          ...(includeCodeCategory ? { codeCategory: col.codeCategory || col.code_category } : {}),
        }));
        setter(columns);
      } catch (_) {
        setter([]);
      }
    };

    if (config.sourceTable) loadColumns(config.sourceTable, setSourceTableColumns);
    if (config.targetTable) loadColumns(config.targetTable, setTargetTableColumns, true);
  }, [componentId, config.sourceTable, config.targetTable]);

  const screenComponents = React.useMemo(() => {
    if (!allComponents) return [];
    return allComponents.map((comp: any) => ({
      id: comp.id,
      componentType: comp.componentType || comp.type,
      label: comp.label || comp.name || comp.id,
      tableName: comp.componentConfig?.tableName || comp.tableName,
      columnName: comp.columnName || comp.componentConfig?.columnName || comp.componentConfig?.fieldName,
    }));
  }, [allComponents]);

  if (loading) {
    return (
      <div className="rounded-md border border-dashed border-input bg-muted p-4 w-full">
        <div className="flex items-center gap-2 text-muted-foreground">
          <span className="text-sm font-medium">로딩 중...</span>
        </div>
        <p className="mt-1 text-xs text-muted-foreground">설정 패널을 불러오는 중입니다.</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="rounded-md border border-dashed border-destructive/30 bg-destructive/10 p-4 w-full">
        <div className="flex items-center gap-2 text-destructive">
          <span className="text-sm font-medium">로드 실패</span>
        </div>
        <p className="mt-1 text-xs text-destructive">설정 패널을 불러올 수 없습니다: {error}</p>
      </div>
    );
  }

  if (!ConfigPanelComponent) {
    return (
      <div className="rounded-md border border-dashed border-amber-300 bg-amber-50 p-4 w-full">
        <div className="flex items-center gap-2 text-amber-600">
          <span className="text-sm font-medium">설정 패널 없음</span>
        </div>
        <p className="mt-1 text-xs text-amber-500">컴포넌트 &quot;{componentId}&quot;에 대한 설정 패널이 없습니다.</p>
      </div>
    );
  }

  // 테이블 변경 핸들러
  const handleTableChange = async (tableName: string) => {
    try {
      const existingTable = tables?.find((t) => t.tableName === tableName);
      if (existingTable?.columns?.length > 0) {
        setSelectedTableColumns(existingTable.columns);
        return;
      }
      const { tableTypeApi } = await import("@/lib/api/screen");
      const columnsResponse = await tableTypeApi.getColumns(tableName);
      const columns = (columnsResponse || []).map((col: any) => ({
        tableName: col.tableName || tableName,
        columnName: col.columnName || col.column_name,
        columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
        dataType: col.dataType || col.data_type || col.dbType,
        webType: col.webType || col.web_type,
        input_type: col.inputType || col.input_type,
        widgetType: col.widgetType || col.widget_type || col.webType || col.web_type,
        isNullable: col.isNullable || col.is_nullable,
        required: col.required !== undefined ? col.required : col.isNullable === "NO" || col.is_nullable === "NO",
        columnDefault: col.columnDefault || col.column_default,
        characterMaximumLength: col.characterMaximumLength || col.character_maximum_length,
        codeCategory: col.codeCategory || col.code_category,
        codeValue: col.codeValue || col.code_value,
      }));
      setSelectedTableColumns(columns);
    } catch (_) {
      setSelectedTableColumns([]);
    }
  };

  const handleSourceTableChange = async (tableName: string) => {
    try {
      const { tableTypeApi } = await import("@/lib/api/screen");
      const columnsResponse = await tableTypeApi.getColumns(tableName);
      const columns = (columnsResponse || []).map((col: any) => ({
        columnName: col.columnName || col.column_name,
        columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
        dataType: col.dataType || col.data_type || col.dbType,
        inputType: col.inputType || col.input_type,
      }));
      setSourceTableColumns(columns);
    } catch (_) {
      setSourceTableColumns([]);
    }
  };

  const handleTargetTableChange = async (tableName: string) => {
    try {
      const { tableTypeApi } = await import("@/lib/api/screen");
      const columnsResponse = await tableTypeApi.getColumns(tableName);
      const columns = (columnsResponse || []).map((col: any) => ({
        columnName: col.columnName || col.column_name,
        columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
        dataType: col.dataType || col.data_type || col.dbType,
        inputType: col.inputType || col.input_type,
        codeCategory: col.codeCategory || col.code_category,
      }));
      setTargetTableColumns(columns);
    } catch (_) {
      setTargetTableColumns([]);
    }
  };

  // --- 특수 래퍼: 레거시 위젯 (component/onUpdateProperty props) ---
  const LEGACY_PANELS = new Set([
    "card", "dashboard", "stats", "stats-card",
    "progress", "progress-bar", "chart", "chart-basic",
    "alert", "alert-info", "badge", "badge-status",
  ]);

  if (LEGACY_PANELS.has(componentId)) {
    const pseudoComponent = {
      id: currentComponent?.id || "temp",
      type: "component",
      componentConfig: config,
      ...currentComponent,
    };
    return (
      <ConfigPanelComponent
        component={pseudoComponent}
        onUpdateProperty={(path: string, value: any) => {
          if (path.startsWith("componentConfig.")) {
            const key = path.replace("componentConfig.", "");
            onChange({ ...config, [key]: value });
          }
        }}
      />
    );
  }

  // --- 특수 래퍼: ButtonConfigPanel (component/onUpdateProperty props) ---
  if (componentId === "button-primary" || componentId === "v2-button-primary") {
    const componentForButton = currentComponent || {
      id: "temp",
      type: "component",
      componentType: componentId,
      componentConfig: config,
    };
    return (
      <ConfigPanelComponent
        component={componentForButton}
        onUpdateProperty={(path: string, value: any) => {
          if (path.startsWith("componentConfig.")) {
            const configPath = path.replace("componentConfig.", "");
            const pathParts = configPath.split(".");
            const currentConfig = componentForButton.componentConfig || {};
            const newConfig = JSON.parse(JSON.stringify(currentConfig));
            let current: any = newConfig;
            for (let i = 0; i < pathParts.length - 1; i++) {
              if (!current[pathParts[i]]) current[pathParts[i]] = {};
              current = current[pathParts[i]];
            }
            current[pathParts[pathParts.length - 1]] = value;
            onChange(newConfig);
          } else {
            const currentConfig = componentForButton.componentConfig || {};
            onChange({ ...currentConfig, [path]: value });
          }
        }}
        allComponents={allComponents}
        currentTableName={screenTableName}
      />
    );
  }

  // --- 통일된 props: 모든 일반 패널에 동일한 props 전달 ---
  const context: ConfigPanelContext = {
    tables,
    tableColumns: selectedTableColumns,
    screenTableName,
    menuObjid,
    allComponents,
    currentComponent,
    allTables: allTablesList.length > 0 ? allTablesList : tables,
    screenComponents,
  };

  return (
    <ConfigPanelComponent
      config={config}
      onChange={onChange}
      onConfigChange={onChange}
      context={context}
      screenTableName={screenTableName}
      tableName={screenTableName}
      columnName={currentComponent?.columnName || config?.columnName || config?.fieldName}
      tableColumns={selectedTableColumns}
      tables={tables}
      allTables={allTablesList.length > 0 ? allTablesList : tables}
      onTableChange={handleTableChange}
      menuObjid={menuObjid}
      allComponents={allComponents}
      currentComponent={currentComponent}
      screenComponents={screenComponents}
      inputType={currentComponent?.inputType || config?.inputType}
      componentType={componentType || componentId}
      sourceTableColumns={sourceTableColumns}
      targetTableColumns={targetTableColumns}
      onSourceTableChange={handleSourceTableChange}
      onTargetTableChange={handleTargetTableChange}
    />
  );
};
