/**
 * V2 레이아웃 변환 유틸리티
 *
 * 기존 LayoutData ↔ V2 LayoutData 변환
 */

import {
  ComponentV2,
  LayoutV2,
  getComponentUrl,
  getComponentTypeFromUrl,
  getDefaultsByUrl,
  mergeComponentConfig,
  extractCustomConfig,
} from "@/lib/schemas/componentConfig";

// 기존 ComponentData 타입 (간략화)
interface LegacyComponentData {
  id: string;
  componentType?: string;
  widgetType?: string;
  type?: string;
  position?: { x: number; y: number };
  size?: { width: number; height: number };
  componentConfig?: Record<string, any>;
  [key: string]: any;
}

interface LegacyLayoutData {
  components: LegacyComponentData[];
  layers?: any[]; // 레이어 시스템
  gridSettings?: any;
  screenResolution?: any;
  metadata?: any;
}

// ============================================
// 중첩 컴포넌트 기본값 적용 헬퍼 함수 (재귀적)
// ============================================
function applyDefaultsToNestedComponents(components: any[]): any[] {
  if (!Array.isArray(components)) return components;

  return components.map((nestedComp: any) => {
    if (!nestedComp) return nestedComp;

    // 중첩 컴포넌트의 타입 확인 (componentType 또는 url에서 추출)
    let nestedComponentType = nestedComp.componentType;
    if (!nestedComponentType && nestedComp.url) {
      nestedComponentType = getComponentTypeFromUrl(nestedComp.url);
    }

    // 결과 객체 초기화 (원본 복사)
    const result = { ...nestedComp };

    // 🆕 탭 위젯인 경우 재귀적으로 탭 내부 컴포넌트도 처리
    if (nestedComponentType === "v2-tabs-widget") {
      const config = result.componentConfig || {};
      if (config.tabs && Array.isArray(config.tabs)) {
        result.componentConfig = {
          ...config,
          tabs: config.tabs.map((tab: any) => {
            if (tab?.components && Array.isArray(tab.components)) {
              return {
                ...tab,
                components: applyDefaultsToNestedComponents(tab.components),
              };
            }
            return tab;
          }),
        };
      }
    }

    // 🆕 분할 패널인 경우 재귀적으로 내부 컴포넌트도 처리
    if (nestedComponentType === "v2-split-panel-layout") {
      const config = result.componentConfig || {};
      result.componentConfig = {
        ...config,
        leftPanel: config.leftPanel
          ? {
              ...config.leftPanel,
              components: applyDefaultsToNestedComponents(config.leftPanel.components || []),
            }
          : config.leftPanel,
        rightPanel: config.rightPanel
          ? {
              ...config.rightPanel,
              components: applyDefaultsToNestedComponents(config.rightPanel.components || []),
            }
          : config.rightPanel,
      };
    }

    // 컴포넌트 타입이 없으면 그대로 반환
    if (!nestedComponentType) {
      return result;
    }

    // 중첩 컴포넌트의 기본값 가져오기
    const nestedDefaults = getDefaultsByUrl(`registry://${nestedComponentType}`);

    // componentConfig가 있으면 기본값과 병합
    if (result.componentConfig && Object.keys(nestedDefaults).length > 0) {
      const mergedNestedConfig = mergeComponentConfig(nestedDefaults, result.componentConfig);
      return {
        ...result,
        componentConfig: mergedNestedConfig,
      };
    }

    return result;
  });
}

// ============================================
// 분할 패널 내부 컴포넌트 기본값 적용
// ============================================
function applyDefaultsToSplitPanelComponents(mergedConfig: Record<string, any>): Record<string, any> {
  const result = { ...mergedConfig };

  // leftPanel.components 처리
  if (result.leftPanel?.components) {
    result.leftPanel = {
      ...result.leftPanel,
      components: applyDefaultsToNestedComponents(result.leftPanel.components),
    };
  }

  // rightPanel.components 처리
  if (result.rightPanel?.components) {
    result.rightPanel = {
      ...result.rightPanel,
      components: applyDefaultsToNestedComponents(result.rightPanel.components),
    };
  }

  return result;
}

