"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Checkbox } from "@/components/ui/checkbox";
import { useAuth } from "@/hooks/useAuth";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { 
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle, 
  DialogFooter,
  DialogDescription,
} from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import { MoreHorizontal, Edit, Trash2, Copy, Eye, Plus, Search, Palette, RotateCcw, Trash, Check, ChevronsUpDown } from "lucide-react";
import { ScreenDefinition } from "@/types/screen";
import { screenApi } from "@/lib/api/screen";
import { ExternalRestApiConnectionAPI, ExternalRestApiConnection } from "@/lib/api/externalRestApiConnection";
import { getScreenGroups, ScreenGroup } from "@/lib/api/screenGroup";
import { Layers } from "lucide-react";
import CreateScreenModal from "./CreateScreenModal";
import CopyScreenModal from "./CopyScreenModal";
import dynamic from "next/dynamic";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";
import { DynamicWebTypeRenderer } from "@/lib/registry";
import { isFileComponent, getComponentWebType } from "@/lib/utils/componentTypeUtils";
import { TableOptionsProvider } from "@/contexts/TableOptionsContext";
import { RealtimePreview } from "./RealtimePreviewDynamic";
import { ScreenPreviewProvider } from "@/contexts/ScreenPreviewContext";
import { showErrorToast } from "@/lib/utils/toastUtils";

// InteractiveScreenViewer를 동적으로 import (SSR 비활성화)
const InteractiveScreenViewer = dynamic(
  () => import("./InteractiveScreenViewer").then((mod) => mod.InteractiveScreenViewer),
  {
    ssr: false,
    loading: () => <div className="flex items-center justify-center p-8">로딩 중...</div>,
  },
);

interface ScreenListProps {
  onScreenSelect: (screen: ScreenDefinition) => void;
  selectedScreen: ScreenDefinition | null;
  onDesignScreen: (screen: ScreenDefinition) => void;
}

type DeletedScreenDefinition = ScreenDefinition & {
  deletedDate?: Date;
  deletedBy?: string;
  deleteReason?: string;
};

