/**
 * 레거시 CustomEvent ↔ V2 EventBus 어댑터
 *
 * 기존 window.dispatchEvent/addEventListener 기반 이벤트를
 * V2 EventBus로 브릿지하여 점진적 마이그레이션을 지원합니다.
 *
 * 특징:
 * - 양방향 브릿지 (레거시 → V2, V2 → 레거시)
 * - 이벤트 중복 방지
 * - 선택적 브릿지 활성화/비활성화
 */

import { v2EventBus, V2_EVENTS, V2EventName, V2EventPayloadMap } from "../events";

// ============================================================================
// 이벤트 매핑 정의
// ============================================================================

interface EventMapping {
  legacy: string;
  v2: V2EventName;
  /** 레거시 → V2 페이로드 변환 함수 */
  toV2?: (legacyDetail: any) => any;
  /** V2 → 레거시 페이로드 변환 함수 */
  toLegacy?: (v2Payload: any) => any;
}

const EVENT_MAPPINGS: EventMapping[] = [
  // 테이블 관련
  {
    legacy: "refreshTable",
    v2: V2_EVENTS.TABLE_REFRESH,
    toV2: (detail) => ({
      tableName: detail?.tableName,
      target: detail?.target ?? "all",
      screenCode: detail?.screenCode,
    }),
    toLegacy: (payload) => ({
      tableName: payload.tableName,
      target: payload.target,
      screenCode: payload.screenCode,
    }),
  },
  {
    legacy: "tableListDataChange",
    v2: V2_EVENTS.TABLE_DATA_CHANGE,
    toV2: (detail) => ({
      tableName: detail?.tableName,
      data: detail?.data ?? [],
      totalCount: detail?.totalCount ?? 0,
      source: detail?.source ?? "legacy",
    }),
    toLegacy: (payload) => ({
      tableName: payload.tableName,
      data: payload.data,
      totalCount: payload.totalCount,
      source: payload.source,
    }),
  },
  {
    legacy: "tableSelectionChange",
    v2: V2_EVENTS.TABLE_SELECTION_CHANGE,
    toV2: (detail) => ({
      tableName: detail?.tableName,
      selectedRows: detail?.selectedRows ?? [],
      selectedRowIds: detail?.selectedRowIds ?? [],
      source: detail?.source ?? "legacy",
    }),
    toLegacy: (payload) => ({
      tableName: payload.tableName,
      selectedRows: payload.selectedRows,
      selectedRowIds: payload.selectedRowIds,
      source: payload.source,
    }),
  },
  {
    legacy: "selectionChange",
    v2: V2_EVENTS.TABLE_SELECTION_CHANGE,
    toV2: (detail) => ({
      tableName: detail?.tableName ?? "",
      selectedRows: detail?.selectedRows ?? [],
      selectedRowIds: detail?.selectedRowIds ?? [],
      source: "legacy-selectionChange",
    }),
    toLegacy: (payload) => ({
      tableName: payload.tableName,
      selectedRows: payload.selectedRows,
      selectedRowIds: payload.selectedRowIds,
      source: payload.source,
    }),
  },

  // 폼 저장 관련
  {
    legacy: "beforeFormSave",
    v2: V2_EVENTS.FORM_SAVE_COLLECT,
    toV2: (detail) => ({
      requestId: detail?.requestId ?? `req_${Date.now()}`,
      formData: detail?.formData ?? {},
      componentId: detail?.componentId ?? "legacy",
    }),
    toLegacy: (payload) => ({
      requestId: payload.requestId,
      formData: payload.formData,
      componentId: payload.componentId,
    }),
  },
  {
    legacy: "saveSuccess",
    v2: V2_EVENTS.FORM_SAVE_COMPLETE,
    toV2: (detail) => ({
      requestId: detail?.requestId ?? "",
      success: true,
      savedData: detail?.savedData ?? detail,
      tableName: detail?.tableName ?? "",
    }),
    toLegacy: (payload) => ({
      requestId: payload.requestId,
      savedData: payload.savedData,
      tableName: payload.tableName,
    }),
  },

  // 리피터 관련
  {
    legacy: "repeaterSave",
    v2: V2_EVENTS.REPEATER_SAVE,
    toV2: (detail) => ({
      repeaterId: detail?.repeaterId ?? "",
      tableName: detail?.tableName ?? "",
      items: detail?.items ?? [],
      joinData: detail?.joinData,
    }),
    toLegacy: (payload) => ({
      repeaterId: payload.repeaterId,
      tableName: payload.tableName,
      items: payload.items,
      joinData: payload.joinData,
    }),
  },
  {
    legacy: "repeaterDataChange",
    v2: V2_EVENTS.REPEATER_DATA_CHANGE,
    toV2: (detail) => ({
      repeaterId: detail?.repeaterId ?? "",
      tableName: detail?.tableName ?? "",
      data: detail?.data ?? [],
      action: detail?.action ?? "update",
    }),
    toLegacy: (payload) => ({
      repeaterId: payload.repeaterId,
      tableName: payload.tableName,
      data: payload.data,
      action: payload.action,
    }),
  },

  // 모달 관련
  {
    legacy: "closeEditModal",
    v2: V2_EVENTS.MODAL_CLOSE,
    toV2: (detail) => ({
      modalId: detail?.modalId ?? "edit-modal",
      reason: detail?.reason ?? "close",
    }),
    toLegacy: (payload) => ({
      modalId: payload.modalId,
      reason: payload.reason,
    }),
  },
  {
    legacy: "saveSuccessInModal",
    v2: V2_EVENTS.MODAL_SAVE_SUCCESS,
    toV2: (detail) => ({
      modalId: detail?.modalId ?? "edit-modal",
      savedData: detail?.savedData ?? {},
      tableName: detail?.tableName ?? "",
    }),
    toLegacy: (payload) => ({
      modalId: payload.modalId,
      savedData: payload.savedData,
      tableName: payload.tableName,
    }),
  },
  {
    legacy: "openScreenModal",
    v2: V2_EVENTS.MODAL_OPEN,
    toV2: (detail) => ({
      modalId: detail?.modalId ?? "",
      screenCode: detail?.screenCode,
      data: detail?.data,
      mode: detail?.mode ?? "view",
    }),
    toLegacy: (payload) => ({
      modalId: payload.modalId,
      screenCode: payload.screenCode,
      data: payload.data,
      mode: payload.mode,
    }),
  },

  // 카드 디스플레이
  {
    legacy: "refreshCardDisplay",
    v2: V2_EVENTS.CARD_REFRESH,
    toV2: (detail) => ({
      cardId: detail?.cardId,
      tableName: detail?.tableName,
    }),
    toLegacy: (payload) => ({
      cardId: payload.cardId,
      tableName: payload.tableName,
    }),
  },

  // 분할 패널
  {
    legacy: "splitPanelDataTransfer",
    v2: V2_EVENTS.SPLIT_PANEL_DATA_TRANSFER,
    toV2: (detail) => ({
      sourcePanel: detail?.sourcePanel ?? "left",
      targetPanel: detail?.targetPanel ?? "right",
      data: detail?.data ?? {},
      tableName: detail?.tableName ?? "",
    }),
    toLegacy: (payload) => ({
      sourcePanel: payload.sourcePanel,
      targetPanel: payload.targetPanel,
      data: payload.data,
      tableName: payload.tableName,
    }),
  },

  // 컴포넌트 데이터 전송
  {
    legacy: "componentDataTransfer",
    v2: V2_EVENTS.COMPONENT_DATA_TRANSFER,
    toV2: (detail) => ({
      sourceComponentId: detail?.sourceComponentId ?? "",
      targetComponentId: detail?.targetComponentId,
      data: detail?.data ?? {},
      tableName: detail?.tableName,
    }),
    toLegacy: (payload) => ({
      sourceComponentId: payload.sourceComponentId,
      targetComponentId: payload.targetComponentId,
      data: payload.data,
      tableName: payload.tableName,
    }),
  },

  // 관련 버튼
  {
    legacy: "related-button-register",
    v2: V2_EVENTS.RELATED_BUTTON_REGISTER,
    toV2: (detail) => ({
      buttonId: detail?.buttonId ?? "",
      targetTables: detail?.targetTables ?? [],
    }),
    toLegacy: (payload) => ({
      buttonId: payload.buttonId,
      targetTables: payload.targetTables,
    }),
  },
  {
    legacy: "related-button-unregister",
    v2: V2_EVENTS.RELATED_BUTTON_UNREGISTER,
    toV2: (detail) => ({
      buttonId: detail?.buttonId ?? "",
    }),
    toLegacy: (payload) => ({
      buttonId: payload.buttonId,
    }),
  },
  {
    legacy: "related-button-select",
    v2: V2_EVENTS.RELATED_BUTTON_SELECT,
    toV2: (detail) => ({
      tableName: detail?.tableName ?? "",
      selectedData: detail?.selectedData ?? [],
    }),
    toLegacy: (payload) => ({
      tableName: payload.tableName,
      selectedData: payload.selectedData,
    }),
  },
];