// ============================================
// V2 → Legacy 변환 (로드 시)
// ============================================
export function convertV2ToLegacy(v2Layout: LayoutV2 | null): LegacyLayoutData | null {
  if (!v2Layout) {
    return null;
  }

  // V2 컴포넌트를 Legacy 컴포넌트로 변환하는 함수 (레이어 내 컴포넌트에도 재사용)
  const convertV2Component = (comp: ComponentV2, layerId?: string): LegacyComponentData => {
    const componentType = getComponentTypeFromUrl(comp.url);
    const defaults = getDefaultsByUrl(comp.url);
    let mergedConfig = mergeComponentConfig(defaults, comp.overrides);

    // 분할 패널인 경우 내부 컴포넌트에도 기본값 적용
    if (componentType === "v2-split-panel-layout") {
      mergedConfig = applyDefaultsToSplitPanelComponents(mergedConfig);
    }

    // 탭 위젯인 경우 탭 내부 컴포넌트에도 기본값 적용
    if (componentType === "v2-tabs-widget" && mergedConfig.tabs) {
      mergedConfig = {
        ...mergedConfig,
        tabs: mergedConfig.tabs.map((tab: any) => {
          if (tab?.components) {
            return {
              ...tab,
              components: applyDefaultsToNestedComponents(tab.components),
            };
          }
          return tab;
        }),
      };
    }

    const overrides = comp.overrides || {};

    return {
      id: comp.id,
      componentType: componentType,
      widgetType: componentType,
      type: "component",
      position: comp.position,
      size: comp.size,
      componentConfig: mergedConfig,
      // 상위 레벨 속성 복원
      tableName: overrides.tableName,
      columnName: overrides.columnName,
      label: overrides.label || mergedConfig.label || "",
      required: overrides.required,
      readonly: overrides.readonly,
      hidden: overrides.hidden,
      codeCategory: overrides.codeCategory,
      inputType: overrides.inputType,
      webType: overrides.webType,
      autoFill: overrides.autoFill,
      style: overrides.style || {},
      webTypeConfig: overrides.webTypeConfig || {},
      parentId: null,
      gridColumns: 12,
      gridRowIndex: 0,
      // 🆕 레이어 ID 복원
      ...(layerId ? { layerId } : {}),
    };
  };

  // 🆕 레이어 구조가 있는 경우 (v2.1)
  const v2Layers = (v2Layout as any).layers;
  if (v2Layers && Array.isArray(v2Layers) && v2Layers.length > 0) {
    // 모든 레이어의 컴포넌트를 평탄화하여 layout.components에 저장 (layerId 포함)
    const allComponents: LegacyComponentData[] = [];
    const legacyLayers = v2Layers.map((layer: any) => {
      const layerComponents = (layer.components || []).map((comp: any) => 
        convertV2Component(comp, layer.id)
      );
      allComponents.push(...layerComponents);

      return {
        ...layer,
        // layer.components는 legacy 변환 시 빈 배열로 (layout.components + layerId 방식 사용)
        components: [],
      };
    });

    return {
      components: allComponents,
      layers: legacyLayers,
      gridSettings: v2Layout.gridSettings || {
        enabled: true, size: 20, color: "#d1d5db", opacity: 0.5,
        snapToGrid: true, columns: 12, gap: 16, padding: 16,
      },
      screenResolution: v2Layout.screenResolution || { width: 1920, height: 1080 },
    };
  }

  // 레이어 없는 기존 방식
  if (!v2Layout.components) return null;
  
  const components: LegacyComponentData[] = v2Layout.components.map((comp) => convertV2Component(comp));

  return {
    components,
    gridSettings: v2Layout.gridSettings || {
      enabled: true, size: 20, color: "#d1d5db", opacity: 0.5,
      snapToGrid: true, columns: 12, gap: 16, padding: 16,
    },
    screenResolution: v2Layout.screenResolution || { width: 1920, height: 1080 },
  };
}

