"use client";

import React, { useEffect, useState, useMemo } from "react";
import { useParams, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Loader2 } from "lucide-react";
import { screenApi } from "@/lib/api/screen";
import { ScreenDefinition, LayoutData, ComponentData } from "@/types/screen";
import { LayerDefinition } from "@/types/screen-management";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { initializeComponents } from "@/lib/registry/components";
import { EditModal } from "@/components/screen/EditModal";
import { RealtimePreview } from "@/components/screen/RealtimePreviewDynamic";
import { FlowButtonGroup } from "@/components/screen/widgets/FlowButtonGroup";
import { FlowVisibilityConfig } from "@/types/control-management";
import { findAllButtonGroups } from "@/lib/utils/flowButtonGroupUtils";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";
import { ScreenPreviewProvider } from "@/contexts/ScreenPreviewContext";
import { useAuth } from "@/hooks/useAuth"; // 🆕 사용자 정보
import { useResponsive } from "@/lib/hooks/useResponsive"; // 🆕 반응형 감지
import { TableOptionsProvider } from "@/contexts/TableOptionsContext"; // 테이블 옵션
import { TableSearchWidgetHeightProvider, useTableSearchWidgetHeight } from "@/contexts/TableSearchWidgetHeightContext"; // 높이 관리
import { ScreenContextProvider } from "@/contexts/ScreenContext"; // 컴포넌트 간 통신
import { SplitPanelProvider } from "@/lib/registry/components/split-panel-layout/SplitPanelContext"; // 분할 패널 리사이즈
import { ActiveTabProvider } from "@/contexts/ActiveTabContext"; // 활성 탭 관리
import { evaluateConditional } from "@/lib/utils/conditionalEvaluator"; // 조건부 표시 평가
import { ScreenMultiLangProvider } from "@/contexts/ScreenMultiLangContext"; // 화면 다국어
import { convertV2ToLegacy, isValidV2Layout } from "@/lib/utils/layoutV2Converter"; // V2 Zod 기반 변환
import { useScheduleGenerator, ScheduleConfirmDialog } from "@/lib/v2-core/services/ScheduleGeneratorService"; // 스케줄 자동 생성