export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScreen }: ScreenListProps) {
  const { user, switchCompany } = useAuth();
  const isSuperAdmin = user?.userType === "SUPER_ADMIN" || user?.companyCode === "*";

  const [activeTab, setActiveTab] = useState("active");
  const [screens, setScreens] = useState<ScreenDefinition[]>([]);
  const [deletedScreens, setDeletedScreens] = useState<DeletedScreenDefinition[]>([]);
  const [loading, setLoading] = useState(true); // 초기 로딩
  const [isSearching, setIsSearching] = useState(false); // 검색 중 로딩 (포커스 유지)
  const [searchTerm, setSearchTerm] = useState("");
  const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
  const [selectedCompanyCode, setSelectedCompanyCode] = useState<string>("all");
  const [companies, setCompanies] = useState<any[]>([]);
  const [loadingCompanies, setLoadingCompanies] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [isCopyOpen, setIsCopyOpen] = useState(false);
  const [screenToCopy, setScreenToCopy] = useState<ScreenDefinition | null>(null);

  // 그룹 필터 관련 상태
  const [selectedGroupId, setSelectedGroupId] = useState<string>("all");
  const [groups, setGroups] = useState<ScreenGroup[]>([]);
  const [loadingGroups, setLoadingGroups] = useState(false);

  // 검색어 디바운스를 위한 타이머 ref
  const debounceTimer = useRef<NodeJS.Timeout | null>(null);
  
  // 첫 로딩 여부를 추적 (한 번만 true)
  const isFirstLoad = useRef(true);

  // 삭제 관련 상태
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [screenToDelete, setScreenToDelete] = useState<ScreenDefinition | null>(null);
  const [deleteReason, setDeleteReason] = useState("");
  const [dependencies, setDependencies] = useState<
    Array<{
      screenId: number;
      screenName: string;
      screenCode: string;
      componentId: string;
      componentType: string;
      referenceType: string;
    }>
  >([]);
  const [showDependencyWarning, setShowDependencyWarning] = useState(false);
  const [checkingDependencies, setCheckingDependencies] = useState(false);

  // 영구 삭제 관련 상태
  const [permanentDeleteDialogOpen, setPermanentDeleteDialogOpen] = useState(false);
  const [screenToPermanentDelete, setScreenToPermanentDelete] = useState<DeletedScreenDefinition | null>(null);

  // 휴지통 일괄삭제 관련 상태
  const [selectedScreenIds, setSelectedScreenIds] = useState<number[]>([]);
  const [bulkDeleteDialogOpen, setBulkDeleteDialogOpen] = useState(false);
  const [bulkDeleting, setBulkDeleting] = useState(false);

  // 활성 화면 일괄삭제 관련 상태
  const [selectedActiveScreenIds, setSelectedActiveScreenIds] = useState<number[]>([]);
  const [activeBulkDeleteDialogOpen, setActiveBulkDeleteDialogOpen] = useState(false);
  const [activeBulkDeleteReason, setActiveBulkDeleteReason] = useState("");
  const [activeBulkDeleting, setActiveBulkDeleting] = useState(false);

  // 편집 관련 상태
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [screenToEdit, setScreenToEdit] = useState<ScreenDefinition | null>(null);
  const [editFormData, setEditFormData] = useState({
    screenName: "",
    description: "",
    isActive: "Y",
    tableName: "",
    dataSourceType: "database" as "database" | "restapi",
    restApiConnectionId: null as number | null,
    restApiEndpoint: "",
    restApiJsonPath: "data",
  });
  const [tables, setTables] = useState<Array<{ tableName: string; tableLabel: string }>>([]);
  const [loadingTables, setLoadingTables] = useState(false);
  const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
  
  // REST API 연결 관련 상태 (편집용)
  const [editRestApiConnections, setEditRestApiConnections] = useState<ExternalRestApiConnection[]>([]);
  const [editRestApiComboboxOpen, setEditRestApiComboboxOpen] = useState(false);

  // 미리보기 관련 상태
  const [previewDialogOpen, setPreviewDialogOpen] = useState(false);
  const [screenToPreview, setScreenToPreview] = useState<ScreenDefinition | null>(null);
  const [previewLayout, setPreviewLayout] = useState<any>(null);
  const [isLoadingPreview, setIsLoadingPreview] = useState(false);
  const [previewFormData, setPreviewFormData] = useState<Record<string, any>>({});

  // 최고 관리자인 경우 회사 목록 로드
  useEffect(() => {
    if (isSuperAdmin) {
      loadCompanies();
    }
  }, [isSuperAdmin]);

  const loadCompanies = async () => {
    try {
      setLoadingCompanies(true);
      const { apiClient } = await import("@/lib/api/client"); // named export
      const response = await apiClient.get("/admin/companies");
      const data = response.data.data || response.data || [];
      setCompanies(data.map((c: any) => ({
        companyCode: c.company_code || c.companyCode,
        companyName: c.company_name || c.companyName,
      })));
    } catch (error) {
      console.error("회사 목록 조회 실패:", error);
    } finally {
      setLoadingCompanies(false);
    }
  };

  // 🔧 회사 선택 시 회사 전환 (JWT 토큰 변경)
  const handleCompanySelect = async (companyCode: string) => {
    setSelectedCompanyCode(companyCode);
    
    // "all"은 전체 조회이므로 회사 전환하지 않음 (최고 관리자 상태 유지)
    if (companyCode && companyCode !== "all") {
      const result = await switchCompany(companyCode);
      if (!result.success) {
        console.error("회사 전환 실패:", result.message);
        return;
      }
      // 🔧 페이지 새로고침으로 새 JWT 확실하게 적용
      window.location.reload();
    } else if (companyCode === "all") {
      // "전체 회사" 선택 시 최고 관리자 모드로 복귀
      const result = await switchCompany("*");
      if (!result.success) {
        console.error("최고 관리자 모드 복귀 실패:", result.message);
        return;
      }
      // 🔧 페이지 새로고침으로 새 JWT 확실하게 적용
      window.location.reload();
    }
  };

  // 화면 그룹 목록 로드
  useEffect(() => {
    loadGroups();
  }, []);

  const loadGroups = async () => {
    try {
      setLoadingGroups(true);
      const response = await getScreenGroups({ excludePop: true });
      if (response.success && response.data) {
        setGroups(response.data);
      }
    } catch (error) {
      console.error("그룹 목록 조회 실패:", error);
    } finally {
      setLoadingGroups(false);
    }
  };

  // 검색어 디바운스 처리 (150ms 지연 - 빠른 응답)
  useEffect(() => {
    // 이전 타이머 취소
    if (debounceTimer.current) {
      clearTimeout(debounceTimer.current);
    }

    // 새 타이머 설정
    debounceTimer.current = setTimeout(() => {
      setDebouncedSearchTerm(searchTerm);
    }, 150);

    // 클린업
    return () => {
      if (debounceTimer.current) {
        clearTimeout(debounceTimer.current);
      }
    };
  }, [searchTerm]);

  // 화면 목록 로드 (실제 API) - debouncedSearchTerm 사용
  useEffect(() => {
    let abort = false;
    const load = async () => {
      try {
        // 첫 로딩인 경우에만 loading=true, 그 외에는 isSearching=true
        if (isFirstLoad.current) {
          setLoading(true);
          isFirstLoad.current = false; // 첫 로딩 완료 표시
        } else {
          setIsSearching(true);
        }

        if (activeTab === "active") {
          const params: any = { page: currentPage, size: 20, searchTerm: debouncedSearchTerm };
          
          // 최고 관리자이고 특정 회사를 선택한 경우
          if (isSuperAdmin && selectedCompanyCode !== "all") {
            params.companyCode = selectedCompanyCode;
          }

          // 그룹 필터
          if (selectedGroupId !== "all") {
            params.groupId = selectedGroupId;
          }

          console.log("🔍 화면 목록 API 호출:", params); // 디버깅용
          const resp = await screenApi.getScreens(params);
          console.log("✅ 화면 목록 응답:", resp); // 디버깅용
          
          if (abort) return;
          setScreens(resp.data || []);
          setTotalPages(Math.max(1, Math.ceil((resp.total || 0) / 20)));
        } else if (activeTab === "trash") {
          const resp = await screenApi.getDeletedScreens({ page: currentPage, size: 20 });
          if (abort) return;
          setDeletedScreens(resp.data || []);
          setTotalPages(Math.max(1, Math.ceil((resp.total || 0) / 20)));
        }
      } catch (e) {
        console.error("화면 목록 조회 실패", e);
        if (activeTab === "active") {
          setScreens([]);
        } else {
          setDeletedScreens([]);
        }
        setTotalPages(1);
      } finally {
        if (!abort) {
          setLoading(false);
          setIsSearching(false);
        }
      }
    };
    load();
    return () => {
      abort = true;
    };
  }, [currentPage, debouncedSearchTerm, activeTab, selectedCompanyCode, selectedGroupId, isSuperAdmin]);

  const filteredScreens = screens; // 서버 필터 기준 사용

  // 화면 목록 다시 로드
  const reloadScreens = async () => {
    try {
      setIsSearching(true);
      const params: any = { page: currentPage, size: 20, searchTerm: debouncedSearchTerm };
      
      // 최고 관리자이고 특정 회사를 선택한 경우
      if (isSuperAdmin && selectedCompanyCode !== "all") {
        params.companyCode = selectedCompanyCode;
      }
      
      const resp = await screenApi.getScreens(params);
      setScreens(resp.data || []);
      setTotalPages(Math.max(1, Math.ceil((resp.total || 0) / 20)));
    } catch (e) {
      console.error("화면 목록 조회 실패", e);
    } finally {
      setIsSearching(false);
    }
  };

  const handleScreenSelect = (screen: ScreenDefinition) => {
    onScreenSelect(screen);
  };

  const handleEdit = async (screen: ScreenDefinition) => {
    setScreenToEdit(screen);
    
    // 데이터 소스 타입 결정
    const isRestApi = screen.dataSourceType === "restapi" || screen.tableName?.startsWith("_restapi_");
    
    setEditFormData({
      screenName: screen.screenName,
      description: screen.description || "",
      isActive: screen.isActive,
      tableName: screen.tableName || "",
      dataSourceType: isRestApi ? "restapi" : "database",
      restApiConnectionId: (screen as any).restApiConnectionId || null,
      restApiEndpoint: (screen as any).restApiEndpoint || "",
      restApiJsonPath: (screen as any).restApiJsonPath || "data",
    });
    setEditDialogOpen(true);

    // 테이블 목록 로드
    try {
      setLoadingTables(true);
      const { tableManagementApi } = await import("@/lib/api/tableManagement");
      const response = await tableManagementApi.getTableList();
      if (response.success && response.data) {
        // tableName과 displayName 매핑 (백엔드에서 displayName으로 라벨을 반환함)
        const tableList = response.data.map((table: any) => ({
          tableName: table.tableName,
          tableLabel: table.displayName || table.tableName,
        }));
        setTables(tableList);
      }
    } catch (error) {
      console.error("테이블 목록 조회 실패:", error);
    } finally {
      setLoadingTables(false);
    }
    
    // REST API 연결 목록 로드
    try {
      const connections = await ExternalRestApiConnectionAPI.getConnections({ is_active: "Y" });
      setEditRestApiConnections(connections);
    } catch (error) {
      console.error("REST API 연결 목록 조회 실패:", error);
      setEditRestApiConnections([]);
    }
  };

  const handleEditSave = async () => {
    if (!screenToEdit) return;

    try {
      // 데이터 소스 타입에 따라 업데이트 데이터 구성
      const updateData: any = {
        screenName: editFormData.screenName,
        description: editFormData.description,
        isActive: editFormData.isActive,
        dataSourceType: editFormData.dataSourceType,
      };

      if (editFormData.dataSourceType === "database") {
        updateData.tableName = editFormData.tableName;
        updateData.restApiConnectionId = null;
        updateData.restApiEndpoint = null;
        updateData.restApiJsonPath = null;
      } else {
        // REST API
        updateData.tableName = `_restapi_${editFormData.restApiConnectionId}`;
        updateData.restApiConnectionId = editFormData.restApiConnectionId;
        updateData.restApiEndpoint = editFormData.restApiEndpoint;
        updateData.restApiJsonPath = editFormData.restApiJsonPath || "data";
      }

      console.log("📤 화면 편집 저장 요청:", {
        screenId: screenToEdit.screenId,
        editFormData,
        updateData,
      });

      // 화면 정보 업데이트 API 호출
      await screenApi.updateScreenInfo(screenToEdit.screenId, updateData);

      // 선택된 테이블의 라벨 찾기
      const selectedTable = tables.find((t) => t.tableName === editFormData.tableName);
      const tableLabel = selectedTable?.tableLabel || editFormData.tableName;

      // 목록에서 해당 화면 정보 업데이트
      setScreens((prev) =>
        prev.map((s) =>
          s.screenId === screenToEdit.screenId
            ? {
                ...s,
                screenName: editFormData.screenName,
                tableName: updateData.tableName,
                tableLabel: tableLabel,
                description: editFormData.description,
                isActive: editFormData.isActive,
                dataSourceType: editFormData.dataSourceType,
              }
            : s,
        ),
      );

      setEditDialogOpen(false);
      setScreenToEdit(null);
    } catch (error) {
      console.error("화면 정보 업데이트 실패:", error);
      alert("화면 정보 업데이트에 실패했습니다.");
    }
  };

  const handleDelete = async (screen: ScreenDefinition) => {
    setScreenToDelete(screen);
    setCheckingDependencies(true);

    try {
      // 의존성 체크
      const dependencyResult = await screenApi.checkScreenDependencies(screen.screenId);

      if (dependencyResult.hasDependencies) {
        setDependencies(dependencyResult.dependencies);
        setShowDependencyWarning(true);
      } else {
        setDeleteDialogOpen(true);
      }
    } catch (error) {
      // console.error("의존성 체크 실패:", error);
      // 의존성 체크 실패 시에도 삭제 다이얼로그는 열어줌
      setDeleteDialogOpen(true);
    } finally {
      setCheckingDependencies(false);
    }
  };

  const confirmDelete = async (force: boolean = false) => {
    if (!screenToDelete) return;

    try {
      await screenApi.deleteScreen(screenToDelete.screenId, deleteReason, force);
      setScreens((prev) => prev.filter((s) => s.screenId !== screenToDelete.screenId));
      setDeleteDialogOpen(false);
      setShowDependencyWarning(false);
      setScreenToDelete(null);
      setDeleteReason("");
      setDependencies([]);
    } catch (error: any) {
      // console.error("화면 삭제 실패:", error);

      // 의존성 오류인 경우 경고창 표시
      if (error.response?.status === 409 && error.response?.data?.code === "SCREEN_HAS_DEPENDENCIES") {
        setDependencies(error.response.data.dependencies || []);
        setShowDependencyWarning(true);
        setDeleteDialogOpen(false);
      } else {
        alert("화면 삭제에 실패했습니다.");
      }
    }
  };

  const handleCancelDelete = () => {
    setDeleteDialogOpen(false);
    setShowDependencyWarning(false);
    setScreenToDelete(null);
    setDeleteReason("");
    setDependencies([]);
  };

  const handleRestore = async (screen: DeletedScreenDefinition) => {
    if (!confirm(`"${screen.screenName}" 화면을 복원하시겠습니까?`)) return;

    try {
      await screenApi.restoreScreen(screen.screenId);
      setDeletedScreens((prev) => prev.filter((s) => s.screenId !== screen.screenId));
      // 활성 탭으로 이동하여 복원된 화면 확인
      setActiveTab("active");
      reloadScreens();
    } catch (error) {
      // console.error("화면 복원 실패:", error);
      alert("화면 복원에 실패했습니다.");
    }
  };

  const handlePermanentDelete = (screen: DeletedScreenDefinition) => {
    setScreenToPermanentDelete(screen);
    setPermanentDeleteDialogOpen(true);
  };

  const confirmPermanentDelete = async () => {
    if (!screenToPermanentDelete) return;

    try {
      await screenApi.permanentDeleteScreen(screenToPermanentDelete.screenId);
      setDeletedScreens((prev) => prev.filter((s) => s.screenId !== screenToPermanentDelete.screenId));
      setPermanentDeleteDialogOpen(false);
      setScreenToPermanentDelete(null);
    } catch (error) {
      // console.error("화면 영구 삭제 실패:", error);
      alert("화면 영구 삭제에 실패했습니다.");
    }
  };

  // 휴지통 체크박스 선택 처리
  const handleScreenCheck = (screenId: number, checked: boolean) => {
    if (checked) {
      setSelectedScreenIds((prev) => [...prev, screenId]);
    } else {
      setSelectedScreenIds((prev) => prev.filter((id) => id !== screenId));
    }
  };

  // 휴지통 전체 선택/해제
  const handleSelectAll = (checked: boolean) => {
    if (checked) {
      setSelectedScreenIds(deletedScreens.map((screen) => screen.screenId));
    } else {
      setSelectedScreenIds([]);
    }
  };

  // 휴지통 일괄삭제 실행
  const handleBulkDelete = () => {
    if (selectedScreenIds.length === 0) {
      alert("삭제할 화면을 선택해주세요.");
      return;
    }
    setBulkDeleteDialogOpen(true);
  };

  // 활성 화면 체크박스 선택 처리
  const handleActiveScreenCheck = (screenId: number, checked: boolean) => {
    if (checked) {
      setSelectedActiveScreenIds((prev) => [...prev, screenId]);
    } else {
      setSelectedActiveScreenIds((prev) => prev.filter((id) => id !== screenId));
    }
  };

  // 활성 화면 전체 선택/해제
  const handleActiveSelectAll = (checked: boolean) => {
    if (checked) {
      setSelectedActiveScreenIds(screens.map((screen) => screen.screenId));
    } else {
      setSelectedActiveScreenIds([]);
    }
  };

  // 활성 화면 일괄삭제 실행
  const handleActiveBulkDelete = () => {
    if (selectedActiveScreenIds.length === 0) {
      alert("삭제할 화면을 선택해주세요.");
      return;
    }
    setActiveBulkDeleteDialogOpen(true);
  };

  // 활성 화면 일괄삭제 확인
  const confirmActiveBulkDelete = async () => {
    if (selectedActiveScreenIds.length === 0) return;

    try {
      setActiveBulkDeleting(true);
      const result = await screenApi.bulkDeleteScreens(
        selectedActiveScreenIds,
        activeBulkDeleteReason || undefined,
        true // 강제 삭제 (의존성 무시)
      );

      // 삭제된 화면들을 목록에서 제거
      setScreens((prev) => prev.filter((screen) => !selectedActiveScreenIds.includes(screen.screenId)));

      setSelectedActiveScreenIds([]);
      setActiveBulkDeleteDialogOpen(false);
      setActiveBulkDeleteReason("");

      // 결과 메시지 표시
      let message = `${result.deletedCount}개 화면이 휴지통으로 이동되었습니다.`;
      if (result.skippedCount > 0) {
        message += `\n${result.skippedCount}개 화면은 삭제되지 않았습니다.`;
      }
      if (result.errors.length > 0) {
        message += `\n오류 발생: ${result.errors.map((e) => `화면 ${e.screenId}: ${e.error}`).join(", ")}`;
      }

      alert(message);
    } catch (error) {
      console.error("일괄 삭제 실패:", error);
      alert("일괄 삭제에 실패했습니다.");
    } finally {
      setActiveBulkDeleting(false);
    }
  };

  const confirmBulkDelete = async () => {
    if (selectedScreenIds.length === 0) return;

    try {
      setBulkDeleting(true);
      const result = await screenApi.bulkPermanentDeleteScreens(selectedScreenIds);

      // 삭제된 화면들을 목록에서 제거
      setDeletedScreens((prev) => prev.filter((screen) => !selectedScreenIds.includes(screen.screenId)));

      setSelectedScreenIds([]);
      setBulkDeleteDialogOpen(false);

      // 결과 메시지 표시
      let message = `${result.deletedCount}개 화면이 영구 삭제되었습니다.`;
      if (result.skippedCount > 0) {
        message += `\n${result.skippedCount}개 화면은 삭제되지 않았습니다.`;
      }
      if (result.errors.length > 0) {
        message += `\n오류 발생: ${result.errors.map((e) => `화면 ${e.screenId}: ${e.error}`).join(", ")}`;
      }

      alert(message);
    } catch (error) {
      // console.error("일괄 삭제 실패:", error);
      alert("일괄 삭제에 실패했습니다.");
    } finally {
      setBulkDeleting(false);
    }
  };

  const handleCopy = (screen: ScreenDefinition) => {
    setScreenToCopy(screen);
    setIsCopyOpen(true);
  };

  const handleView = async (screen: ScreenDefinition) => {
    setScreenToPreview(screen);
    setPreviewLayout(null); // 이전 레이아웃 초기화
    setIsLoadingPreview(true);
    setPreviewDialogOpen(true); // 모달 먼저 열기

    // 모달이 열린 후에 레이아웃 로드
    setTimeout(async () => {
      try {
        // 화면 레이아웃 로드
        const layoutData = await screenApi.getLayout(screen.screenId);
        console.log("📊 미리보기 레이아웃 로드:", layoutData);
        setPreviewLayout(layoutData);
      } catch (error) {
        console.error("❌ 레이아웃 로드 실패:", error);
        showErrorToast("화면 레이아웃을 불러오는 데 실패했습니다", error, { guidance: "화면 설정을 확인하거나 잠시 후 다시 시도해 주세요." });
      } finally {
        setIsLoadingPreview(false);
      }
    }, 100); // 100ms 딜레이로 모달 애니메이션이 먼저 시작되도록
  };

  const handleCopySuccess = () => {
    // 복사 성공 후 화면 목록 다시 로드
    reloadScreens();
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-8">
        <div className="text-muted-foreground text-sm">로딩 중...</div>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* 검색 및 필터 */}
      <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
          {/* 최고 관리자 전용: 회사 필터 */}
          {isSuperAdmin && (
            <div className="w-full sm:w-[200px]">
              <Select value={selectedCompanyCode} onValueChange={handleCompanySelect} disabled={activeTab === "trash"}>
                <SelectTrigger className="h-10 text-sm">
                  <SelectValue placeholder="전체 회사" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">전체 회사</SelectItem>
                  {companies.map((company) => (
                    <SelectItem key={company.companyCode} value={company.companyCode}>
                      {company.companyName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          )}

          {/* 그룹 필터 */}
          <div className="w-full sm:w-[180px]">
            <Select value={selectedGroupId} onValueChange={setSelectedGroupId} disabled={activeTab === "trash"}>
              <SelectTrigger className="h-10 text-sm">
                <Layers className="mr-2 h-4 w-4 text-muted-foreground" />
                <SelectValue placeholder="전체 그룹" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">전체 그룹</SelectItem>
                <SelectItem value="ungrouped">미분류</SelectItem>
                {groups.map((group) => (
                  <SelectItem key={group.id} value={String(group.id)}>
                    {group.groupName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* 검색 입력 */}
          <div className="w-full sm:w-[400px]">
            <div className="relative">
              <Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
              <Input
                key="screen-search-input" // 리렌더링 시에도 동일한 Input 유지
                placeholder="화면명, 코드, 테이블명으로 검색..."
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                className="h-10 pl-10 text-sm"
                disabled={activeTab === "trash"}
              />
              {/* 검색 중 인디케이터 */}
              {isSearching && (
                <div className="absolute right-3 top-1/2 -translate-y-1/2">
                  <div className="h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" />
                </div>
              )}
            </div>
          </div>
        </div>

        <Button
          onClick={() => setIsCreateOpen(true)}
          disabled={activeTab === "trash"}
          className="h-10 gap-2 text-sm font-medium"
        >
          <Plus className="h-4 w-4" />새 화면 생성
        </Button>
      </div>

      {/* 탭 구조 */}
      <Tabs value={activeTab} onValueChange={(value) => {
        setActiveTab(value);
        // 탭 전환 시 선택 상태 초기화
        setSelectedActiveScreenIds([]);
        setSelectedScreenIds([]);
      }}>
        <TabsList className="grid w-full grid-cols-2">
          <TabsTrigger value="active">활성 화면</TabsTrigger>
          <TabsTrigger value="trash">휴지통</TabsTrigger>
        </TabsList>

        {/* 활성 화면 탭 */}
        <TabsContent value="active">
          {/* 선택 삭제 헤더 (선택된 항목이 있을 때만 표시) */}
          {selectedActiveScreenIds.length > 0 && (
            <div className="bg-muted/50 mb-4 flex items-center justify-between rounded-lg border p-3">
              <span className="text-sm font-medium">
                {selectedActiveScreenIds.length}개 화면 선택됨
              </span>
              <div className="flex items-center gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setSelectedActiveScreenIds([])}
                  className="h-8 text-xs"
                >
                  선택 해제
                </Button>
                <Button
                  variant="destructive"
                  size="sm"
                  onClick={handleActiveBulkDelete}
                  disabled={activeBulkDeleting}
                  className="h-8 gap-1 text-xs"
                >
                  <Trash2 className="h-3.5 w-3.5" />
                  {activeBulkDeleting ? "삭제 중..." : "선택 삭제"}
                </Button>
              </div>
            </div>
          )}

          {/* 데스크톱 테이블 뷰 (lg 이상) */}
          <div className="bg-card hidden shadow-sm lg:block">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 w-12 px-4 py-3">
                    <Checkbox
                      checked={screens.length > 0 && selectedActiveScreenIds.length === screens.length}
                      onCheckedChange={handleActiveSelectAll}
                      aria-label="전체 선택"
                    />
                  </TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">화면명</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">테이블명</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">상태</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">생성일</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">작업</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {screens.map((screen) => (
                  <TableRow
                    key={screen.screenId}
                    className={`bg-background hover:bg-muted/50 cursor-pointer border-b transition-colors ${
                      selectedScreen?.screenId === screen.screenId ? "border-primary/20 bg-accent" : ""
                    } ${selectedActiveScreenIds.includes(screen.screenId) ? "bg-muted/30" : ""}`}
                    onClick={() => onDesignScreen(screen)}
                  >
                    <TableCell className="h-16 px-4 py-3">
                      <Checkbox
                        checked={selectedActiveScreenIds.includes(screen.screenId)}
                        onCheckedChange={(checked) => handleActiveScreenCheck(screen.screenId, checked as boolean)}
                        onClick={(e) => e.stopPropagation()}
                        aria-label={`${screen.screenName} 선택`}
                      />
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3 cursor-pointer">
                      <div>
                        <div className="font-medium">{screen.screenName}</div>
                        {screen.description && (
                          <div className="text-muted-foreground mt-1 text-sm">{screen.description}</div>
                        )}
                      </div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <span className="text-muted-foreground font-mono text-sm">
                        {screen.tableLabel || screen.tableName}
                      </span>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <Badge variant={screen.isActive === "Y" ? "default" : "secondary"}>
                        {screen.isActive === "Y" ? "활성" : "비활성"}
                      </Badge>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div className="text-muted-foreground text-sm">{screen.createdDate.toLocaleDateString()}</div>
                      <div className="text-muted-foreground text-xs">{screen.createdBy}</div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="icon" className="h-8 w-8">
                            <MoreHorizontal className="h-4 w-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              onDesignScreen(screen);
                            }}
                          >
                            <Palette className="mr-2 h-4 w-4" />
                            화면 설계
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              handleView(screen);
                            }}
                          >
                            <Eye className="mr-2 h-4 w-4" />
                            미리보기
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              handleEdit(screen);
                            }}
                          >
                            <Edit className="mr-2 h-4 w-4" />
                            편집
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              handleCopy(screen);
                            }}
                          >
                            <Copy className="mr-2 h-4 w-4" />
                            복사
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            onClick={(e) => {
                              e.stopPropagation();
                              handleDelete(screen);
                            }}
                            className="text-destructive"
                            disabled={checkingDependencies && screenToDelete?.screenId === screen.screenId}
                          >
                            <Trash2 className="mr-2 h-4 w-4" />
                            {checkingDependencies && screenToDelete?.screenId === screen.screenId
                              ? "확인 중..."
                              : "삭제"}
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>

            {filteredScreens.length === 0 && (
              <div className="flex h-64 flex-col items-center justify-center">
                <p className="text-muted-foreground text-sm">검색 결과가 없습니다.</p>
              </div>
            )}
          </div>

          {/* 모바일/태블릿 카드 뷰 (lg 미만) */}
          <div className="space-y-4 lg:hidden">
            {/* 선택 헤더 */}
            <div className="bg-card flex items-center justify-between rounded-lg border p-4 shadow-sm">
              <div className="flex items-center gap-3">
                <Checkbox
                  checked={screens.length > 0 && selectedActiveScreenIds.length === screens.length}
                  onCheckedChange={handleActiveSelectAll}
                  aria-label="전체 선택"
                />
                <span className="text-sm text-muted-foreground">전체 선택</span>
              </div>
              {selectedActiveScreenIds.length > 0 && (
                <Button
                  variant="destructive"
                  size="sm"
                  onClick={handleActiveBulkDelete}
                  disabled={activeBulkDeleting}
                  className="h-9 gap-2 text-sm"
                >
                  <Trash2 className="h-4 w-4" />
                  {activeBulkDeleting ? "삭제 중..." : `${selectedActiveScreenIds.length}개 삭제`}
                </Button>
              )}
            </div>

            {/* 카드 목록 */}
            <div className="grid gap-4 sm:grid-cols-2">
              {screens.map((screen) => (
                <div
                  key={screen.screenId}
                  className={`bg-card hover:bg-muted/50 cursor-pointer rounded-lg border p-4 shadow-sm transition-colors ${
                    selectedScreen?.screenId === screen.screenId ? "border-primary bg-accent" : ""
                  } ${selectedActiveScreenIds.includes(screen.screenId) ? "bg-muted/30 border-primary/50" : ""}`}
                  onClick={() => handleScreenSelect(screen)}
                >
                  {/* 헤더 */}
                  <div className="mb-4 flex items-start gap-3">
                    <Checkbox
                      checked={selectedActiveScreenIds.includes(screen.screenId)}
                      onCheckedChange={(checked) => handleActiveScreenCheck(screen.screenId, checked as boolean)}
                      onClick={(e) => e.stopPropagation()}
                      className="mt-1"
                      aria-label={`${screen.screenName} 선택`}
                    />
                    <div className="flex-1">
                      <h3 className="text-base font-semibold">{screen.screenName}</h3>
                    </div>
                    <Badge variant={screen.isActive === "Y" ? "default" : "secondary"}>
                      {screen.isActive === "Y" ? "활성" : "비활성"}
                    </Badge>
                  </div>

                {/* 설명 */}
                {screen.description && <p className="text-muted-foreground mb-4 text-sm">{screen.description}</p>}

                {/* 정보 */}
                <div className="space-y-2 border-t pt-4">
                  <div className="flex justify-between text-sm">
                    <span className="text-muted-foreground">테이블</span>
                    <span className="font-mono font-medium">{screen.tableLabel || screen.tableName}</span>
                  </div>
                  <div className="flex justify-between text-sm">
                    <span className="text-muted-foreground">생성일</span>
                    <span className="font-medium">{screen.createdDate.toLocaleDateString()}</span>
                  </div>
                  <div className="flex justify-between text-sm">
                    <span className="text-muted-foreground">작성자</span>
                    <span className="font-medium">{screen.createdBy}</span>
                  </div>
                </div>

                {/* 액션 */}
                <div className="mt-4 flex gap-2 border-t pt-4">
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={(e) => {
                      e.stopPropagation();
                      onDesignScreen(screen);
                    }}
                    className="h-9 flex-1 gap-2 text-sm"
                  >
                    <Palette className="h-4 w-4" />
                    설계
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={(e) => {
                      e.stopPropagation();
                      handleView(screen);
                    }}
                    className="h-9 flex-1 gap-2 text-sm"
                  >
                    <Eye className="h-4 w-4" />
                    미리보기
                  </Button>
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                      <Button variant="outline" size="sm" className="h-9 px-3">
                        <MoreHorizontal className="h-4 w-4" />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end">
                      <DropdownMenuItem
                        onClick={(e) => {
                          e.stopPropagation();
                          handleEdit(screen);
                        }}
                      >
                        <Edit className="mr-2 h-4 w-4" />
                        편집
                      </DropdownMenuItem>
                      <DropdownMenuItem
                        onClick={(e) => {
                          e.stopPropagation();
                          handleCopy(screen);
                        }}
                      >
                        <Copy className="mr-2 h-4 w-4" />
                        복사
                      </DropdownMenuItem>
                      <DropdownMenuItem
                        onClick={(e) => {
                          e.stopPropagation();
                          handleDelete(screen);
                        }}
                        className="text-destructive"
                        disabled={checkingDependencies && screenToDelete?.screenId === screen.screenId}
                      >
                        <Trash2 className="mr-2 h-4 w-4" />
                        {checkingDependencies && screenToDelete?.screenId === screen.screenId ? "확인 중..." : "삭제"}
                      </DropdownMenuItem>
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              </div>
            ))}

              {filteredScreens.length === 0 && (
                <div className="bg-card col-span-2 flex h-64 flex-col items-center justify-center rounded-lg border shadow-sm">
                  <p className="text-muted-foreground text-sm">검색 결과가 없습니다.</p>
                </div>
              )}
            </div>
          </div>
        </TabsContent>

        {/* 휴지통 탭 */}
        <TabsContent value="trash">
          {/* 데스크톱 테이블 뷰 (lg 이상) */}
          <div className="bg-card hidden shadow-sm lg:block">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="h-12 w-12 px-6 py-3">
                    <Checkbox
                      checked={deletedScreens.length > 0 && selectedScreenIds.length === deletedScreens.length}
                      onCheckedChange={handleSelectAll}
                      aria-label="전체 선택"
                    />
                  </TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">화면명</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">테이블명</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">삭제일</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">삭제자</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">삭제 사유</TableHead>
                  <TableHead className="h-12 px-6 py-3 text-sm font-semibold">작업</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {deletedScreens.map((screen) => (
                  <TableRow key={screen.screenId} className="bg-background hover:bg-muted/50 border-b transition-colors">
                    <TableCell className="h-16 px-6 py-3">
                      <Checkbox
                        checked={selectedScreenIds.includes(screen.screenId)}
                        onCheckedChange={(checked) => handleScreenCheck(screen.screenId, checked as boolean)}
                        aria-label={`${screen.screenName} 선택`}
                      />
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div>
                        <div className="font-medium">{screen.screenName}</div>
                        {screen.description && (
                          <div className="text-muted-foreground mt-1 text-sm">{screen.description}</div>
                        )}
                      </div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <span className="text-muted-foreground font-mono text-sm">
                        {screen.tableLabel || screen.tableName}
                      </span>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div className="text-muted-foreground text-sm">{screen.deletedDate?.toLocaleDateString()}</div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div className="text-muted-foreground text-sm">{screen.deletedBy}</div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div className="text-muted-foreground max-w-32 truncate text-sm" title={screen.deleteReason}>
                        {screen.deleteReason || "-"}
                      </div>
                    </TableCell>
                    <TableCell className="h-16 px-6 py-3">
                      <div className="flex items-center gap-2">
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => handleRestore(screen)}
                          className="text-primary hover:text-primary/80 h-9 gap-2 text-sm"
                        >
                          <RotateCcw className="h-4 w-4" />
                          복원
                        </Button>
                        <Button
                          variant="destructive"
                          size="sm"
                          onClick={() => handlePermanentDelete(screen)}
                          className="h-9 gap-2 text-sm"
                        >
                          <Trash className="h-4 w-4" />
                          영구삭제
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>

            {deletedScreens.length === 0 && (
              <div className="flex h-64 flex-col items-center justify-center">
                <p className="text-muted-foreground text-sm">휴지통이 비어있습니다.</p>
              </div>
            )}
          </div>

          {/* 모바일/태블릿 카드 뷰 (lg 미만) */}
          <div className="space-y-4 lg:hidden">
            {/* 헤더 */}
            <div className="bg-card flex items-center justify-between rounded-lg border p-4 shadow-sm">
              <div className="flex items-center gap-3">
                <Checkbox
                  checked={deletedScreens.length > 0 && selectedScreenIds.length === deletedScreens.length}
                  onCheckedChange={handleSelectAll}
                  aria-label="전체 선택"
                />
              </div>
              {selectedScreenIds.length > 0 && (
                <Button
                  variant="destructive"
                  size="sm"
                  onClick={handleBulkDelete}
                  disabled={bulkDeleting}
                  className="h-9 gap-2 text-sm"
                >
                  <Trash className="h-4 w-4" />
                  {bulkDeleting ? "삭제 중..." : `${selectedScreenIds.length}개`}
                </Button>
              )}
            </div>

            {/* 카드 목록 */}
            <div className="grid gap-4 sm:grid-cols-2">
              {deletedScreens.map((screen) => (
                <div key={screen.screenId} className="bg-card rounded-lg border p-4 shadow-sm">
                  {/* 헤더 */}
                  <div className="mb-4 flex items-start gap-3">
                    <Checkbox
                      checked={selectedScreenIds.includes(screen.screenId)}
                      onCheckedChange={(checked) => handleScreenCheck(screen.screenId, checked as boolean)}
                      className="mt-1"
                      aria-label={`${screen.screenName} 선택`}
                    />
                    <div className="flex-1">
                      <h3 className="text-base font-semibold">{screen.screenName}</h3>
                    </div>
                  </div>

                  {/* 설명 */}
                  {screen.description && <p className="text-muted-foreground mb-4 text-sm">{screen.description}</p>}

                  {/* 정보 */}
                  <div className="space-y-2 border-t pt-4">
                    <div className="flex justify-between text-sm">
                      <span className="text-muted-foreground">테이블</span>
                      <span className="font-mono font-medium">{screen.tableLabel || screen.tableName}</span>
                    </div>
                    <div className="flex justify-between text-sm">
                      <span className="text-muted-foreground">삭제일</span>
                      <span className="font-medium">{screen.deletedDate?.toLocaleDateString()}</span>
                    </div>
                    <div className="flex justify-between text-sm">
                      <span className="text-muted-foreground">삭제자</span>
                      <span className="font-medium">{screen.deletedBy}</span>
                    </div>
                    {screen.deleteReason && (
                      <div className="flex flex-col gap-1 text-sm">
                        <span className="text-muted-foreground">삭제 사유</span>
                        <span className="font-medium">{screen.deleteReason}</span>
                      </div>
                    )}
                  </div>

                  {/* 액션 */}
                  <div className="mt-4 flex gap-2 border-t pt-4">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => handleRestore(screen)}
                      className="text-primary hover:text-primary/80 h-9 flex-1 gap-2 text-sm"
                    >
                      <RotateCcw className="h-4 w-4" />
                      복원
                    </Button>
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={() => handlePermanentDelete(screen)}
                      className="h-9 flex-1 gap-2 text-sm"
                    >
                      <Trash className="h-4 w-4" />
                      영구삭제
                    </Button>
                  </div>
                </div>
              ))}
            </div>

            {deletedScreens.length === 0 && (
              <div className="bg-card flex h-64 flex-col items-center justify-center rounded-lg border shadow-sm">
                <p className="text-muted-foreground text-sm">휴지통이 비어있습니다.</p>
              </div>
            )}
          </div>
        </TabsContent>
      </Tabs>

      {/* 페이지네이션 */}
      {totalPages > 1 && (
        <div className="flex items-center justify-center space-x-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
            disabled={currentPage === 1}
          >
            이전
          </Button>
          <span className="text-muted-foreground text-sm">
            {currentPage} / {totalPages}
          </span>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
            disabled={currentPage === totalPages}
          >
            다음
          </Button>
        </div>
      )}
      {/* 새 화면 생성 모달 */}
      <CreateScreenModal
        open={isCreateOpen}
        onOpenChange={setIsCreateOpen}
        onCreated={(created) => {
          // 목록에 즉시 반영 (첫 페이지 기준 상단 추가)
          setScreens((prev) => [created, ...prev]);
        }}
      />

      {/* 화면 복사 모달 */}
      <CopyScreenModal
        isOpen={isCopyOpen}
        onClose={() => setIsCopyOpen(false)}
        sourceScreen={screenToCopy}
        onCopySuccess={handleCopySuccess}
      />

      {/* 삭제 확인 다이얼로그 */}
      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>화면 삭제 확인</AlertDialogTitle>
            <AlertDialogDescription>
              "{screenToDelete?.screenName}" 화면을 휴지통으로 이동하시겠습니까?
              <br />
              휴지통에서 언제든지 복원할 수 있습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <div className="space-y-2">
            <Label htmlFor="deleteReason">삭제 사유 (선택사항)</Label>
            <Textarea
              id="deleteReason"
              placeholder="삭제 사유를 입력하세요..."
              value={deleteReason}
              onChange={(e) => setDeleteReason(e.target.value)}
              rows={3}
            />
          </div>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={handleCancelDelete}>취소</AlertDialogCancel>
            <AlertDialogAction onClick={() => confirmDelete(false)} variant="destructive">
              휴지통으로 이동
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 의존성 경고 다이얼로그 */}
      <AlertDialog open={showDependencyWarning} onOpenChange={setShowDependencyWarning}>
        <AlertDialogContent className="max-w-2xl">
          <AlertDialogHeader>
            <AlertDialogTitle className="text-amber-600">⚠️ 화면 삭제 경고</AlertDialogTitle>
            <AlertDialogDescription>
              "{screenToDelete?.screenName}" 화면이 다른 화면에서 사용 중입니다.
              <br />이 화면을 삭제하면 아래 화면들의 버튼 기능이 작동하지 않을 수 있습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>

          <div className="max-h-60 overflow-y-auto">
            <div className="space-y-3">
              <h4 className="font-medium">사용 중인 화면 목록:</h4>
              {dependencies.map((dep, index) => (
                <div key={index} className="rounded-lg border border-orange-200 bg-amber-50 p-3">
                  <div className="flex items-center justify-between">
                    <div>
                      <div className="font-medium">{dep.screenName}</div>
                      <div className="text-muted-foreground text-sm">화면 코드: {dep.screenCode}</div>
                    </div>
                    <div className="text-right">
                      <div className="text-sm font-medium text-amber-600">
                        {dep.referenceType === "popup" && "팝업 버튼"}
                        {dep.referenceType === "navigate" && "이동 버튼"}
                        {dep.referenceType === "url" && "URL 링크"}
                        {dep.referenceType === "menu_assignment" && "메뉴 할당"}
                      </div>
                      <div className="text-muted-foreground text-xs">
                        {dep.referenceType === "menu_assignment" ? "메뉴" : "컴포넌트"}: {dep.componentId}
                      </div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="space-y-2">
            <Label htmlFor="forceDeleteReason">삭제 사유 (필수)</Label>
            <Textarea
              id="forceDeleteReason"
              placeholder="강제 삭제 사유를 입력하세요..."
              value={deleteReason}
              onChange={(e) => setDeleteReason(e.target.value)}
              rows={3}
            />
          </div>

          <AlertDialogFooter>
            <AlertDialogCancel onClick={handleCancelDelete}>취소</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => confirmDelete(true)}
              variant="destructive"
              disabled={!deleteReason.trim()}
            >
              강제 삭제
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 영구 삭제 확인 다이얼로그 */}
      <AlertDialog open={permanentDeleteDialogOpen} onOpenChange={setPermanentDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>영구 삭제 확인</AlertDialogTitle>
            <AlertDialogDescription className="text-destructive">
              ⚠️ "{screenToPermanentDelete?.screenName}" 화면을 영구적으로 삭제하시겠습니까?
              <br />
              <strong>이 작업은 되돌릴 수 없습니다!</strong>
              <br />
              모든 레이아웃 정보와 관련 데이터가 완전히 삭제됩니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel
              onClick={() => {
                setPermanentDeleteDialogOpen(false);
                setScreenToPermanentDelete(null);
              }}
            >
              취소
            </AlertDialogCancel>
            <AlertDialogAction onClick={confirmPermanentDelete} variant="destructive">
              영구 삭제
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 휴지통 일괄삭제 확인 다이얼로그 */}
      <AlertDialog open={bulkDeleteDialogOpen} onOpenChange={setBulkDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>일괄 영구 삭제 확인</AlertDialogTitle>
            <AlertDialogDescription className="text-destructive">
              선택된 {selectedScreenIds.length}개 화면을 영구적으로 삭제하시겠습니까?
              <br />
              <strong>이 작업은 되돌릴 수 없습니다!</strong>
              <br />
              모든 레이아웃 정보와 관련 데이터가 완전히 삭제됩니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel
              onClick={() => {
                setBulkDeleteDialogOpen(false);
              }}
              disabled={bulkDeleting}
            >
              취소
            </AlertDialogCancel>
            <AlertDialogAction onClick={confirmBulkDelete} variant="destructive" disabled={bulkDeleting}>
              {bulkDeleting ? "삭제 중..." : `${selectedScreenIds.length}개 영구 삭제`}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 활성 화면 일괄삭제 확인 다이얼로그 */}
      <AlertDialog open={activeBulkDeleteDialogOpen} onOpenChange={setActiveBulkDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>선택 화면 삭제 확인</AlertDialogTitle>
            <AlertDialogDescription>
              선택된 {selectedActiveScreenIds.length}개 화면을 휴지통으로 이동하시겠습니까?
              <br />
              휴지통에서 언제든지 복원할 수 있습니다.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <div className="space-y-2">
            <Label htmlFor="activeBulkDeleteReason">삭제 사유 (선택사항)</Label>
            <Textarea
              id="activeBulkDeleteReason"
              placeholder="삭제 사유를 입력하세요..."
              value={activeBulkDeleteReason}
              onChange={(e) => setActiveBulkDeleteReason(e.target.value)}
              rows={3}
            />
          </div>
          <AlertDialogFooter>
            <AlertDialogCancel
              onClick={() => {
                setActiveBulkDeleteDialogOpen(false);
                setActiveBulkDeleteReason("");
              }}
              disabled={activeBulkDeleting}
            >
              취소
            </AlertDialogCancel>
            <AlertDialogAction onClick={confirmActiveBulkDelete} variant="destructive" disabled={activeBulkDeleting}>
              {activeBulkDeleting ? "삭제 중..." : `${selectedActiveScreenIds.length}개 휴지통으로 이동`}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 화면 편집 다이얼로그 */}
      <Dialog open={editDialogOpen} onOpenChange={setEditDialogOpen}>
        <DialogContent className="sm:max-w-[500px]">
          <DialogHeader>
            <DialogTitle>화면 정보 편집</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-4">
            <div className="space-y-2">
              <Label htmlFor="edit-screenName">화면명 *</Label>
              <Input
                id="edit-screenName"
                value={editFormData.screenName}
                onChange={(e) => setEditFormData({ ...editFormData, screenName: e.target.value })}
                placeholder="화면명을 입력하세요"
              />
            </div>
            
            {/* 데이터 소스 타입 선택 */}
            <div className="space-y-2">
              <Label>데이터 소스 타입</Label>
              <Select
                value={editFormData.dataSourceType}
                onValueChange={(value: "database" | "restapi") => {
                  setEditFormData({ 
                    ...editFormData, 
                    dataSourceType: value,
                    tableName: "",
                    restApiConnectionId: null,
                    restApiEndpoint: "",
                    restApiJsonPath: "data",
                  });
                }}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="database">데이터베이스</SelectItem>
                  <SelectItem value="restapi">REST API</SelectItem>
                </SelectContent>
              </Select>
            </div>
            
            {/* 데이터베이스 선택 (database 타입인 경우) */}
            {editFormData.dataSourceType === "database" && (
              <div className="space-y-2">
                <Label htmlFor="edit-tableName">테이블 *</Label>
                <Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={tableComboboxOpen}
                      className="h-8 w-full justify-between text-xs sm:h-10 sm:text-sm"
                      disabled={loadingTables}
                    >
                      {loadingTables
                        ? "로딩 중..."
                        : editFormData.tableName
                          ? tables.find((table) => table.tableName === editFormData.tableName)?.tableLabel || editFormData.tableName
                          : "테이블을 선택하세요"}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent
                    className="p-0"
                    style={{ width: "var(--radix-popover-trigger-width)" }}
                    align="start"
                  >
                    <Command>
                      <CommandInput placeholder="테이블 검색..." className="text-xs sm:text-sm" />
                      <CommandList>
                        <CommandEmpty className="text-xs sm:text-sm">
                          테이블을 찾을 수 없습니다.
                        </CommandEmpty>
                        <CommandGroup>
                          {tables.map((table) => (
                            <CommandItem
                              key={table.tableName}
                              value={`${table.tableName} ${table.tableLabel}`}
                              onSelect={() => {
                                setEditFormData({ ...editFormData, tableName: table.tableName });
                                setTableComboboxOpen(false);
                              }}
                              className="text-xs sm:text-sm"
                            >
                              <Check
                                className={cn(
                                  "mr-2 h-4 w-4",
                                  editFormData.tableName === table.tableName ? "opacity-100" : "opacity-0"
                                )}
                              />
                              <div className="flex flex-col">
                                <span className="font-medium">{table.tableLabel}</span>
                                <span className="text-[10px] text-muted-foreground">{table.tableName}</span>
                              </div>
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>
            )}
            
            {/* REST API 선택 (restapi 타입인 경우) */}
            {editFormData.dataSourceType === "restapi" && (
              <>
                <div className="space-y-2">
                  <Label>REST API 연결 *</Label>
                  <Popover open={editRestApiComboboxOpen} onOpenChange={setEditRestApiComboboxOpen}>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        aria-expanded={editRestApiComboboxOpen}
                        className="h-8 w-full justify-between text-xs sm:h-10 sm:text-sm"
                      >
                        {editFormData.restApiConnectionId
                          ? editRestApiConnections.find((c) => c.id === editFormData.restApiConnectionId)?.connection_name || "선택된 연결"
                          : "REST API 연결 선택"}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent
                      className="p-0"
                      style={{ width: "var(--radix-popover-trigger-width)" }}
                      align="start"
                    >
                      <Command>
                        <CommandInput placeholder="연결 검색..." className="text-xs sm:text-sm" />
                        <CommandList>
                          <CommandEmpty className="text-xs sm:text-sm">
                            연결을 찾을 수 없습니다.
                          </CommandEmpty>
                          <CommandGroup>
                            {editRestApiConnections.map((conn) => (
                              <CommandItem
                                key={conn.id}
                                value={conn.connection_name}
                                onSelect={() => {
                                  setEditFormData({ ...editFormData, restApiConnectionId: conn.id || null });
                                  setEditRestApiComboboxOpen(false);
                                }}
                                className="text-xs sm:text-sm"
                              >
                                <Check
                                  className={cn(
                                    "mr-2 h-4 w-4",
                                    editFormData.restApiConnectionId === conn.id ? "opacity-100" : "opacity-0"
                                  )}
                                />
                                <div className="flex flex-col">
                                  <span className="font-medium">{conn.connection_name}</span>
                                  <span className="text-[10px] text-muted-foreground">{conn.base_url}</span>
                                </div>
                              </CommandItem>
                            ))}
                          </CommandGroup>
                        </CommandList>
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
                
                <div className="space-y-2">
                  <Label htmlFor="edit-restApiEndpoint">API 엔드포인트</Label>
                  <Input
                    id="edit-restApiEndpoint"
                    value={editFormData.restApiEndpoint}
                    onChange={(e) => setEditFormData({ ...editFormData, restApiEndpoint: e.target.value })}
                    placeholder="예: /api/data/list"
                  />
                  <p className="text-muted-foreground text-[10px]">
                    데이터를 조회할 API 엔드포인트 경로입니다
                  </p>
                </div>
                
                <div className="space-y-2">
                  <Label htmlFor="edit-restApiJsonPath">JSON 경로</Label>
                  <Input
                    id="edit-restApiJsonPath"
                    value={editFormData.restApiJsonPath}
                    onChange={(e) => setEditFormData({ ...editFormData, restApiJsonPath: e.target.value })}
                    placeholder="예: data 또는 result.items"
                  />
                  <p className="text-muted-foreground text-[10px]">
                    응답 JSON에서 데이터 배열의 경로입니다 (기본: data)
                  </p>
                </div>
              </>
            )}
            
            <div className="space-y-2">
              <Label htmlFor="edit-description">설명</Label>
              <Textarea
                id="edit-description"
                value={editFormData.description}
                onChange={(e) => setEditFormData({ ...editFormData, description: e.target.value })}
                placeholder="화면 설명을 입력하세요"
                rows={3}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="edit-isActive">상태</Label>
              <Select
                value={editFormData.isActive}
                onValueChange={(value) => setEditFormData({ ...editFormData, isActive: value })}
              >
                <SelectTrigger id="edit-isActive">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="Y">활성</SelectItem>
                  <SelectItem value="N">비활성</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditDialogOpen(false)}>
              취소
            </Button>
            <Button 
              onClick={handleEditSave} 
              disabled={
                !editFormData.screenName.trim() || 
                (editFormData.dataSourceType === "database" && !editFormData.tableName.trim()) ||
                (editFormData.dataSourceType === "restapi" && !editFormData.restApiConnectionId)
              }
            >
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 화면 미리보기 다이얼로그 */}
      <Dialog open={previewDialogOpen} onOpenChange={setPreviewDialogOpen}>
        <DialogContent className="h-[95vh] max-w-[95vw]">
          <DialogHeader>
            <DialogTitle>화면 미리보기 - {screenToPreview?.screenName}</DialogTitle>
          </DialogHeader>
          <ScreenPreviewProvider isPreviewMode={true}>
            <TableOptionsProvider>
              <div className="flex flex-1 items-center justify-center overflow-hidden bg-muted/30 p-6">
              {isLoadingPreview ? (
                <div className="flex h-full items-center justify-center">
                  <div className="text-center">
                    <div className="mb-2 text-lg font-medium">레이아웃 로딩 중...</div>
                    <div className="text-muted-foreground text-sm">화면 정보를 불러오고 있습니다.</div>
                  </div>
                </div>
              ) : previewLayout && previewLayout.components ? (
              (() => {
                const screenWidth = previewLayout.screenResolution?.width || 1200;
                const screenHeight = previewLayout.screenResolution?.height || 800;

                // 모달 내부 가용 공간 계산 (헤더, 푸터, 패딩 제외)
                const modalPadding = 100; // 헤더 + 푸터 + 패딩
                const availableWidth = typeof window !== "undefined" ? window.innerWidth * 0.95 - modalPadding : 1700;
                const availableHeight = typeof window !== "undefined" ? window.innerHeight * 0.95 - modalPadding : 900;

                // 가로/세로 비율을 모두 고려하여 작은 쪽에 맞춤 (화면이 잘리지 않도록)
                const scaleX = availableWidth / screenWidth;
                const scaleY = availableHeight / screenHeight;
                const scale = Math.min(scaleX, scaleY, 1); // 최대 1배율 (확대 방지)

                console.log("📐 미리보기 스케일 계산:", {
                  screenWidth,
                  screenHeight,
                  availableWidth,
                  availableHeight,
                  scaleX,
                  scaleY,
                  finalScale: scale,
                });

                return (
                  <div
                    className="bg-card relative mx-auto rounded-xl border shadow-lg"
                    style={{
                      width: `${screenWidth}px`,
                      height: `${screenHeight}px`,
                      transform: `scale(${scale})`,
                      transformOrigin: "center center",
                    }}
                  >
                    {/* 실제 화면과 동일한 렌더링 */}
                    {previewLayout.components
                      .filter((comp: any) => !comp.parentId) // 최상위 컴포넌트만 렌더링
                      .map((component: any) => {
                        if (!component || !component.id) return null;

                        // 그룹 컴포넌트인 경우 특별 처리
                        if (component.type === "group") {
                          const groupChildren = previewLayout.components.filter(
                            (child: any) => child.parentId === component.id,
                          );

                          return (
                            <div
                              key={component.id}
                              style={{
                                position: "absolute",
                                left: `${component.position?.x || 0}px`,
                                top: `${component.position?.y || 0}px`,
                                width: component.style?.width || `${component.size?.width || 200}px`,
                                height: component.style?.height || `${component.size?.height || 40}px`,
                                zIndex: component.position?.z || 1,
                                backgroundColor: component.backgroundColor || "rgba(59, 130, 246, 0.05)",
                                border: component.border || "1px solid rgba(59, 130, 246, 0.2)",
                                borderRadius: component.borderRadius || "12px",
                                padding: "20px",
                                boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
                              }}
                            >
                              {/* 그룹 제목 */}
                              {component.title && (
                                <div className="mb-3 inline-block rounded-lg bg-primary/10 px-3 py-1 text-sm font-semibold text-primary">
                                  {component.title}
                                </div>
                              )}

                              {/* 그룹 내 자식 컴포넌트들 렌더링 */}
                              {groupChildren.map((child: any) => (
                                <div
                                  key={child.id}
                                  style={{
                                    position: "absolute",
                                    left: `${child.position.x}px`,
                                    top: `${child.position.y}px`,
                                    width: child.style?.width || `${child.size.width}px`,
                                    height: child.style?.height || `${child.size.height}px`,
                                    zIndex: child.position.z || 1,
                                  }}
                                >
                                  <InteractiveScreenViewer
                                    component={child}
                                    allComponents={previewLayout.components}
                                    formData={previewFormData}
                                    onFormDataChange={(fieldName, value) => {
                                      setPreviewFormData((prev) => ({
                                        ...prev,
                                        [fieldName]: value,
                                      }));
                                    }}
                                    screenInfo={{
                                      id: screenToPreview!.screenId,
                                      tableName: screenToPreview?.tableName,
                                    }}
                                    layers={previewLayout.layers || []}
                                  />
                                </div>
                              ))}
                            </div>
                          );
                        }

                        // 일반 컴포넌트 렌더링 - RealtimePreview 사용 (실제 화면과 동일)
                        return (
                          <RealtimePreview
                            key={component.id}
                            component={component}
                            isSelected={false}
                            isDesignMode={false}
                            onClick={() => {}}
                            screenId={screenToPreview!.screenId}
                            tableName={screenToPreview?.tableName}
                            formData={previewFormData}
                            onFormDataChange={(fieldName, value) => {
                              setPreviewFormData((prev) => ({
                                ...prev,
                                [fieldName]: value,
                              }));
                            }}
                          >
                            {/* 자식 컴포넌트들 */}
                            {(component.type === "group" ||
                              component.type === "container" ||
                              component.type === "area") &&
                              previewLayout.components
                                .filter((child: any) => child.parentId === component.id)
                                .map((child: any) => {
                                  // 자식 컴포넌트의 위치를 부모 기준 상대 좌표로 조정
                                  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={() => {}}
                                      screenId={screenToPreview!.screenId}
                                      tableName={screenToPreview?.tableName}
                                      formData={previewFormData}
                                      onFormDataChange={(fieldName, value) => {
                                        setPreviewFormData((prev) => ({
                                          ...prev,
                                          [fieldName]: value,
                                        }));
                                      }}
                                    />
                                  );
                                })}
                          </RealtimePreview>
                        );
                      })}
                  </div>
                );
              })()
            ) : (
              <div className="flex h-full items-center justify-center">
                <div className="text-center">
                  <div className="text-muted-foreground mb-2 text-lg font-medium">레이아웃이 비어있습니다</div>
                  <div className="text-muted-foreground text-sm">이 화면에는 아직 컴포넌트가 배치되지 않았습니다.</div>
                </div>
              </div>
            )}
              </div>
            </TableOptionsProvider>
          </ScreenPreviewProvider>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPreviewDialogOpen(false)}>
              닫기
            </Button>
            <Button onClick={() => onDesignScreen(screenToPreview!)}>
              <Palette className="mr-2 h-4 w-4" />
              편집 모드로 전환
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