// ============================================
// Legacy → V2 변환 (저장 시)
// ============================================
export function convertLegacyToV2(legacyLayout: LegacyLayoutData): LayoutV2 {
  // 컴포넌트 변환 함수 (레이어 내 컴포넌트 변환에도 재사용)
  const convertComponent = (comp: LegacyComponentData, index: number): ComponentV2 => {
    // 컴포넌트 타입 결정
    const componentType = comp.componentType || comp.widgetType || comp.type || "unknown";
    const url = getComponentUrl(componentType);

    // 기본값 가져오기
    const defaults = getDefaultsByUrl(url);

    // 🆕 컴포넌트 상위 레벨 속성들도 포함 (tableName, columnName 등)
    const topLevelProps: Record<string, any> = {};
    if (comp.tableName) topLevelProps.tableName = comp.tableName;
    if (comp.columnName) topLevelProps.columnName = comp.columnName;
    // 🔧 label은 빈 문자열도 저장 (라벨 삭제 지원)
    if (comp.label !== undefined) topLevelProps.label = comp.label;
    if (comp.required !== undefined) topLevelProps.required = comp.required;
    if (comp.readonly !== undefined) topLevelProps.readonly = comp.readonly;
    if (comp.hidden !== undefined) topLevelProps.hidden = comp.hidden; // 🆕 숨김 설정 저장
    if (comp.codeCategory) topLevelProps.codeCategory = comp.codeCategory;
    if (comp.inputType) topLevelProps.inputType = comp.inputType;
    if (comp.webType) topLevelProps.webType = comp.webType;
    // 🆕 autoFill 설정 저장 (자동 입력 기능)
    if (comp.autoFill) topLevelProps.autoFill = comp.autoFill;
    // 🆕 style 설정 저장 (라벨 텍스트, 라벨 스타일 등)
    if (comp.style && Object.keys(comp.style).length > 0) topLevelProps.style = comp.style;
    // 🔧 webTypeConfig 저장 (버튼 제어기능, 플로우 가시성 등)
    if (comp.webTypeConfig && Object.keys(comp.webTypeConfig).length > 0) {
      topLevelProps.webTypeConfig = comp.webTypeConfig;
      // 🔍 디버그: webTypeConfig 저장 확인
      if (comp.webTypeConfig.dataflowConfig || comp.webTypeConfig.enableDataflowControl) {
        console.log("💾 webTypeConfig 저장:", {
          componentId: comp.id,
          enableDataflowControl: comp.webTypeConfig.enableDataflowControl,
          dataflowConfig: comp.webTypeConfig.dataflowConfig,
        });
      }
    }

    // 현재 설정에서 차이값만 추출
    const fullConfig = comp.componentConfig || {};
    const configOverrides = extractCustomConfig(fullConfig, defaults);

    // 🔧 디버그: style 저장 확인 (주석 처리)
    // if (comp.style?.labelDisplay !== undefined || configOverrides.style?.labelDisplay !== undefined) { console.log("💾 저장 시 style 변환:", { componentId: comp.id, "comp.style": comp.style, "configOverrides.style": configOverrides.style, "topLevelProps.style": topLevelProps.style }); }

    // 상위 레벨 속성과 componentConfig 병합
    // 🔧 style은 양쪽을 병합하되 comp.style(topLevelProps.style)을 우선시
    const mergedStyle = {
      ...(configOverrides.style || {}),
      ...(topLevelProps.style || {}),
    };

    // 🔧 webTypeConfig도 병합 (topLevelProps가 우선, dataflowConfig 등 보존)
    const mergedWebTypeConfig = {
      ...(configOverrides.webTypeConfig || {}),
      ...(topLevelProps.webTypeConfig || {}),
    };

    const overrides = {
      ...topLevelProps,
      ...configOverrides,
      // 🆕 병합된 style 사용 (comp.style 값이 최종 우선)
      ...(Object.keys(mergedStyle).length > 0 ? { style: mergedStyle } : {}),
      // 🆕 병합된 webTypeConfig 사용 (comp.webTypeConfig가 최종 우선)
      ...(Object.keys(mergedWebTypeConfig).length > 0 ? { webTypeConfig: mergedWebTypeConfig } : {}),
    };

    return {
      id: comp.id,
      url: url,
      position: comp.position || { x: 0, y: 0 },
      size: comp.size || { width: 100, height: 100 },
      displayOrder: index,
      overrides: overrides,
    };
  };

  // 🆕 레이어 정보 변환 (layers가 있으면 레이어 구조로 저장)
  const legacyLayers = (legacyLayout as any).layers;
  if (legacyLayers && Array.isArray(legacyLayers) && legacyLayers.length > 0) {
    const v2Layers = legacyLayers.map((layer: any) => ({
      ...layer,
      // 레이어 내 컴포넌트를 V2 형식으로 변환
      components: (layer.components || []).map((comp: any, idx: number) => convertComponent(comp, idx)),
    }));

    return {
      version: "2.1",
      layers: v2Layers,
      components: [], // 레이어 구조 사용 시 상위 components는 빈 배열
      gridSettings: legacyLayout.gridSettings,
      screenResolution: legacyLayout.screenResolution,
      metadata: legacyLayout.metadata,
    };
  }

  // 레이어 없으면 기존 방식 (컴포넌트만)
  const components = legacyLayout.components.map((comp, index) => convertComponent(comp, index));

  return {
    version: "2.0",
    components,
    gridSettings: legacyLayout.gridSettings,
    screenResolution: legacyLayout.screenResolution,
    metadata: legacyLayout.metadata,
  };
}

// ============================================
// V2 레이아웃 유효성 검사
// ============================================
export function isValidV2Layout(data: any): data is LayoutV2 {
  if (!data || typeof data !== "object") return false;
  // v2.0: components 기반, v2.1: layers 기반
  const isV2 = data.version === "2.0" && Array.isArray(data.components);
  const isV21 = data.version === "2.1" && Array.isArray(data.layers);
  return isV2 || isV21;
}

// ============================================
// 기존 레이아웃인지 확인
// ============================================
export function isLegacyLayout(data: any): boolean {
  return data && typeof data === "object" && Array.isArray(data.components) && data.version !== "2.0";
}