function ScreenViewPage() {
  // 스케줄 자동 생성 서비스 활성화
  const { showConfirmDialog, previewResult, handleConfirm, closeDialog, isLoading: scheduleLoading } = useScheduleGenerator();
  const params = useParams();
  const searchParams = useSearchParams();
  const router = useRouter();
  const screenId = parseInt(params.screenId as string);

  // URL 쿼리에서 menuObjid 가져오기 (메뉴 스코프)
  const menuObjid = searchParams.get("menuObjid") ? parseInt(searchParams.get("menuObjid")!) : undefined;

  // URL 쿼리에서 프리뷰용 company_code 가져오기
  const previewCompanyCode = searchParams.get("company_code");

  // 프리뷰 모드 감지 (iframe에서 로드될 때)
  const isPreviewMode = searchParams.get("preview") === "true";

  // 🆕 현재 로그인한 사용자 정보
  const { user, userName, companyCode: authCompanyCode } = useAuth();

  // 프리뷰 모드에서는 URL 파라미터의 company_code 우선 사용
  const companyCode = previewCompanyCode || authCompanyCode;

  // 🆕 모바일 환경 감지
  const { isMobile } = useResponsive();

  // 🆕 TableSearchWidget 높이 관리
  const { getHeightDiff } = useTableSearchWidgetHeight();

  const [screen, setScreen] = useState<ScreenDefinition | null>(null);
  const [layout, setLayout] = useState<LayoutData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [formData, setFormData] = useState<Record<string, unknown>>({});

  // 테이블에서 선택된 행 데이터 (버튼 액션에 전달)
  const [selectedRowsData, setSelectedRowsData] = useState<any[]>([]);

  // 테이블 정렬 정보 (엑셀 다운로드용)
  const [tableSortBy, setTableSortBy] = useState<string | undefined>();
  const [tableSortOrder, setTableSortOrder] = useState<"asc" | "desc">("asc");
  const [tableColumnOrder, setTableColumnOrder] = useState<string[] | undefined>();
  const [tableDisplayData, setTableDisplayData] = useState<any[]>([]); // 화면에 표시된 데이터 (컬럼 순서 포함)

  // 플로우에서 선택된 데이터 (버튼 액션에 전달)
  const [flowSelectedData, setFlowSelectedData] = useState<any[]>([]);
  const [flowSelectedStepId, setFlowSelectedStepId] = useState<number | null>(null);

  // 테이블 새로고침을 위한 키 (값이 변경되면 테이블이 리렌더링됨)
  const [tableRefreshKey, setTableRefreshKey] = useState(0);

  // 플로우 새로고침을 위한 키 (값이 변경되면 플로우 데이터가 리렌더링됨)
  const [flowRefreshKey, setFlowRefreshKey] = useState(0);

  // 🆕 조건부 컨테이너 높이 추적 (컴포넌트 ID → 높이)
  const [conditionalContainerHeights, setConditionalContainerHeights] = useState<Record<string, number>>({});

  // 레이어 시스템 지원
  const [conditionalLayers, setConditionalLayers] = useState<LayerDefinition[]>([]);
  // 조건부 영역(Zone) 목록
  const [zones, setZones] = useState<import("@/types/screen-management").ConditionalZone[]>([]);
  // 데이터 전달에 의해 강제 활성화된 레이어 ID 목록
  const [forceActivatedLayerIds, setForceActivatedLayerIds] = useState<string[]>([]);

  // 편집 모달 상태
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [editModalConfig, setEditModalConfig] = useState<{
    screenId?: number;
    modalSize?: "sm" | "md" | "lg" | "xl" | "full";
    editData?: Record<string, unknown>;
    onSave?: () => void;
    modalTitle?: string;
    modalDescription?: string;
  }>({});

  // 레이아웃 준비 완료 상태 (버튼 위치 계산 완료 후 화면 표시)
  const [layoutReady, setLayoutReady] = useState(true);

  const containerRef = React.useRef<HTMLDivElement>(null);
  const [scale, setScale] = useState(1);
  const [containerWidth, setContainerWidth] = useState(0);

  useEffect(() => {
    const initComponents = async () => {
      try {
        await initializeComponents();
      } catch (error) {
        console.error("❌ 할당된 화면에서 컴포넌트 시스템 초기화 실패:", error);
      }
    };

    initComponents();
  }, []);

  // 편집 모달 이벤트 리스너 등록
  useEffect(() => {
    const handleOpenEditModal = (event: CustomEvent) => {
      // console.log("🎭 편집 모달 열기 이벤트 수신:", event.detail);

      setEditModalConfig({
        screenId: event.detail.screenId,
        modalSize: event.detail.modalSize,
        editData: event.detail.editData,
        onSave: event.detail.onSave,
        modalTitle: event.detail.modalTitle,
        modalDescription: event.detail.modalDescription,
      });
      setEditModalOpen(true);
    };

    // @ts-expect-error - CustomEvent type
    window.addEventListener("openEditModal", handleOpenEditModal);

    return () => {
      // @ts-expect-error - CustomEvent type
      window.removeEventListener("openEditModal", handleOpenEditModal);
    };
  }, []);

  useEffect(() => {
    const loadScreen = async () => {
      try {
        setLoading(true);
        setLayoutReady(false); // 화면 로드 시 레이아웃 준비 초기화
        setError(null);

        // 화면 정보 로드
        const screenData = await screenApi.getScreen(screenId);
        setScreen(screenData);

        // 레이아웃 로드 (V2 우선, Zod 기반 기본값 병합)
        try {
          // V2 API 먼저 시도
          const v2Response = await screenApi.getLayoutV2(screenId);

          if (v2Response && isValidV2Layout(v2Response)) {
            // V2 레이아웃: Zod 기반 변환 (기본값 병합)
            const convertedLayout = convertV2ToLegacy(v2Response);
            if (convertedLayout) {
              setLayout({
                ...convertedLayout,
                screenResolution: v2Response.screenResolution || convertedLayout.screenResolution,
              } as LayoutData);
            } else {
              throw new Error("V2 레이아웃 변환 실패");
            }
          } else {
            // V1 레이아웃 또는 빈 레이아웃
            const layoutData = await screenApi.getLayout(screenId);
            if (layoutData?.components?.length > 0) {
              setLayout(layoutData);
            } else {
              console.warn("[ScreenViewPage] getLayout 실패, getLayerLayout(1) fallback:", screenId);
              const baseLayerData = await screenApi.getLayerLayout(screenId, 1);
              if (baseLayerData && isValidV2Layout(baseLayerData)) {
                const converted = convertV2ToLegacy(baseLayerData);
                if (converted) {
                  setLayout({
                    ...converted,
                    screenResolution: baseLayerData.screenResolution || converted.screenResolution,
                  } as LayoutData);
                } else {
                  setLayout(layoutData);
                }
              } else {
                setLayout(layoutData);
              }
            }
          }
        } catch (layoutError) {
          console.warn("레이아웃 로드 실패, 빈 레이아웃 사용:", layoutError);
          setLayout({
            screenId,
            components: [],
            gridSettings: {
              columns: 12,
              gap: 16,
              padding: 16,
              enabled: true,
              size: 8,
              color: "#e0e0e0",
              opacity: 0.5,
              snapToGrid: true,
            },
          });
        }
      } catch (error) {
        console.error("화면 로드 실패:", error);
        setError("화면을 불러오는데 실패했습니다.");
        showErrorToast("화면을 불러오는 데 실패했습니다", error, { guidance: "화면 설정을 확인하거나 잠시 후 다시 시도해 주세요." });
      } finally {
        setLoading(false);
      }
    };

    if (screenId) {
      loadScreen();
    }
  }, [screenId]);

  // 🆕 조건부 레이어 + Zone 로드
  useEffect(() => {
    const loadConditionalLayersAndZones = async () => {
      if (!screenId || !layout) return;

      try {
        // 1. Zone 로드
        const loadedZones = await screenApi.getScreenZones(screenId);
        setZones(loadedZones);

        // 2. 모든 레이어 목록 조회
        const allLayers = await screenApi.getScreenLayers(screenId);
        const nonBaseLayers = allLayers.filter((l: any) => l.layer_id > 1);

        if (nonBaseLayers.length === 0) {
          setConditionalLayers([]);
          return;
        }

        // 3. 각 레이어의 레이아웃 데이터 로드
        const layerDefinitions: LayerDefinition[] = [];

        for (const layerInfo of nonBaseLayers) {
          try {
            const layerData = await screenApi.getLayerLayout(screenId, layerInfo.layer_id);
            const condConfig = layerInfo.condition_config || layerData?.conditionConfig || {};

            // 레이어 컴포넌트 변환 (V2 → Legacy)
            let layerComponents: any[] = [];
            const rawComponents = layerData?.components;
            if (rawComponents && Array.isArray(rawComponents) && rawComponents.length > 0) {
              const tempV2 = {
                version: "2.0" as const,
                components: rawComponents,
                gridSettings: layerData.gridSettings,
                screenResolution: layerData.screenResolution,
              };
              if (isValidV2Layout(tempV2)) {
                const converted = convertV2ToLegacy(tempV2);
                if (converted) {
                  layerComponents = converted.components || [];
                }
              }
            }

            // Zone 기반 condition_config 처리
            const zoneId = condConfig.zone_id;
            const conditionValue = condConfig.condition_value;
            const zone = zoneId ? loadedZones.find((z: any) => z.zone_id === zoneId) : null;

            // LayerDefinition 생성
            const layerDef: LayerDefinition = {
              id: String(layerInfo.layer_id),
              name: layerInfo.layer_name || `레이어 ${layerInfo.layer_id}`,
              type: "conditional",
              zIndex: layerInfo.layer_id * 10,
              isVisible: false,
              isLocked: false,
              // Zone 기반 조건 (Zone에서 트리거 정보를 가져옴)
              condition: zone ? {
                targetComponentId: zone.trigger_component_id || "",
                operator: (zone.trigger_operator as "eq" | "neq" | "in") || "eq",
                value: conditionValue,
              } : condConfig.targetComponentId ? {
                targetComponentId: condConfig.targetComponentId,
                operator: condConfig.operator || "eq",
                value: condConfig.value,
              } : undefined,
              // Zone 기반: displayRegion은 Zone에서 가져옴
              zoneId: zoneId || undefined,
              conditionValue: conditionValue || undefined,
              displayRegion: zone ? { x: zone.x, y: zone.y, width: zone.width, height: zone.height } : condConfig.displayRegion || undefined,
              components: layerComponents,
            };

            layerDefinitions.push(layerDef);
          } catch (layerError) {
            console.warn(`레이어 ${layerInfo.layer_id} 로드 실패:`, layerError);
          }
        }

        console.log("🔄 조건부 레이어 로드 완료:", layerDefinitions.length, "개", layerDefinitions.map(l => ({
          id: l.id, name: l.name, zoneId: l.zoneId, conditionValue: l.conditionValue,
          componentCount: l.components.length,
          condition: l.condition ? {
            targetComponentId: l.condition.targetComponentId,
            operator: l.condition.operator,
            value: l.condition.value,
          } : "없음",
        })));
        console.log("🗺️ Zone 정보:", loadedZones.map(z => ({
          zone_id: z.zone_id,
          trigger_component_id: z.trigger_component_id,
          trigger_operator: z.trigger_operator,
        })));
        setConditionalLayers(layerDefinitions);
      } catch (error) {
        console.error("레이어/Zone 로드 실패:", error);
      }
    };

    loadConditionalLayersAndZones();
  }, [screenId, layout]);

  // 🆕 조건부 레이어 조건 평가 (formData 변경 시 동기적으로 즉시 계산)
  const activeLayerIds = useMemo(() => {
    if (conditionalLayers.length === 0 || !layout) return [] as string[];

    const allComponents = layout.components || [];
    const newActiveIds: string[] = [];

    conditionalLayers.forEach((layer) => {
      if (layer.condition) {
        const { targetComponentId, operator, value } = layer.condition;

        // 빈 targetComponentId는 무시
        if (!targetComponentId) return;

        // 트리거 컴포넌트 찾기 (기본 레이어에서)
        const targetComponent = allComponents.find((c) => c.id === targetComponentId);

        // columnName으로 formData에서 값 조회
        const fieldKey =
          (targetComponent as any)?.columnName ||
          (targetComponent as any)?.componentConfig?.columnName ||
          targetComponentId;

        const targetValue = formData[fieldKey];

        let isMatch = false;
        switch (operator) {
          case "eq":
            // 문자열로 변환하여 비교 (타입 불일치 방지)
            isMatch = String(targetValue ?? "") === String(value ?? "");
            break;
          case "neq":
            isMatch = String(targetValue ?? "") !== String(value ?? "");
            break;
          case "in":
            if (Array.isArray(value)) {
              isMatch = value.some(v => String(v) === String(targetValue ?? ""));
            } else if (typeof value === "string" && value.includes(",")) {
              // 쉼표로 구분된 문자열도 지원
              isMatch = value.split(",").map(v => v.trim()).includes(String(targetValue ?? ""));
            }
            break;
        }

        // 디버그 로깅 (값이 존재할 때만)
        if (targetValue !== undefined && targetValue !== "") {
          console.log("🔍 [레이어 조건 평가]", {
            layerId: layer.id,
            layerName: layer.name,
            targetComponentId,
            fieldKey,
            targetValue: String(targetValue),
            conditionValue: String(value),
            operator,
            isMatch,
          });
        }

        if (isMatch) {
          newActiveIds.push(layer.id);
        }
      }
    });

    // 강제 활성화된 레이어 ID 병합
    for (const forcedId of forceActivatedLayerIds) {
      if (!newActiveIds.includes(forcedId)) {
        newActiveIds.push(forcedId);
      }
    }

    return newActiveIds;
  }, [formData, conditionalLayers, layout, forceActivatedLayerIds]);

  // 데이터 전달에 의한 레이어 강제 활성화 이벤트 리스너
  useEffect(() => {
    const handleActivateLayer = (e: Event) => {
      const { componentId, targetLayerId } = (e as CustomEvent).detail || {};
      if (!componentId && !targetLayerId) return;

      // targetLayerId가 직접 지정된 경우
      if (targetLayerId) {
        setForceActivatedLayerIds((prev) =>
          prev.includes(targetLayerId) ? prev : [...prev, targetLayerId],
        );
        console.log(`🔓 [레이어 강제 활성화] layerId: ${targetLayerId}`);
        return;
      }

      // componentId로 해당 컴포넌트가 속한 레이어를 찾아 활성화
      for (const layer of conditionalLayers) {
        const found = layer.components.some((comp) => comp.id === componentId);
        if (found) {
          setForceActivatedLayerIds((prev) =>
            prev.includes(layer.id) ? prev : [...prev, layer.id],
          );
          console.log(`🔓 [레이어 강제 활성화] componentId: ${componentId} → layerId: ${layer.id}`);
          return;
        }
      }
    };

    window.addEventListener("activateLayerForComponent", handleActivateLayer);
    return () => {
      window.removeEventListener("activateLayerForComponent", handleActivateLayer);
    };
  }, [conditionalLayers]);

  // 메인 테이블 데이터 자동 로드 (단일 레코드 폼)
  useEffect(() => {
    const loadMainTableData = async () => {
      if (!screen || !layout || !layout.components || !companyCode) {
        return;
      }

      const mainTableName = screen.tableName;
      if (!mainTableName) {
        return;
      }

      // 테이블 위젯이 없는 경우에만 자동 로드 (테이블이 있으면 행 선택으로 데이터 로드)
      const hasTableWidget = layout.components.some(
        (comp: any) => 
          comp.componentType === "table-list" || 
          comp.componentType === "v2-table-list" ||
          comp.widgetType === "table"
      );

      if (hasTableWidget) {
        return;
      }

      // 인풋 컴포넌트들 중 메인 테이블의 컬럼을 사용하는 것들 찾기
      const inputComponents = layout.components.filter((comp: any) => {
        const compType = comp.componentType || comp.widgetType;
        const isInputType = compType?.includes("input") || 
                           compType?.includes("select") || 
                           compType?.includes("textarea") ||
                           compType?.includes("v2-input") ||
                           compType?.includes("v2-select") ||
                           compType?.includes("v2-media") ||
                           compType?.includes("file-upload"); // 🆕 레거시 파일 업로드 포함
        const hasColumnName = !!(comp as any).columnName;
        return isInputType && hasColumnName;
      });

      if (inputComponents.length === 0) {
        return;
      }

      // 메인 테이블에서 현재 회사의 데이터 조회
      try {
        const { tableTypeApi } = await import("@/lib/api/screen");
        
        // company_code로 필터링하여 단일 레코드 조회
        const result = await tableTypeApi.getTableRecord(
          mainTableName,
          "company_code",
          companyCode,
          "*" // 모든 컬럼
        );

        if (result && result.record) {
          console.log("📦 메인 테이블 데이터 자동 로드:", mainTableName, result.record);
          
          // 각 인풋 컴포넌트에 해당하는 데이터 채우기
          const newFormData: Record<string, any> = {};
          inputComponents.forEach((comp: any) => {
            const columnName = comp.columnName;
            if (columnName && result.record[columnName] !== undefined) {
              newFormData[columnName] = result.record[columnName];
            }
          });

          if (Object.keys(newFormData).length > 0) {
            setFormData((prev) => ({
              ...prev,
              ...newFormData,
            }));
          }
        }
      } catch (error) {
        console.log("메인 테이블 자동 로드 실패 (정상일 수 있음):", error);
        // 에러는 무시 - 데이터가 없거나 권한이 없을 수 있음
      }
    };

    loadMainTableData();
  }, [screen, layout, companyCode]);

  // 🆕 개별 autoFill 처리 (메인 테이블과 다른 테이블에서 조회하는 경우)
  useEffect(() => {
    const initAutoFill = async () => {
      if (!layout || !layout.components || !user) {
        return;
      }

      for (const comp of layout.components) {
        // type: "component" 또는 type: "widget" 모두 처리
        if (comp.type === "widget" || comp.type === "component") {
          const widget = comp as any;
          const fieldName = widget.columnName || widget.id;

          // autoFill 처리 (명시적으로 설정된 경우만)
          if (widget.autoFill?.enabled || (comp as any).autoFill?.enabled) {
            const autoFillConfig = widget.autoFill || (comp as any).autoFill;
            const currentValue = formData[fieldName];

            if (currentValue === undefined || currentValue === "") {
              const { sourceTable, filterColumn, userField, displayColumn } = autoFillConfig;

              // 사용자 정보에서 필터 값 가져오기
              const userValue = user?.[userField as keyof typeof user];

              if (userValue && sourceTable && filterColumn && displayColumn) {
                try {
                  const { tableTypeApi } = await import("@/lib/api/screen");
                  const result = await tableTypeApi.getTableRecord(sourceTable, filterColumn, userValue, displayColumn);

                  setFormData((prev) => ({
                    ...prev,
                    [fieldName]: result.value,
                  }));
                } catch (error) {
                  console.error(`autoFill 조회 실패: ${fieldName}`, error);
                }
              }
            }
          }
        }
      }
    };

    initAutoFill();
  }, [layout, user]);

  // 🆕 조건부 비활성화/숨김 시 해당 필드 값 초기화
  // 조건 필드들의 값을 추적하여 변경 시에만 실행
  const conditionalFieldValues = useMemo(() => {
    if (!layout?.components) return "";

    // 조건부 설정에 사용되는 필드들의 현재 값을 JSON 문자열로 만들어 비교
    const conditionFields = new Set<string>();
    layout.components.forEach((component) => {
      const conditional = (component as any).conditional;
      if (conditional?.enabled && conditional.field) {
        conditionFields.add(conditional.field);
      }
    });

    const values: Record<string, any> = {};
    conditionFields.forEach((field) => {
      values[field] = (formData as Record<string, any>)[field];
    });

    return JSON.stringify(values);
  }, [layout?.components, formData]);

  useEffect(() => {
    if (!layout?.components) return;

    const fieldsToReset: string[] = [];

    layout.components.forEach((component) => {
      const conditional = (component as any).conditional;
      if (!conditional?.enabled) return;

      const conditionalResult = evaluateConditional(conditional, formData as Record<string, any>, layout.components);

      // 숨김 또는 비활성화 상태인 경우
      if (!conditionalResult.visible || conditionalResult.disabled) {
        const fieldName = (component as any).columnName || component.id;
        const currentValue = (formData as Record<string, any>)[fieldName];

        // 값이 있으면 초기화 대상에 추가
        if (currentValue !== undefined && currentValue !== "" && currentValue !== null) {
          fieldsToReset.push(fieldName);
        }
      }
    });

    // 초기화할 필드가 있으면 한 번에 처리
    if (fieldsToReset.length > 0) {
      setFormData((prev) => {
        const updated = { ...prev };
        fieldsToReset.forEach((fieldName) => {
          updated[fieldName] = "";
        });
        return updated;
      });
    }
  }, [conditionalFieldValues, layout?.components]);

  // 캔버스 비율 조정 (사용자 화면에 맞게 자동 스케일) - 초기 로딩 시에만 계산
  // 브라우저 배율 조정 시 메뉴와 화면이 함께 축소/확대되도록 resize 이벤트는 감지하지 않음
  useEffect(() => {
    // 모바일 환경에서는 스케일 조정 비활성화 (반응형만 작동)
    if (isMobile) {
      setScale(1);
      setLayoutReady(true); // 모바일에서도 레이아웃 준비 완료 표시
      return;
    }

    const updateScale = () => {
      if (containerRef.current && layout) {
        const designWidth = layout?.screenResolution?.width || 1200;
        const designHeight = layout?.screenResolution?.height || 800;

        // 컨테이너의 실제 크기 (프리뷰 모드에서는 window 크기 사용)
        let containerWidth: number;
        let containerHeight: number;

        if (isPreviewMode) {
          // iframe에서는 window 크기를 직접 사용
          containerWidth = window.innerWidth;
          containerHeight = window.innerHeight;
        } else {
          containerWidth = containerRef.current.offsetWidth;
          containerHeight = containerRef.current.offsetHeight;
        }

        let newScale: number;

        if (isPreviewMode) {
          // 프리뷰 모드: 가로/세로 모두 fit하도록 (여백 없이)
          const scaleX = containerWidth / designWidth;
          const scaleY = containerHeight / designHeight;
          newScale = Math.min(scaleX, scaleY, 1); // 최대 1배율
        } else {
          // 일반 모드: 가로 기준 스케일 (좌우 여백 16px씩 고정)
          const MARGIN_X = 32;
          const availableWidth = containerWidth - MARGIN_X;
          newScale = availableWidth / designWidth;
        }

        // console.log("📐 스케일 계산:", {
        //   containerWidth,
        //   containerHeight,
        //   designWidth,
        //   designHeight,
        //   finalScale: newScale,
        //   isPreviewMode,
        // });

        setScale(newScale);
        // 컨테이너 너비 업데이트
        setContainerWidth(containerWidth);

        // 스케일 계산 완료 후 레이아웃 준비 완료 표시
        setLayoutReady(true);
      }
    };

    // 초기 측정 (한 번만 실행)
    const timer = setTimeout(updateScale, 100);

    // resize 이벤트는 감지하지 않음 - 브라우저 배율 조정 시 메뉴와 화면이 함께 변경되도록
    return () => {
      clearTimeout(timer);
    };
  }, [layout, isMobile, isPreviewMode]);

  if (loading) {
    return (
      <div className="from-muted to-muted/50 flex h-full min-h-[400px] w-full items-center justify-center bg-gradient-to-br">
        <div className="border-border bg-background rounded-xl border p-8 text-center shadow-lg">
          <Loader2 className="text-primary mx-auto h-10 w-10 animate-spin" />
          <p className="text-foreground mt-4 font-medium">화면을 불러오는 중...</p>
        </div>
      </div>
    );
  }

  if (error || !screen) {
    return (
      <div className="from-muted to-muted/50 flex h-full min-h-[400px] w-full items-center justify-center bg-gradient-to-br">
        <div className="border-border bg-background max-w-md rounded-xl border p-8 text-center shadow-lg">
          <div className="from-destructive/20 to-warning/20 mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br shadow-sm">
            <span className="text-3xl">⚠️</span>
          </div>
          <h2 className="text-foreground mb-3 text-xl font-bold">화면을 찾을 수 없습니다</h2>
          <p className="text-muted-foreground mb-6 leading-relaxed">{error || "요청하신 화면이 존재하지 않습니다."}</p>
          <Button onClick={() => router.back()} variant="outline" className="rounded-lg">
            이전으로 돌아가기
          </Button>
        </div>
      </div>
    );
  }

  // 화면 해상도 정보가 있으면 해당 크기로, 없으면 기본 크기 사용
  const screenWidth = layout?.screenResolution?.width || 1200;
  const screenHeight = layout?.screenResolution?.height || 800;

  return (
    <ScreenPreviewProvider isPreviewMode={false}>
      <ActiveTabProvider>
        <TableOptionsProvider>
          <div
            ref={containerRef}
            className={`bg-background h-full w-full ${isPreviewMode ? "overflow-hidden p-0" : "overflow-auto p-3"}`}
          >
            {/* 레이아웃 준비 중 로딩 표시 */}
            {!layoutReady && (
              <div className="from-muted to-muted/50 flex h-full w-full items-center justify-center bg-gradient-to-br">
                <div className="border-border bg-background rounded-xl border p-8 text-center shadow-lg">
                  <Loader2 className="text-primary mx-auto h-8 w-8 animate-spin" />
                  <p className="text-foreground mt-4 text-sm font-medium">화면 준비 중...</p>
                </div>
              </div>
            )}

            {/* 절대 위치 기반 렌더링 (화면관리와 동일한 방식) */}
            {layoutReady && layout && layout.components.length > 0 ? (
              <ScreenMultiLangProvider components={layout.components} companyCode={companyCode}>
                <div
                  data-screen-runtime="true"
                  className="bg-background relative"
                  style={{
                    width: `${screenWidth}px`,
                    height: `${screenHeight}px`,
                    minWidth: `${screenWidth}px`,
                    maxWidth: `${screenWidth}px`,
                    minHeight: `${screenHeight}px`,
                    maxHeight: `${screenHeight}px`,
                    flexShrink: 0,
                    transform: `scale(${scale})`,
                    transformOrigin: "top left",
                    overflow: "visible",
                  }}
                >
                  {/* 최상위 컴포넌트들 렌더링 */}
                  {(() => {
                    // 🆕 플로우 버튼 그룹 감지 및 처리
                    const topLevelComponents = layout.components.filter((component) => !component.parentId);

                    // 화면 관리에서 설정한 해상도를 사용하므로 widthOffset 계산 불필요
                    // 모든 컴포넌트는 원본 위치 그대로 사용
                    const widthOffset = 0;

                    const buttonGroups: Record<string, any[]> = {};
                    const processedButtonIds = new Set<string>();
                    // 🔍 전체 버튼 목록 확인
                    const allButtons = topLevelComponents.filter((component) => {
                      const isButton =
                        (component.type === "component" &&
                          ["button-primary", "button-secondary"].includes((component as any).componentType)) ||
                        (component.type === "widget" && (component as any).widgetType === "button");
                      return isButton;
                    });

                    topLevelComponents.forEach((component) => {
                      const isButton =
                        (component.type === "component" &&
                          ["button-primary", "button-secondary"].includes((component as any).componentType)) ||
                        (component.type === "widget" && (component as any).widgetType === "button");

                      if (isButton) {
                        const flowConfig = (component as any).webTypeConfig?.flowVisibilityConfig as
                          | FlowVisibilityConfig
                          | undefined;

                        // 🔧 임시: 버튼 그룹 기능 완전 비활성화
                        // TODO: 사용자가 명시적으로 그룹을 원하는 경우에만 활성화하도록 UI 개선 필요
                        const DISABLE_BUTTON_GROUPS = false;

                        if (
                          !DISABLE_BUTTON_GROUPS &&
                          flowConfig?.enabled &&
                          flowConfig.layoutBehavior === "auto-compact" &&
                          flowConfig.groupId
                        ) {
                          if (!buttonGroups[flowConfig.groupId]) {
                            buttonGroups[flowConfig.groupId] = [];
                          }
                          buttonGroups[flowConfig.groupId].push(component);
                          processedButtonIds.add(component.id);
                        }
                        // else: 모든 버튼을 개별 렌더링
                      }
                    });

                    const regularComponents = topLevelComponents.filter((c) => !processedButtonIds.has(c.id));

                    // TableSearchWidget들을 먼저 찾기
                    const tableSearchWidgets = regularComponents.filter(
                      (c) => (c as any).componentId === "table-search-widget",
                    );

                    // 조건부 컨테이너들을 찾기
                    const conditionalContainers = regularComponents.filter(
                      (c) =>
                        (c as any).componentId === "conditional-container" ||
                        (c as any).componentType === "conditional-container",
                    );

                    // 🆕 같은 X 영역(섹션)에서 컴포넌트들이 겹치지 않도록 자동 수직 정렬
                    // ⚠️ V2 레이아웃에서는 사용자가 배치한 위치를 존중하므로 자동 정렬 비활성화
                    const autoLayoutComponents = regularComponents;

                    // TableSearchWidget 및 조건부 컨테이너 높이 차이를 계산하여 Y 위치 추가 조정
                    const adjustedComponents = autoLayoutComponents.map((component) => {
                      const isTableSearchWidget = (component as any).componentId === "table-search-widget";
                      const isConditionalContainer = (component as any).componentId === "conditional-container";

                      if (isTableSearchWidget || isConditionalContainer) {
                        // 자기 자신은 조정하지 않음
                        return component;
                      }

                      let totalHeightAdjustment = 0;

                      // TableSearchWidget 높이 조정
                      for (const widget of tableSearchWidgets) {
                        const isBelow = component.position.y > widget.position.y;
                        const heightDiff = getHeightDiff(screenId, widget.id);

                        if (isBelow && heightDiff > 0) {
                          totalHeightAdjustment += heightDiff;
                        }
                      }

                      // 조건부 컨테이너 높이 조정
                      for (const container of conditionalContainers) {
                        const isBelow = component.position.y > container.position.y;
                        const actualHeight = conditionalContainerHeights[container.id];
                        const originalHeight = container.size?.height || 200;
                        const heightDiff = actualHeight ? actualHeight - originalHeight : 0;

                        if (isBelow && heightDiff > 0) {
                          totalHeightAdjustment += heightDiff;
                        }
                      }

                      // 🆕 Zone 기반 높이 조정
                      // Zone 단위로 활성 여부를 판단하여 Y 오프셋 계산
                      // Zone은 겹치지 않으므로 merge 로직이 불필요 (단순 boolean 판단)
                      for (const zone of zones) {
                        const zoneBottom = zone.y + zone.height;
                        // 컴포넌트가 Zone 하단보다 아래에 있는 경우
                        if (component.position.y >= zoneBottom) {
                          // Zone에 매칭되는 활성 레이어가 있는지 확인
                          const hasActiveLayer = conditionalLayers.some(
                            l => l.zoneId === zone.zone_id && activeLayerIds.includes(l.id)
                          );
                          if (!hasActiveLayer) {
                            // Zone에 활성 레이어 없음: Zone 높이만큼 위로 당김 (빈 공간 제거)
                            totalHeightAdjustment -= zone.height;
                          }
                        }
                      }

                      if (totalHeightAdjustment !== 0) {
                        return {
                          ...component,
                          position: {
                            ...component.position,
                            y: component.position.y + totalHeightAdjustment,
                          },
                        };
                      }

                      return component;
                    });

                    return (
                      <>
                        {/* 일반 컴포넌트들 */}
                        {adjustedComponents.map((component) => {
                          // 조건부 표시 설정이 있는 경우에만 평가
                          const conditional = (component as any).conditional;
                          let conditionalDisabled = false;

                          if (conditional?.enabled) {
                            const conditionalResult = evaluateConditional(
                              conditional,
                              formData as Record<string, any>,
                              layout?.components || [],
                            );

                            // 조건에 따라 숨김 처리
                            if (!conditionalResult.visible) {
                              return null;
                            }

                            // 조건에 따라 비활성화 처리
                            conditionalDisabled = conditionalResult.disabled;
                          }

                          // 화면 관리 해상도를 사용하므로 위치 조정 불필요
                          return (
                            <RealtimePreview
                              conditionalDisabled={conditionalDisabled}
                              key={component.id}
                              component={component}
                              isSelected={false}
                              isDesignMode={false}
                              onClick={() => {}}
                              menuObjid={menuObjid}
                              screenId={screenId}
                              tableName={screen?.tableName}
                              userId={user?.userId}
                              userName={userName}
                              companyCode={companyCode}
                              menuObjid={menuObjid}
                              selectedRowsData={selectedRowsData}
                              sortBy={tableSortBy}
                              sortOrder={tableSortOrder}
                              columnOrder={tableColumnOrder}
                              tableDisplayData={tableDisplayData}
                              onSelectedRowsChange={(
                                _,
                                selectedData,
                                sortBy,
                                sortOrder,
                                columnOrder,
                                tableDisplayData,
                              ) => {
                                setSelectedRowsData(selectedData);
                                setTableSortBy(sortBy);
                                setTableSortOrder(sortOrder || "asc");
                                setTableColumnOrder(columnOrder);
                                setTableDisplayData(tableDisplayData || []);
                              }}
                              flowSelectedData={flowSelectedData}
                              flowSelectedStepId={flowSelectedStepId}
                              onFlowSelectedDataChange={(selectedData: any[], stepId: number | null) => {
                                setFlowSelectedData(selectedData);
                                setFlowSelectedStepId(stepId);
                              }}
                              refreshKey={tableRefreshKey}
                              onRefresh={() => {
                                setTableRefreshKey((prev) => prev + 1);
                                setSelectedRowsData([]); // 선택 해제
                              }}
                              flowRefreshKey={flowRefreshKey}
                              onFlowRefresh={() => {
                                setFlowRefreshKey((prev) => prev + 1);
                                setFlowSelectedData([]); // 선택 해제
                                setFlowSelectedStepId(null);
                              }}
                              formData={formData}
                              onFormDataChange={(fieldName, value) => {
                                setFormData((prev) => ({ ...prev, [fieldName]: value }));
                              }}
                              onHeightChange={(componentId, newHeight) => {
                                setConditionalContainerHeights((prev) => ({
                                  ...prev,
                                  [componentId]: newHeight,
                                }));
                              }}
                            >
                              {/* 자식 컴포넌트들 */}
                              {(component.type === "group" ||
                                component.type === "container" ||
                                component.type === "area") &&
                                layout.components
                                  .filter((child) => child.parentId === component.id)
                                  .map((child) => {
                                    // 자식 컴포넌트의 위치를 부모 기준 상대 좌표로 조정
                                    const relativeChildComponent = {
                                      ...child,
                                      position: {
                                        x: child.position.x - component.position.x,
                                        y: child.position.y - component.position.y,
                                        z: child.position.z || 1,
                                      },
                                    };

                                    return (
                                      <RealtimePreview
                                        key={child.id}
                                        component={relativeChildComponent}
                                        isSelected={false}
                                        isDesignMode={false}
                                        onClick={() => {}}
                                        menuObjid={menuObjid}
                                        screenId={screenId}
                                        tableName={screen?.tableName}
                                        userId={user?.userId}
                                        userName={userName}
                                        companyCode={companyCode}
                                        menuObjid={menuObjid}
                                        selectedRowsData={selectedRowsData}
                                        sortBy={tableSortBy}
                                        sortOrder={tableSortOrder}
                                        columnOrder={tableColumnOrder}
                                        tableDisplayData={tableDisplayData}
                                        onSelectedRowsChange={(
                                          _,
                                          selectedData,
                                          sortBy,
                                          sortOrder,
                                          columnOrder,
                                          tableDisplayData,
                                        ) => {
                                          setSelectedRowsData(selectedData);
                                          setTableSortBy(sortBy);
                                          setTableSortOrder(sortOrder || "asc");
                                          setTableColumnOrder(columnOrder);
                                          setTableDisplayData(tableDisplayData || []);
                                        }}
                                        refreshKey={tableRefreshKey}
                                        onRefresh={() => {
                                          setTableRefreshKey((prev) => prev + 1);
                                          setSelectedRowsData([]); // 선택 해제
                                        }}
                                        formData={formData}
                                        onFormDataChange={(fieldName, value) => {
                                          setFormData((prev) => ({ ...prev, [fieldName]: value }));
                                        }}
                                      />
                                    );
                                  })}
                            </RealtimePreview>
                          );
                        })}

                        {/* 🆕 플로우 버튼 그룹들 */}
                        {Object.entries(buttonGroups).map(([groupId, buttons]) => {
                          if (buttons.length === 0) return null;

                          const firstButton = buttons[0];
                          const groupConfig = (firstButton as any).webTypeConfig
                            ?.flowVisibilityConfig as FlowVisibilityConfig;

                          // 🔍 버튼 그룹 설정 확인
                          console.log("🔍 버튼 그룹 설정:", {
                            groupId,
                            buttonCount: buttons.length,
                            buttons: buttons.map((b) => ({
                              id: b.id,
                              label: b.label,
                              x: b.position.x,
                              y: b.position.y,
                            })),
                            groupConfig: {
                              layoutBehavior: groupConfig.layoutBehavior,
                              groupDirection: groupConfig.groupDirection,
                              groupAlign: groupConfig.groupAlign,
                              groupGap: groupConfig.groupGap,
                            },
                          });

                          // 🔧 수정: 그룹 컨테이너는 첫 번째 버튼 위치를 기준으로 하되,
                          // 각 버튼의 상대 위치는 원래 위치를 유지
                          const firstButtonPosition = {
                            x: buttons[0].position.x,
                            y: buttons[0].position.y,
                            z: buttons[0].position.z || 2,
                          };

                          // 버튼 그룹 위치에도 widthOffset 적용
                          const adjustedGroupPosition = {
                            ...firstButtonPosition,
                            x: firstButtonPosition.x + widthOffset,
                          };

                          // 그룹의 크기 계산: 버튼들의 실제 크기 + 간격을 기준으로 계산
                          const direction = groupConfig.groupDirection || "horizontal";
                          const gap = groupConfig.groupGap ?? 8;

                          let groupWidth = 0;
                          let groupHeight = 0;

                          if (direction === "horizontal") {
                            groupWidth = buttons.reduce((total, button, index) => {
                              const buttonWidth = button.size?.width || 100;
                              const gapWidth = index < buttons.length - 1 ? gap : 0;
                              return total + buttonWidth + gapWidth;
                            }, 0);
                            groupHeight = Math.max(...buttons.map((b) => b.size?.height || 40));
                          } else {
                            groupWidth = Math.max(...buttons.map((b) => b.size?.width || 100));
                            groupHeight = buttons.reduce((total, button, index) => {
                              const buttonHeight = button.size?.height || 40;
                              const gapHeight = index < buttons.length - 1 ? gap : 0;
                              return total + buttonHeight + gapHeight;
                            }, 0);
                          }

                          return (
                            <div
                              key={`flow-button-group-${groupId}`}
                              style={{
                                position: "absolute",
                                left: `${adjustedGroupPosition.x}px`,
                                top: `${adjustedGroupPosition.y}px`,
                                zIndex: adjustedGroupPosition.z,
                                width: `${groupWidth}px`,
                                height: `${groupHeight}px`,
                              }}
                            >
                              <FlowButtonGroup
                                buttons={buttons}
                                groupConfig={groupConfig}
                                isDesignMode={false}
                                renderButton={(button) => {
                                  // 🔧 각 버튼의 상대 위치 = 버튼의 원래 위치 - 첫 번째 버튼 위치
                                  const relativeButton = {
                                    ...button,
                                    position: {
                                      x: button.position.x - firstButtonPosition.x,
                                      y: button.position.y - firstButtonPosition.y,
                                      z: button.position.z || 1,
                                    },
                                  };

                                  return (
                                    <div
                                      key={button.id}
                                      style={{
                                        position: "relative",
                                        display: "inline-block",
                                        width: button.size?.width || 100,
                                        minWidth: button.size?.width || 100,
                                        height: button.size?.height || 40,
                                        flexShrink: 0,
                                      }}
                                    >
                                      <div style={{ width: "100%", height: "100%" }}>
                                        <DynamicComponentRenderer
                                          component={relativeButton}
                                          isDesignMode={false}
                                          isInteractive={true}
                                          formData={formData}
                                          onDataflowComplete={() => {}}
                                          screenId={screenId}
                                          tableName={screen?.tableName}
                                          userId={user?.userId}
                                          userName={userName}
                                          companyCode={companyCode}
                                          tableDisplayData={tableDisplayData}
                                          selectedRowsData={selectedRowsData}
                                          sortBy={tableSortBy}
                                          sortOrder={tableSortOrder}
                                          columnOrder={tableColumnOrder}
                                          onSelectedRowsChange={(_, selectedData, sortBy, sortOrder, columnOrder) => {
                                            setSelectedRowsData(selectedData);
                                            setTableSortBy(sortBy);
                                            setTableSortOrder(sortOrder || "asc");
                                            setTableColumnOrder(columnOrder);
                                          }}
                                          flowSelectedData={flowSelectedData}
                                          flowSelectedStepId={flowSelectedStepId}
                                          onFlowSelectedDataChange={(selectedData: any[], stepId: number | null) => {
                                            setFlowSelectedData(selectedData);
                                            setFlowSelectedStepId(stepId);
                                          }}
                                          refreshKey={tableRefreshKey}
                                          onRefresh={() => {
                                            setTableRefreshKey((prev) => prev + 1);
                                            setSelectedRowsData([]);
                                          }}
                                          flowRefreshKey={flowRefreshKey}
                                          onFlowRefresh={() => {
                                            setFlowRefreshKey((prev) => prev + 1);
                                            setFlowSelectedData([]);
                                            setFlowSelectedStepId(null);
                                          }}
                                          onFormDataChange={(fieldName, value) => {
                                            setFormData((prev) => ({ ...prev, [fieldName]: value }));
                                          }}
                                        />
                                      </div>
                                    </div>
                                  );
                                }}
                              />
                            </div>
                          );
                        })}

                        {/* 🆕 조건부 레이어 컴포넌트 렌더링 (Zone 기반) */}
                        {conditionalLayers.map((layer) => {
                          const isActive = activeLayerIds.includes(layer.id);
                          if (!isActive || !layer.components || layer.components.length === 0) return null;

                          // Zone 기반: zoneId로 Zone 찾아서 위치/크기 결정
                          const zone = layer.zoneId ? zones.find(z => z.zone_id === layer.zoneId) : null;
                          const region = zone 
                            ? { x: zone.x, y: zone.y, width: zone.width, height: zone.height }
                            : layer.displayRegion;

                          return (
                            <div
                              key={`conditional-layer-${layer.id}`}
                              data-conditional-layer="true"
                              style={{
                                position: "absolute",
                                left: region ? `${region.x}px` : "0px",
                                top: region ? `${region.y}px` : "0px",
                                width: region ? `${region.width}px` : "100%",
                                height: region ? `${region.height}px` : "auto",
                                zIndex: layer.zIndex || 20,
                                overflow: "hidden",
                                transition: "none",
                              }}
                            >
                              {layer.components
                                .filter((comp) => !comp.parentId)
                                .map((comp) => (
                                  <RealtimePreview
                                    key={comp.id}
                                    component={comp}
                                    isSelected={false}
                                    isDesignMode={false}
                                    onClick={() => {}}
                                    menuObjid={menuObjid}
                                    screenId={screenId}
                                    tableName={screen?.tableName}
                                    userId={user?.userId}
                                    userName={userName}
                                    companyCode={companyCode}
                                    selectedRowsData={selectedRowsData}
                                    sortBy={tableSortBy}
                                    sortOrder={tableSortOrder}
                                    columnOrder={tableColumnOrder}
                                    tableDisplayData={tableDisplayData}
                                    onSelectedRowsChange={(
                                      _,
                                      selectedData,
                                      sortBy,
                                      sortOrder,
                                      columnOrder,
                                      tableDisplayData,
                                    ) => {
                                      setSelectedRowsData(selectedData);
                                      setTableSortBy(sortBy);
                                      setTableSortOrder(sortOrder || "asc");
                                      setTableColumnOrder(columnOrder);
                                      setTableDisplayData(tableDisplayData || []);
                                    }}
                                    refreshKey={tableRefreshKey}
                                    onRefresh={() => {
                                      setTableRefreshKey((prev) => prev + 1);
                                      setSelectedRowsData([]);
                                    }}
                                    formData={formData}
                                    onFormDataChange={(fieldName, value) => {
                                      setFormData((prev) => ({ ...prev, [fieldName]: value }));
                                    }}
                                  />
                                ))}
                            </div>
                          );
                        })}
                      </>
                    );
                  })()}
                </div>
              </ScreenMultiLangProvider>
            ) : (
              // 빈 화면일 때
              <div className="bg-background flex items-center justify-center" style={{ minHeight: screenHeight }}>
                <div className="text-center">
                  <div className="bg-muted mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full shadow-sm">
                    <span className="text-2xl">📄</span>
                  </div>
                  <h2 className="text-foreground mb-2 text-xl font-semibold">화면이 비어있습니다</h2>
                  <p className="text-muted-foreground">이 화면에는 아직 설계된 컴포넌트가 없습니다.</p>
                </div>
              </div>
            )}

            {/* 편집 모달 */}
            <EditModal
              isOpen={editModalOpen}
              onClose={() => {
                setEditModalOpen(false);
                setEditModalConfig({});
              }}
              screenId={editModalConfig.screenId}
              modalSize={editModalConfig.modalSize}
              editData={editModalConfig.editData}
              onSave={editModalConfig.onSave}
              modalTitle={editModalConfig.modalTitle}
              modalDescription={editModalConfig.modalDescription}
              onDataChange={(changedFormData) => {
                console.log("📝 EditModal에서 데이터 변경 수신:", changedFormData);
                // 변경된 데이터를 메인 폼에 반영
                setFormData((prev) => {
                  const updatedFormData = {
                    ...prev,
                    ...changedFormData, // 변경된 필드들만 업데이트
                  };
                  console.log("📊 메인 폼 데이터 업데이트:", updatedFormData);
                  return updatedFormData;
                });
              }}
            />

            {/* 스케줄 생성 확인 다이얼로그 */}
            <ScheduleConfirmDialog
              open={showConfirmDialog}
              onOpenChange={(open) => !open && closeDialog()}
              preview={previewResult}
              onConfirm={() => handleConfirm(true)}
              onCancel={closeDialog}
              isLoading={scheduleLoading}
            />
          </div>
        </TableOptionsProvider>
      </ActiveTabProvider>
    </ScreenPreviewProvider>
  );
}

// 실제 컴포넌트를 Provider로 감싸기
function ScreenViewPageWrapper() {
  return (
    <TableSearchWidgetHeightProvider>
      <ScreenContextProvider>
        <SplitPanelProvider>
          <ScreenViewPage />
        </SplitPanelProvider>
      </ScreenContextProvider>
    </TableSearchWidgetHeightProvider>
  );
}

export default ScreenViewPageWrapper;
