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

"use client";

import { useState, useCallback, useEffect, useMemo } from "react";
import { useRouter } from "next/navigation";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import PopRenderer from "../designer/renderers/PopRenderer";
import type { PopLayoutData, 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: PopLayoutData;
  /** 뷰포트 너비 */
  viewportWidth: number;
  /** 화면 ID (이벤트 버스용) */
  screenId: string;
  /** 현재 그리드 모드 (PopRenderer 전달용) */
  currentMode?: GridMode;
  /** Gap 오버라이드 */
  overrideGap?: number;
  /** Padding 오버라이드 */
  overridePadding?: number;
  /** 부모 화면에서 선택된 행 데이터 (모달 내부 컴포넌트가 sharedData로 조회) */
  parentRow?: Record<string, unknown>;
}

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

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

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

  useEffect(() => {
    if (parentRow) {
      setSharedData("parentRow", parentRow);
    }
  }, [parentRow, setSharedData]);

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

  const componentTypes = useMemo(() => {
    const map = new Map<string, string>();
    if (layout.components) {
      for (const comp of Object.values(layout.components)) {
        map.set(comp.id, comp.type);
      }
    }
    return map;
  }, [layout.components]);

  useConnectionResolver({
    screenId,
    connections: stableConnections,
    componentTypes,
  });

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

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

    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);
      });
    });

    const unsubNavigate = subscribe("__pop_navigate__", (payload: unknown) => {
      const data = payload as {
        screenId?: string;
        params?: Record<string, string>;
      };

      if (!data?.screenId) return;

      if (data.screenId === "back") {
        router.back();
      } else {
        const query = data.params
          ? "?" + new URLSearchParams(data.params).toString()
          : "";
        window.location.href = `/pop/screens/${data.screenId}${query}`;
      }
    });

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

  // 최상위 모달만 닫기 (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, fullscreen } = modal;
        const isTopModal = index === modalStack.length - 1;
        const closeOnOverlay = definition.frameConfig?.closeOnOverlay !== false;
        const closeOnEsc = definition.frameConfig?.closeOnEsc !== false;

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

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

        return (
          <Dialog
            key={`${definition.id}-${index}`}
            open={true}
            onOpenChange={(open) => {
              if (!open && isTopModal) handleCloseTopModal();
            }}
          >
            <DialogContent
              className={isFull
                ? "flex h-dvh max-h-dvh w-screen max-w-[100vw] flex-col gap-0 overflow-hidden rounded-none border-none p-0"
                : "max-h-[90vh] overflow-auto p-0"
              }
              style={isFull ? undefined : {
                maxWidth: `${modalWidth}px`,
                width: `${modalWidth}px`,
              }}
              onInteractOutside={(e) => {
                if (!isTopModal || !closeOnOverlay) e.preventDefault();
              }}
              onEscapeKeyDown={(e) => {
                if (!isTopModal || !closeOnEsc) e.preventDefault();
              }}
            >
              {definition.title && (
                <DialogHeader className={isFull ? "shrink-0 border-b px-4 py-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>
        );
      })}
    </>
  );
}