// ============================================================================
// 어댑터 클래스
// ============================================================================

class LegacyEventAdapter {
  private isActive = false;
  private legacyListeners: Map<string, (e: Event) => void> = new Map();
  private v2Unsubscribes: Map<string, () => void> = new Map();

  /** 브릿지에서 발생한 이벤트 추적 (무한 루프 방지) */
  private bridgedEvents: Set<string> = new Set();

  /** 브릿지 방향 설정 */
  private config = {
    legacyToV2: true,
    v2ToLegacy: true,
  };

  /**
   * 어댑터 초기화 및 브릿지 시작
   *
   * @param options - 브릿지 설정
   */
  init(options?: { legacyToV2?: boolean; v2ToLegacy?: boolean }): void {
    if (this.isActive) {
      console.warn("[LegacyEventAdapter] 이미 초기화되어 있습니다.");
      return;
    }

    if (options) {
      this.config = { ...this.config, ...options };
    }

    EVENT_MAPPINGS.forEach((mapping) => {
      // 레거시 → V2 브릿지
      if (this.config.legacyToV2) {
        this.setupLegacyToV2Bridge(mapping);
      }

      // V2 → 레거시 브릿지
      if (this.config.v2ToLegacy) {
        this.setupV2ToLegacyBridge(mapping);
      }
    });

    this.isActive = true;
  }

