/**
 * PopViewerWithModals - 뷰어 모드에서 모달 렌더링 래퍼
 *
 * PopRenderer를 감싸서:
 *   1. __pop_modal_open__ 이벤트 구독 → Dialog 열기
 *   2. __pop_modal_close__ 이벤트 구독 → Dialog 닫기
 *   3. 모달 스택 관리 (중첩 모달 지원)
 *
 * 모달 내부는 또 다른 PopRenderer로 렌더링 (독립 그리드).
 */

"use client";

import { useState, useCallback, useEffect, useMemo } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import PopRenderer from "../designer/renderers/PopRenderer";
import type { PopLayoutDataV5, PopModalDefinition, GridMode } from "../designer/types/pop-layout";
import { detectGridMode, resolveModalWidth } from "../designer/types/pop-layout";
import { usePopEvent } from "@/hooks/pop/usePopEvent";
import { useConnectionResolver } from "@/hooks/pop/useConnectionResolver";

// ========================================
// 타입
// ========================================

interface PopViewerWithModalsProps {
  /** 전체 레이아웃 (모달 정의 포함) */
  layout: PopLayoutDataV5;
  /** 뷰포트 너비 */
  viewportWidth: number;
  /** 화면 ID (이벤트 버스용) */
  screenId: string;
  /** 현재 그리드 모드 (PopRenderer 전달용) */
  currentMode?: GridMode;
  /** Gap 오버라이드 */
  overrideGap?: number;
  /** Padding 오버라이드 */
  overridePadding?: number;
}

/** 열린 모달 상태 */
interface OpenModal {
  definition: PopModalDefinition;
  returnTo?: string;
}

// ========================================
// 메인 컴포넌트
// ========================================

export default function PopViewerWithModals({
  layout,
  viewportWidth,
  screenId,
  currentMode,
  overrideGap,
  overridePadding,
}: PopViewerWithModalsProps) {
  const [modalStack, setModalStack] = useState<OpenModal[]>([]);
  const { subscribe, publish } = usePopEvent(screenId);

  // 연결 해석기: layout에 정의된 connections를 이벤트 라우팅으로 변환
  const stableConnections = useMemo(() => layout.dataFlow?.connections ?? [], [layout.dataFlow?.connections]);
  useConnectionResolver({
    screenId,
    connections: stableConnections,
  });

  // 모달 열기/닫기 이벤트 구독
  useEffect(() => {
    const unsubOpen = subscribe("__pop_modal_open__", (payload: unknown) => {
      const data = payload as {
        modalId?: string;
        title?: string;
        mode?: string;
        returnTo?: string;
      };

      if (data?.modalId) {
        const modalDef = layout.modals?.find((m) => m.id === data.modalId);
        if (modalDef) {
          setModalStack((prev) => [
            ...prev,
            {
              definition: modalDef,
              returnTo: data.returnTo,
            },
          ]);
        }
      }
    });

    const unsubClose = subscribe("__pop_modal_close__", (payload: unknown) => {
      const data = payload as { selectedRow?: Record<string, unknown> } | undefined;

      setModalStack((prev) => {
        if (prev.length === 0) return prev;
        const topModal = prev[prev.length - 1];

        // 결과 데이터가 있고, 반환 대상이 지정된 경우 결과 이벤트 발행
        if (data?.selectedRow && topModal.returnTo) {
          publish("__pop_modal_result__", {
            selectedRow: data.selectedRow,
            returnTo: topModal.returnTo,
          });
        }

        return prev.slice(0, -1);
      });
    });

    return () => {
      unsubOpen();
      unsubClose();
    };
  }, [subscribe, publish, layout.modals]);

  // 최상위 모달만 닫기 (X 버튼, overlay 클릭, ESC)
  const handleCloseTopModal = useCallback(() => {
    setModalStack((prev) => prev.slice(0, -1));
  }, []);

  return (
    <>
      {/* 메인 화면 렌더링 */}
      <PopRenderer
        layout={layout}
        viewportWidth={viewportWidth}
        currentScreenId={Number(screenId) || undefined}
        currentMode={currentMode}
        isDesignMode={false}
        overrideGap={overrideGap}
        overridePadding={overridePadding}
      />

      {/* 모달 스택 렌더링 */}
      {modalStack.map((modal, index) => {
        const { definition } = modal;
        const isTopModal = index === modalStack.length - 1;
        const closeOnOverlay = definition.frameConfig?.closeOnOverlay !== false;
        const closeOnEsc = definition.frameConfig?.closeOnEsc !== false;

        const modalLayout: PopLayoutDataV5 = {
          ...layout,
          gridConfig: definition.gridConfig,
          components: definition.components,
          overrides: definition.overrides,
        };

        const detectedMode = currentMode || detectGridMode(viewportWidth);
        const modalWidth = resolveModalWidth(definition.sizeConfig, detectedMode, viewportWidth);
        const isFull = modalWidth >= viewportWidth;
        const rendererWidth = isFull ? viewportWidth : modalWidth - 32;

        return (
          <Dialog
            key={`${definition.id}-${index}`}
            open={true}
            onOpenChange={(open) => {
              if (!open && isTopModal) handleCloseTopModal();
            }}
          >
            <DialogContent
              className={
                isFull
                  ? "h-dvh max-h-dvh w-screen max-w-[100vw] overflow-auto rounded-none border-none p-0"
                  : "max-h-[90vh] overflow-auto p-0"
              }
              style={
                isFull
                  ? undefined
                  : {
                      maxWidth: `${modalWidth}px`,
                      width: `${modalWidth}px`,
                    }
              }
              onInteractOutside={(e) => {
                // 최상위 모달이 아니면 overlay 클릭 무시 (하위 모달이 먼저 닫히는 것 방지)
                if (!isTopModal || !closeOnOverlay) e.preventDefault();
              }}
              onEscapeKeyDown={(e) => {
                if (!isTopModal || !closeOnEsc) e.preventDefault();
              }}
            >
              <DialogHeader className={isFull ? "px-4 pt-3 pb-2" : "px-4 pt-4 pb-2"}>
                <DialogTitle className="text-base">{definition.title}</DialogTitle>
              </DialogHeader>
              <div className={isFull ? "flex-1 overflow-auto" : "px-4 pb-4"}>
                <PopRenderer
                  layout={modalLayout}
                  viewportWidth={rendererWidth}
                  currentScreenId={Number(screenId) || undefined}
                />
              </div>
            </DialogContent>
          </Dialog>
        );
      })}
    </>
  );
}