  private setupLegacyToV2Bridge(mapping: EventMapping): void {
    const listener = (event: Event) => {
      const customEvent = event as CustomEvent;
      const bridgeKey = `${mapping.legacy}-${Date.now()}`;

      // 무한 루프 방지: 브릿지에서 발생한 이벤트인지 확인
      if (customEvent.detail?.__v2Bridged) {
        return;
      }

      this.bridgedEvents.add(bridgeKey);

      // 페이로드 변환
      const v2Payload = mapping.toV2
        ? mapping.toV2(customEvent.detail)
        : customEvent.detail;

      // V2 EventBus로 발행
      v2EventBus.emitSync(mapping.v2, v2Payload);

      // 잠시 후 브릿지 키 정리
      setTimeout(() => {
        this.bridgedEvents.delete(bridgeKey);
      }, 100);
    };

    window.addEventListener(mapping.legacy, listener);
    this.legacyListeners.set(mapping.legacy, listener);
  }

  private setupV2ToLegacyBridge(mapping: EventMapping): void {
    const unsubscribe = v2EventBus.subscribe(
      mapping.v2,
      (payload) => {
        // 무한 루프 방지 표시 추가
        const legacyPayload = mapping.toLegacy
          ? { ...mapping.toLegacy(payload), __v2Bridged: true }
          : { ...payload, __v2Bridged: true };

        // 레거시 이벤트 발행
        window.dispatchEvent(
          new CustomEvent(mapping.legacy, { detail: legacyPayload })
        );
      },
      { componentId: "legacy-adapter" }
    );

    this.v2Unsubscribes.set(mapping.v2, unsubscribe);
  }

  /**
   * 어댑터 정지 및 정리
   */
  destroy(): void {
    if (!this.isActive) {
      return;
    }

    // 레거시 리스너 정리
    this.legacyListeners.forEach((listener, eventName) => {
      window.removeEventListener(eventName, listener);
    });
    this.legacyListeners.clear();

    // V2 구독 정리
    this.v2Unsubscribes.forEach((unsubscribe) => {
      unsubscribe();
    });
    this.v2Unsubscribes.clear();

    this.bridgedEvents.clear();
    this.isActive = false;
  }

  /**
   * 현재 활성 상태 확인
   */
  get active(): boolean {
    return this.isActive;
  }

  /**
   * 매핑된 이벤트 목록 조회
   */
  getMappings(): Array<{ legacy: string; v2: string }> {
    return EVENT_MAPPINGS.map((m) => ({
      legacy: m.legacy,
      v2: m.v2,
    }));
  }
}

// 싱글톤 인스턴스
export const legacyEventAdapter = new LegacyEventAdapter();

// 개발 환경에서 window에 노출 (디버깅용)
if (typeof window !== "undefined" && process.env.NODE_ENV === "development") {
  (window as any).__legacyEventAdapter = legacyEventAdapter;
}

