"use client";

import { useState, useEffect, useMemo } from "react";
import { cn } from "@/lib/utils";
import {
  ChevronRight,
  ChevronDown,
  Monitor,
  FolderOpen,
  Folder,
  Plus,
  MoreVertical,
  Edit,
  Trash2,
  FolderInput,
  Copy,
  FolderTree,
  Loader2,
  RefreshCw,
  Building2,
  AlertTriangle,
} from "lucide-react";
import { ScreenDefinition } from "@/types/screen";
import {
  ScreenGroup,
  getScreenGroups,
  deleteScreenGroup,
  addScreenToGroup,
  removeScreenFromGroup,
  getMenuScreenSyncStatus,
  syncScreenGroupsToMenu,
  syncMenuToScreenGroups,
  syncAllCompanies,
  SyncStatus,
  AllCompaniesSyncResult,
} from "@/lib/api/screenGroup";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { useAuth } from "@/hooks/useAuth";
import { getCompanyList } from "@/lib/api/company";
import type { Company } from "@/types/company";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Check, ChevronsUpDown } from "lucide-react";
import { ScreenGroupModal } from "./ScreenGroupModal";
import CopyScreenModal from "./CopyScreenModal";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { screenApi } from "@/lib/api/screen";

interface ScreenGroupTreeViewProps {
  screens: ScreenDefinition[];
  selectedScreen: ScreenDefinition | null;
  onScreenSelect: (screen: ScreenDefinition) => void;
  onScreenDesign: (screen: ScreenDefinition) => void;
  onGroupSelect?: (group: { id: number; name: string; company_code?: string } | null) => void;
  onScreenSelectInGroup?: (group: { id: number; name: string; company_code?: string }, screenId: number) => void;
  companyCode?: string;
  searchTerm?: string; // 검색어 (띄어쓰기로 구분된 여러 키워드)
}

interface TreeNode {
  type: "group" | "screen";
  id: string;
  name: string;
  data?: ScreenDefinition | ScreenGroup;
  children?: TreeNode[];
  expanded?: boolean;
}

export function ScreenGroupTreeView({
  screens,
  selectedScreen,
  onScreenSelect,
  onScreenDesign,
  onGroupSelect,
  onScreenSelectInGroup,
  companyCode,
  searchTerm = "",
}: ScreenGroupTreeViewProps) {
  const [groups, setGroups] = useState<ScreenGroup[]>([]);
  const [loading, setLoading] = useState(true);
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  const [groupScreensMap, setGroupScreensMap] = useState<Map<number, number[]>>(new Map());

  // 그룹 모달 상태
  const [isGroupModalOpen, setIsGroupModalOpen] = useState(false);
  const [editingGroup, setEditingGroup] = useState<ScreenGroup | null>(null);

  // 삭제 확인 다이얼로그 상태
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
  const [deletingGroup, setDeletingGroup] = useState<ScreenGroup | null>(null);
  const [deleteScreensWithGroup, setDeleteScreensWithGroup] = useState(false); // 화면도 함께 삭제 체크박스
  const [deleteNumberingRules, setDeleteNumberingRules] = useState(false); // 채번 규칙도 함께 삭제 체크박스
  const [isDeleting, setIsDeleting] = useState(false); // 삭제 진행 중 상태
  const [deleteProgress, setDeleteProgress] = useState({ current: 0, total: 0, message: "" }); // 삭제 진행 상태

  // 단일 화면 삭제 상태
  const [isScreenDeleteDialogOpen, setIsScreenDeleteDialogOpen] = useState(false);
  const [deletingScreen, setDeletingScreen] = useState<ScreenDefinition | null>(null);
  const [isScreenDeleting, setIsScreenDeleting] = useState(false); // 화면 삭제 진행 중

  // 화면 수정 모달 상태 (이름 변경 + 그룹 이동 통합)
  const [editingScreen, setEditingScreen] = useState<ScreenDefinition | null>(null);
  const [isEditScreenModalOpen, setIsEditScreenModalOpen] = useState(false);
  const [editScreenName, setEditScreenName] = useState<string>("");
  const [selectedGroupForMove, setSelectedGroupForMove] = useState<number | null>(null);
  const [screenRole, setScreenRole] = useState<string>("");
  const [isGroupSelectOpen, setIsGroupSelectOpen] = useState(false);
  const [displayOrder, setDisplayOrder] = useState<number>(1);

  // 화면 복제 모달 상태 (CopyScreenModal 사용)
  const [isCopyModalOpen, setIsCopyModalOpen] = useState(false);
  const [copyingScreen, setCopyingScreen] = useState<ScreenDefinition | null>(null);
  const [copyTargetGroupId, setCopyTargetGroupId] = useState<number | null>(null);
  const [copyMode, setCopyMode] = useState<"screen" | "group">("screen");

  // 그룹 복제 모달 상태 (CopyScreenModal 그룹 모드 사용)
  const [copyingGroup, setCopyingGroup] = useState<ScreenGroup | null>(null);

  // 컨텍스트 메뉴 상태 (화면용)
  const [contextMenuScreen, setContextMenuScreen] = useState<ScreenDefinition | null>(null);
  const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null);

  // 그룹 컨텍스트 메뉴 상태
  const [contextMenuGroup, setContextMenuGroup] = useState<ScreenGroup | null>(null);
  const [contextMenuGroupPosition, setContextMenuGroupPosition] = useState<{ x: number; y: number } | null>(null);

  // 메뉴-화면그룹 동기화 상태
  const [isSyncDialogOpen, setIsSyncDialogOpen] = useState(false);
  const [syncStatus, setSyncStatus] = useState<SyncStatus | null>(null);
  const [isSyncing, setIsSyncing] = useState(false);
  const [syncDirection, setSyncDirection] = useState<"screen-to-menu" | "menu-to-screen" | "all" | null>(null);
  const [syncProgress, setSyncProgress] = useState<{ message: string; detail?: string } | null>(null);
  
  // 회사 선택 (최고 관리자용)
  const { user } = useAuth();
  const [companies, setCompanies] = useState<Company[]>([]);
  const [selectedCompanyCode, setSelectedCompanyCode] = useState<string>("");
  const [isSyncCompanySelectOpen, setIsSyncCompanySelectOpen] = useState(false);
  
  // 현재 사용자가 최고 관리자인지 확인
  const isSuperAdmin = user?.companyCode === "*";
  
  // 실제 사용할 회사 코드 (props → 선택 → 사용자 기본값)
  const effectiveCompanyCode = companyCode || selectedCompanyCode || (isSuperAdmin ? "" : user?.companyCode) || "";

  // 그룹 목록 및 그룹별 화면 로드
  useEffect(() => {
    loadGroupsData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [companyCode]);

  // 그룹에 속한 화면 ID들을 가져오기
  const getGroupedScreenIds = (): Set<number> => {
    const ids = new Set<number>();
    groupScreensMap.forEach((screenIds) => {
      screenIds.forEach((id) => ids.add(id));
    });
    return ids;
  };

  // 미분류 화면들 (어떤 그룹에도 속하지 않은 화면)
  const getUngroupedScreens = (): ScreenDefinition[] => {
    const groupedIds = getGroupedScreenIds();
    return screens.filter((screen) => !groupedIds.has(screen.screenId));
  };

  // 그룹에 속한 화면들 (display_order 오름차순 정렬)
  const getScreensInGroup = (groupId: number): ScreenDefinition[] => {
    const group = groups.find((g) => g.id === groupId);
    if (!group?.screens) {
    const screenIds = groupScreensMap.get(groupId) || [];
    return screens.filter((screen) => screenIds.includes(screen.screenId));
    }
    
    // 그룹의 screens 배열에서 display_order 정보를 가져와서 정렬
    const sortedScreenIds = [...group.screens]
      .sort((a, b) => (a.display_order || 999) - (b.display_order || 999))
      .map((s) => s.screen_id);
    
    return sortedScreenIds
      .map((id) => screens.find((screen) => screen.screenId === id))
      .filter((screen): screen is ScreenDefinition => screen !== undefined);
  };

  const toggleGroup = (groupId: string) => {
    const newExpanded = new Set(expandedGroups);
    if (newExpanded.has(groupId)) {
      newExpanded.delete(groupId);
      // 그룹 접으면 선택 해제
      if (onGroupSelect) {
        onGroupSelect(null);
      }
    } else {
      newExpanded.add(groupId);
      // 그룹 펼치면 해당 그룹 선택
      if (onGroupSelect && groupId !== "ungrouped") {
        const group = groups.find((g) => String(g.id) === groupId);
        if (group) {
          onGroupSelect({ id: group.id, name: group.group_name, company_code: group.company_code });
        }
      }
    }
    setExpandedGroups(newExpanded);
  };

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

  // 그룹 내 화면 클릭 핸들러 (그룹 전체 표시 + 해당 화면 포커스)
  const handleScreenClickInGroup = (screen: ScreenDefinition, group: ScreenGroup) => {
    if (onScreenSelectInGroup) {
      onScreenSelectInGroup(
        { id: group.id, name: group.group_name, company_code: group.company_code },
        screen.screenId
      );
    } else {
      // fallback: 기존 동작
      onScreenSelect(screen);
    }
  };

  const handleScreenDoubleClick = (screen: ScreenDefinition) => {
    onScreenDesign(screen);
  };

  // 그룹 추가 버튼 클릭
  const handleAddGroup = () => {
    setEditingGroup(null);
    setIsGroupModalOpen(true);
  };

  // 동기화 다이얼로그 열기
  const handleOpenSyncDialog = async () => {
    setIsSyncDialogOpen(true);
    setSyncStatus(null);
    setSyncDirection(null);
    setSelectedCompanyCode("");
    
    // 최고 관리자일 때 회사 목록 로드
    if (isSuperAdmin && companies.length === 0) {
      try {
        const companiesList = await getCompanyList();
        // 최고 관리자(*)용 회사는 제외
        const filteredCompanies = companiesList.filter(c => c.company_code !== "*");
        setCompanies(filteredCompanies);
      } catch (error) {
        console.error("회사 목록 로드 실패:", error);
      }
    }
    
    // 최고 관리자가 아니면 바로 상태 조회
    if (!isSuperAdmin && user?.companyCode) {
      const response = await getMenuScreenSyncStatus(user.companyCode);
      if (response.success && response.data) {
        setSyncStatus(response.data);
      }
    }
  };
  
  // 회사 선택 시 상태만 변경 (페이지 새로고침 없이)
  const handleCompanySelect = async (companyCode: string) => {
    setSelectedCompanyCode(companyCode);
    setIsSyncCompanySelectOpen(false);
    setSyncStatus(null);
    
    if (companyCode) {
      // 동기화 상태 조회 (선택한 회사 코드로)
      const response = await getMenuScreenSyncStatus(companyCode);
      if (response.success && response.data) {
        setSyncStatus(response.data);
      }
    }
  };

  // 동기화 실행
  const handleSync = async (direction: "screen-to-menu" | "menu-to-screen") => {
    // 사용할 회사 코드 결정
    const targetCompanyCode = isSuperAdmin ? selectedCompanyCode : user?.companyCode;
    
    if (!targetCompanyCode) {
      toast.error("회사를 선택해주세요.");
      return;
    }
    
    setIsSyncing(true);
    setSyncDirection(direction);
    setSyncProgress({
      message: direction === "screen-to-menu" 
        ? "화면관리 → 메뉴 동기화 중..." 
        : "메뉴 → 화면관리 동기화 중...",
      detail: "데이터를 분석하고 있습니다..."
    });
    
    try {
      setSyncProgress({
        message: direction === "screen-to-menu" 
          ? "화면관리 → 메뉴 동기화 중..." 
          : "메뉴 → 화면관리 동기화 중...",
        detail: "동기화 작업을 수행하고 있습니다..."
      });
      
      const response = direction === "screen-to-menu"
        ? await syncScreenGroupsToMenu(targetCompanyCode)
        : await syncMenuToScreenGroups(targetCompanyCode);
      
      if (response.success) {
        const data = response.data;
        setSyncProgress({
          message: "동기화 완료!",
          detail: `생성 ${data?.created || 0}개, 연결 ${data?.linked || 0}개, 스킵 ${data?.skipped || 0}개`
        });
        toast.success(
          `동기화 완료: 생성 ${data?.created || 0}개, 연결 ${data?.linked || 0}개, 스킵 ${data?.skipped || 0}개`
        );
        // 그룹 데이터 새로고침
        await loadGroupsData();
        // 동기화 상태 새로고침
        const statusResponse = await getMenuScreenSyncStatus(targetCompanyCode);
        if (statusResponse.success && statusResponse.data) {
          setSyncStatus(statusResponse.data);
        }
      } else {
        setSyncProgress(null);
        toast.error(`동기화 실패: ${response.error || "알 수 없는 오류"}`);
      }
    } catch (error: any) {
      setSyncProgress(null);
      toast.error(`동기화 실패: ${error.message}`);
    } finally {
      setIsSyncing(false);
      setSyncDirection(null);
      // 3초 후 진행 메시지 초기화
      setTimeout(() => setSyncProgress(null), 3000);
    }
  };

  // 전체 회사 동기화 (최고 관리자만)
  const handleSyncAll = async () => {
    if (!isSuperAdmin) {
      toast.error("전체 동기화는 최고 관리자만 수행할 수 있습니다.");
      return;
    }

    setIsSyncing(true);
    setSyncDirection("all");
    setSyncProgress({
      message: "전체 회사 동기화 중...",
      detail: "모든 회사의 데이터를 분석하고 있습니다..."
    });

    try {
      setSyncProgress({
        message: "전체 회사 동기화 중...",
        detail: "양방향 동기화 작업을 수행하고 있습니다..."
      });
      
      const response = await syncAllCompanies();

      if (response.success && response.data) {
        const data = response.data;
        setSyncProgress({
          message: "전체 동기화 완료!",
          detail: `${data.totalCompanies}개 회사, 생성 ${data.totalCreated}개, 연결 ${data.totalLinked}개`
        });
        toast.success(
          `전체 동기화 완료: ${data.totalCompanies}개 회사, 생성 ${data.totalCreated}개, 연결 ${data.totalLinked}개`
        );
        // 그룹 데이터 새로고침
        await loadGroupsData();
      } else {
        setSyncProgress(null);
        toast.error(`전체 동기화 실패: ${response.error || "알 수 없는 오류"}`);
      }
    } catch (error: any) {
      setSyncProgress(null);
      toast.error(`전체 동기화 실패: ${error.message}`);
    } finally {
      setIsSyncing(false);
      setSyncDirection(null);
      // 3초 후 진행 메시지 초기화
      setTimeout(() => setSyncProgress(null), 3000);
    }
  };

  // 그룹 수정 버튼 클릭
  const handleEditGroup = (group: ScreenGroup, e: React.MouseEvent) => {
    e.stopPropagation();
    setEditingGroup(group);
    setIsGroupModalOpen(true);
  };

  // 그룹 삭제 버튼 클릭
  const handleDeleteGroup = (group: ScreenGroup, e?: React.MouseEvent) => {
    e?.stopPropagation();
    setDeletingGroup(group);
    setDeleteScreensWithGroup(false);
    setDeleteNumberingRules(false);
    setIsDeleteDialogOpen(true);
  };

  // 그룹과 모든 하위 그룹의 화면을 재귀적으로 수집
  // 같은 회사의 그룹만 필터링하여 다른 회사 화면이 잘못 수집되는 것을 방지
  const getAllScreensInGroupRecursively = (groupId: number, targetCompanyCode?: string): ScreenDefinition[] => {
    const result: ScreenDefinition[] = [];
    // 부모 그룹의 company_code 확인
    const parentGroup = groups.find(g => g.id === groupId);
    const companyCode = targetCompanyCode || parentGroup?.company_code;
    
    // 현재 그룹의 화면들
    const currentGroupScreens = getScreensInGroup(groupId);
    result.push(...currentGroupScreens);
    
    // 같은 회사 + 같은 부모를 가진 하위 그룹들 찾기
    const childGroups = groups.filter((g) => 
      (g as any).parent_group_id === groupId &&
      (!companyCode || g.company_code === companyCode)
    );
    for (const childGroup of childGroups) {
      const childScreens = getAllScreensInGroupRecursively(childGroup.id, companyCode);
      result.push(...childScreens);
    }
    
    return result;
  };

  // 모든 하위 그룹 ID를 재귀적으로 수집 (삭제 순서: 자식 → 부모)
  // 같은 회사의 그룹만 필터링하여 다른 회사 그룹이 잘못 삭제되는 것을 방지
  const getAllChildGroupIds = (groupId: number, targetCompanyCode?: string): number[] => {
    const result: number[] = [];
    // 부모 그룹의 company_code 확인
    const parentGroup = groups.find(g => g.id === groupId);
    const companyCode = targetCompanyCode || parentGroup?.company_code;
    
    // 같은 회사 + 같은 부모를 가진 그룹만 필터링
    const childGroups = groups.filter((g) => 
      (g as any).parent_group_id === groupId && 
      (!companyCode || g.company_code === companyCode)
    );
    
    for (const childGroup of childGroups) {
      // 자식의 자식들을 먼저 수집 (깊은 곳부터)
      const grandChildIds = getAllChildGroupIds(childGroup.id, companyCode);
      result.push(...grandChildIds);
      result.push(childGroup.id);
    }
    
    return result;
  };

  // 그룹 삭제 확인
  const confirmDeleteGroup = async () => {
    if (!deletingGroup) return;

    // 🔍 디버깅: 삭제 대상 그룹 정보
    console.log("========== 그룹 삭제 디버깅 ==========");
    console.log("삭제 대상 그룹:", {
      id: deletingGroup.id,
      name: deletingGroup.group_name,
      company_code: deletingGroup.company_code,
      parent_group_id: (deletingGroup as any).parent_group_id
    });

    // 🔍 디버깅: 전체 groups 배열에서 같은 회사 그룹 출력
    const sameCompanyGroups = groups.filter(g => g.company_code === deletingGroup.company_code);
    console.log("같은 회사 그룹들:", sameCompanyGroups.map(g => ({
      id: g.id,
      name: g.group_name,
      parent_group_id: (g as any).parent_group_id
    })));

    // 삭제 전 통계 수집 (화면 수는 삭제 전에 계산)
    const totalScreensToDelete = getAllScreensInGroupRecursively(deletingGroup.id).length;
    const childGroupIds = getAllChildGroupIds(deletingGroup.id);

    // 🔍 디버깅: 수집된 하위 그룹 ID들
    console.log("수집된 하위 그룹 ID들:", childGroupIds);
    console.log("하위 그룹 상세:", childGroupIds.map(id => {
      const g = groups.find(grp => grp.id === id);
      return g ? { id: g.id, name: g.group_name, parent_group_id: (g as any).parent_group_id } : { id, name: "NOT_FOUND" };
    }));
    console.log("==========================================");

    // 총 작업 수 계산 (화면 + 하위 그룹 + 현재 그룹)
    const totalSteps = totalScreensToDelete + childGroupIds.length + 1;
    let currentStep = 0;

    try {
      setIsDeleting(true);
      setDeleteProgress({ current: 0, total: totalSteps, message: "삭제 준비 중..." });

      // 화면도 함께 삭제하는 경우
      if (deleteScreensWithGroup) {
        // 현재 그룹 + 모든 하위 그룹의 화면을 재귀적으로 수집
        const allScreens = getAllScreensInGroupRecursively(deletingGroup.id);
        if (allScreens.length > 0) {
          const { screenApi } = await import("@/lib/api/screen");
          
          // 화면을 하나씩 삭제하면서 진행률 업데이트
          for (let i = 0; i < allScreens.length; i++) {
            const screen = allScreens[i];
            currentStep++;
            setDeleteProgress({ 
              current: currentStep, 
              total: totalSteps, 
              message: `화면 삭제 중: ${screen.screenName}` 
            });
            await screenApi.deleteScreen(screen.screenId, "그룹 삭제와 함께 삭제", true); // force: true로 의존성 무시
          }
          console.log(`✅ 그룹 및 하위 그룹 내 화면 ${allScreens.length}개 삭제 완료`);
        }
      }

      // 하위 그룹들을 먼저 삭제 (자식 → 부모 순서)
      for (let i = 0; i < childGroupIds.length; i++) {
        const childId = childGroupIds[i];
        const childGroup = groups.find(g => g.id === childId);
        currentStep++;
        setDeleteProgress({ 
          current: currentStep, 
          total: totalSteps, 
          message: `하위 그룹 삭제 중: ${childGroup?.group_name || childId}` 
        });
        await deleteScreenGroup(childId);
        console.log(`✅ 하위 그룹 ${childId} 삭제 완료`);
      }

      // 최종적으로 대상 그룹 삭제
      currentStep++;
      setDeleteProgress({ current: currentStep, total: totalSteps, message: "그룹 삭제 완료 중..." });
      const isRootGroup = !deletingGroup.parent_group_id;
      const response = await deleteScreenGroup(deletingGroup.id, {
        deleteNumberingRules: isRootGroup && deleteNumberingRules,
      });
      if (response.success) {
        const messages = [];
        if (deleteScreensWithGroup) messages.push(`화면 ${totalScreensToDelete}개`);
        if (isRootGroup && deleteNumberingRules) messages.push("채번 규칙");
        toast.success(
          messages.length > 0
            ? `그룹과 ${messages.join(", ")}이(가) 삭제되었습니다`
            : "그룹이 삭제되었습니다"
        );
        await loadGroupsData();
        window.dispatchEvent(new CustomEvent("screen-list-refresh"));
      } else {
        showErrorToast("그룹 삭제에 실패했습니다", response.message, { guidance: "하위 항목이 있는 경우 먼저 삭제해 주세요." });
      }
    } catch (error) {
      console.error("그룹 삭제 실패:", error);
      showErrorToast("그룹 삭제에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
    } finally {
      setIsDeleting(false);
      setDeleteProgress({ current: 0, total: 0, message: "" });
      setIsDeleteDialogOpen(false);
      setDeletingGroup(null);
      setDeleteScreensWithGroup(false);
      setDeleteNumberingRules(false);
    }
  };

  // 단일 화면 삭제 버튼 클릭
  const handleDeleteScreen = (screen: ScreenDefinition) => {
    setDeletingScreen(screen);
    setIsScreenDeleteDialogOpen(true);
  };

  // 단일 화면 삭제 확인
  const confirmDeleteScreen = async () => {
    if (!deletingScreen) return;

    try {
      setIsScreenDeleting(true);
      const { screenApi } = await import("@/lib/api/screen");
      await screenApi.deleteScreen(deletingScreen.screenId, "사용자 요청으로 삭제");
      toast.success(`"${deletingScreen.screenName}" 화면이 삭제되었습니다`);
      await loadGroupsData();
      window.dispatchEvent(new CustomEvent("screen-list-refresh"));
    } catch (error) {
      console.error("화면 삭제 실패:", error);
      showErrorToast("화면 삭제에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
    } finally {
      setIsScreenDeleting(false);
      setIsScreenDeleteDialogOpen(false);
      setDeletingScreen(null);
    }
  };

  // 화면 수정 모달 열기 (이름 변경 + 그룹 이동)
  const handleOpenEditScreenModal = (screen: ScreenDefinition) => {
    setEditingScreen(screen);
    setEditScreenName(screen.screenName);
    
    // 현재 화면이 속한 그룹 정보 찾기
    let currentGroupId: number | null = null;
    let currentScreenRole: string = "";
    let currentDisplayOrder: number = 1;
    
    // 현재 화면이 속한 그룹 찾기
    for (const group of groups) {
      if (group.screens && Array.isArray(group.screens)) {
        const screenInfo = group.screens.find((s: any) => Number(s.screen_id) === Number(screen.screenId));
        if (screenInfo) {
          currentGroupId = group.id;
          currentScreenRole = screenInfo.screen_role || "";
          currentDisplayOrder = screenInfo.display_order || 1;
          break;
        }
      }
    }
    
    setSelectedGroupForMove(currentGroupId);
    setScreenRole(currentScreenRole);
    setDisplayOrder(currentDisplayOrder);
    setIsEditScreenModalOpen(true);
  };

  // 화면 복제 모달 열기 (CopyScreenModal 사용)
  const handleOpenCopyModal = (screen: ScreenDefinition) => {
    // 현재 화면이 속한 그룹 찾기 (기본값으로 설정)
    let currentGroupId: number | null = null;
    for (const group of groups) {
      if (group.screens && Array.isArray(group.screens)) {
        const found = group.screens.find((s: any) => Number(s.screen_id) === Number(screen.screenId));
        if (found) {
          currentGroupId = group.id;
          break;
        }
      }
    }
    
    setCopyingScreen(screen);
    setCopyTargetGroupId(currentGroupId);
    setCopyMode("screen");
    setIsCopyModalOpen(true);
    setContextMenuPosition(null); // 컨텍스트 메뉴 닫기
  };

  // 그룹 복제 모달 열기 (CopyScreenModal 그룹 모드 사용)
  const handleOpenGroupCopyModal = (group: ScreenGroup) => {
    setCopyingGroup(group);
    setCopyMode("group");
    setIsCopyModalOpen(true);
    closeGroupContextMenu(); // 그룹 컨텍스트 메뉴 닫기
  };

  // 복제 성공 콜백
  const handleCopySuccess = async () => {
    console.log("🔄 복제 성공 - 새로고침 시작");
    // 그룹 목록 새로고침
    await loadGroupsData();
    console.log("✅ 그룹 목록 새로고침 완료");
    // 화면 목록 새로고침
    window.dispatchEvent(new CustomEvent("screen-list-refresh"));
    console.log("✅ 화면 목록 새로고침 이벤트 발송 완료");
  };

  // 컨텍스트 메뉴 열기
  const handleContextMenu = (e: React.MouseEvent, screen: ScreenDefinition) => {
    e.preventDefault();
    e.stopPropagation();
    setContextMenuScreen(screen);
    setContextMenuPosition({ x: e.clientX, y: e.clientY });
  };

  // 컨텍스트 메뉴 닫기
  const closeContextMenu = () => {
    setContextMenuPosition(null);
    setContextMenuScreen(null);
  };

  // 그룹 컨텍스트 메뉴 열기
  const handleGroupContextMenu = (e: React.MouseEvent, group: ScreenGroup) => {
    e.preventDefault();
    e.stopPropagation();
    setContextMenuGroup(group);
    setContextMenuGroupPosition({ x: e.clientX, y: e.clientY });
  };

  // 그룹 컨텍스트 메뉴 닫기
  const closeGroupContextMenu = () => {
    setContextMenuGroupPosition(null);
    setContextMenuGroup(null);
  };

  // 화면 수정 저장 (이름 변경 + 그룹 이동)
  const saveScreenEdit = async () => {
    if (!editingScreen) return;

    try {
      // 1. 화면 이름이 변경되었으면 업데이트
      if (editScreenName.trim() && editScreenName !== editingScreen.screenName) {
        await screenApi.updateScreen(editingScreen.screenId, {
          screenName: editScreenName.trim(),
        });
      }

      // 2. 현재 그룹에서 제거
      const currentGroupId = Array.from(groupScreensMap.entries()).find(([_, screenIds]) =>
        screenIds.includes(editingScreen.screenId)
      )?.[0];

      if (currentGroupId) {
        // screen_group_screens에서 해당 연결 찾아서 삭제
        const currentGroup = groups.find((g) => g.id === currentGroupId);
        if (currentGroup && currentGroup.screens) {
          const screenGroupScreen = currentGroup.screens.find(
            (s: any) => s.screen_id === editingScreen.screenId
          );
          if (screenGroupScreen) {
            await removeScreenFromGroup(screenGroupScreen.id);
          }
        }
      }

      // 3. 새 그룹에 추가 (미분류가 아닌 경우)
      if (selectedGroupForMove !== null) {
        await addScreenToGroup({
          group_id: selectedGroupForMove,
          screen_id: editingScreen.screenId,
          screen_role: screenRole,
          display_order: displayOrder,
          is_default: "N",
        });
      }

      toast.success("화면이 수정되었습니다");
      loadGroupsData();
      window.dispatchEvent(new CustomEvent("screen-list-refresh"));
    } catch (error) {
      console.error("화면 수정 실패:", error);
      showErrorToast("화면 정보 수정에 실패했습니다", error, { guidance: "입력 데이터를 확인하고 다시 시도해 주세요." });
    } finally {
      setIsEditScreenModalOpen(false);
      setEditingScreen(null);
      setEditScreenName("");
      setSelectedGroupForMove(null);
      setScreenRole("");
      setDisplayOrder(1);
    }
  };

  // 그룹 경로 가져오기 (계층 구조 표시용)
  const getGroupPath = (groupId: number): string => {
    const group = groups.find((g) => g.id === groupId);
    if (!group) return "";
    
    const path: string[] = [group.group_name];
    let currentGroup = group;
    
    while (currentGroup.parent_group_id) {
      const parent = groups.find((g) => g.id === currentGroup.parent_group_id);
      if (parent) {
        path.unshift(parent.group_name);
        currentGroup = parent;
      } else {
        break;
      }
    }
    
    return path.join(" > ");
  };

  // 그룹 레벨 가져오기 (들여쓰기용)
  const getGroupLevel = (groupId: number): number => {
    const group = groups.find((g) => g.id === groupId);
    return group?.group_level || 1;
  };

  // 그룹을 계층 구조로 정렬
  const getSortedGroups = (): typeof groups => {
    const result: typeof groups = [];
    
    const addChildren = (parentId: number | null, level: number) => {
      const children = groups
        .filter((g) => g.parent_group_id === parentId)
        .sort((a, b) => (a.display_order || 0) - (b.display_order || 0));
      
      for (const child of children) {
        result.push({ ...child, group_level: level });
        addChildren(child.id, level + 1);
      }
    };
    
    addChildren(null, 1);
    return result;
  };

  // 검색어로 그룹 필터링 (띄어쓰기로 구분된 여러 키워드 - 계층적 검색)
  const getFilteredGroups = useMemo(() => {
    if (!searchTerm.trim()) {
      return groups; // 검색어가 없으면 모든 그룹 반환
    }

    // 검색어를 띄어쓰기로 분리하고 빈 문자열 제거
    const keywords = searchTerm.toLowerCase().trim().split(/\s+/).filter(k => k.length > 0);
    
    if (keywords.length === 0) {
      return groups;
    }

    // 그룹의 조상 ID들을 가져오는 함수
    const getAncestorIds = (groupId: number): Set<number> => {
      const ancestors = new Set<number>();
      let current = groups.find(g => g.id === groupId);
      while (current?.parent_group_id) {
        ancestors.add(current.parent_group_id);
        current = groups.find(g => g.id === current!.parent_group_id);
      }
      return ancestors;
    };

    // 첫 번째 키워드와 일치하는 그룹 찾기
    let currentMatchingIds = new Set<number>();
    for (const group of groups) {
      const groupName = group.group_name.toLowerCase();
      if (groupName.includes(keywords[0])) {
        currentMatchingIds.add(group.id);
      }
    }

    // 일치하는 그룹이 없으면 빈 배열 반환
    if (currentMatchingIds.size === 0) {
      return [];
    }

    // 나머지 키워드들을 순차적으로 처리 (계층적 검색)
    for (let i = 1; i < keywords.length; i++) {
      const keyword = keywords[i];
      const nextMatchingIds = new Set<number>();
      
      for (const group of groups) {
        const groupName = group.group_name.toLowerCase();
        if (groupName.includes(keyword)) {
          // 이 그룹의 조상 중에 이전 키워드와 일치하는 그룹이 있는지 확인
          const ancestors = getAncestorIds(group.id);
          const hasMatchingAncestor = Array.from(currentMatchingIds).some(id => 
            ancestors.has(id) || id === group.id
          );
          
          if (hasMatchingAncestor) {
            nextMatchingIds.add(group.id);
          }
        }
      }
      
      // 매칭되는 게 있으면 업데이트, 없으면 이전 결과 유지
      if (nextMatchingIds.size > 0) {
        // 이전 키워드 매칭도 유지 (상위 폴더 표시를 위해)
        nextMatchingIds.forEach(id => currentMatchingIds.add(id));
        currentMatchingIds = nextMatchingIds;
      }
    }

    // 최종 매칭 결과
    const finalMatchingIds = currentMatchingIds;

    // 표시할 그룹 ID 집합
    const groupsToShow = new Set<number>();
    
    // 일치하는 그룹의 상위 그룹들도 포함 (계층 유지를 위해)
    const addParents = (groupId: number) => {
      const group = groups.find(g => g.id === groupId);
      if (group) {
        groupsToShow.add(group.id);
        if (group.parent_group_id) {
          addParents(group.parent_group_id);
        }
      }
    };

    // 하위 그룹들을 추가하는 함수
    const addChildren = (groupId: number) => {
      const children = groups.filter(g => g.parent_group_id === groupId);
      for (const child of children) {
        groupsToShow.add(child.id);
        addChildren(child.id);
      }
    };

    // 최종 매칭 그룹들의 상위 추가
    for (const groupId of finalMatchingIds) {
      addParents(groupId);
    }

    // 마지막 키워드와 일치하는 그룹의 하위만 추가
    for (const groupId of finalMatchingIds) {
      addChildren(groupId);
    }

    // 필터링된 그룹만 반환
    return groups.filter(g => groupsToShow.has(g.id));
  }, [groups, searchTerm]);

  // 검색 시 해당 그룹이 일치하는지 확인 (하이라이트용)
  const isGroupMatchingSearch = (groupName: string): boolean => {
    if (!searchTerm.trim()) return false;
    const keywords = searchTerm.toLowerCase().trim().split(/\s+/).filter(k => k.length > 0);
    const name = groupName.toLowerCase();
    return keywords.some(keyword => name.includes(keyword));
  };

  // 검색 시 해당 그룹이 자동으로 펼쳐져야 하는지 확인
  // (검색어와 일치하는 그룹의 상위 + 마지막 검색어와 일치하는 그룹도 자동 펼침)
  const shouldAutoExpandForSearch = useMemo(() => {
    if (!searchTerm.trim()) return new Set<number>();
    
    const keywords = searchTerm.toLowerCase().trim().split(/\s+/).filter(k => k.length > 0);
    if (keywords.length === 0) return new Set<number>();

    // 그룹의 조상 ID들을 가져오는 함수
    const getAncestorIds = (groupId: number): Set<number> => {
      const ancestors = new Set<number>();
      let current = groups.find(g => g.id === groupId);
      while (current?.parent_group_id) {
        ancestors.add(current.parent_group_id);
        current = groups.find(g => g.id === current!.parent_group_id);
      }
      return ancestors;
    };

    // 계층적 검색으로 최종 일치 그룹 찾기 (getFilteredGroups와 동일한 로직)
    let currentMatchingIds = new Set<number>();
    for (const group of groups) {
      const groupName = group.group_name.toLowerCase();
      if (groupName.includes(keywords[0])) {
        currentMatchingIds.add(group.id);
      }
    }

    for (let i = 1; i < keywords.length; i++) {
      const keyword = keywords[i];
      const nextMatchingIds = new Set<number>();
      
      for (const group of groups) {
        const groupName = group.group_name.toLowerCase();
        if (groupName.includes(keyword)) {
          const ancestors = getAncestorIds(group.id);
          const hasMatchingAncestor = Array.from(currentMatchingIds).some(id => 
            ancestors.has(id) || id === group.id
          );
          
          if (hasMatchingAncestor) {
            nextMatchingIds.add(group.id);
          }
        }
      }
      
      if (nextMatchingIds.size > 0) {
        nextMatchingIds.forEach(id => currentMatchingIds.add(id));
        currentMatchingIds = nextMatchingIds;
      }
    }

    // 자동 펼침 대상: 일치 그룹의 상위 + 일치 그룹 자체
    const autoExpandIds = new Set<number>();
    
    const addParents = (groupId: number) => {
      const group = groups.find(g => g.id === groupId);
      if (group?.parent_group_id) {
        autoExpandIds.add(group.parent_group_id);
        addParents(group.parent_group_id);
      }
    };

    for (const groupId of currentMatchingIds) {
      autoExpandIds.add(groupId); // 일치하는 그룹 자체도 펼침 (화면 표시를 위해)
      addParents(groupId);
    }

    return autoExpandIds;
  }, [groups, searchTerm]);

  // 그룹 데이터 새로고침
  const loadGroupsData = async () => {
    try {
      setLoading(true);
      const response = await getScreenGroups({ size: 1000, excludePop: true });
      if (response.success && response.data) {
        setGroups(response.data);

        // 각 그룹별 화면 목록 매핑
        const screenMap = new Map<number, number[]>();
        for (const group of response.data) {
          if (group.screens && Array.isArray(group.screens)) {
            screenMap.set(
              group.id,
              group.screens.map((s: any) => s.screen_id)
            );
          }
        }
        setGroupScreensMap(screenMap);
      }
    } catch (error) {
      console.error("그룹 목록 로드 실패:", error);
    } finally {
      setLoading(false);
    }
  };

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

  const ungroupedScreens = getUngroupedScreens();

  return (
    <div className="h-full flex flex-col overflow-hidden">
      {/* 그룹 추가 & 동기화 버튼 */}
      <div className="flex-shrink-0 border-b p-2 space-y-2">
        <Button
          onClick={handleAddGroup}
          variant="outline"
          size="sm"
          className="w-full gap-2"
        >
          <Plus className="h-4 w-4" />
          그룹 추가
        </Button>
{isSuperAdmin && (
          <Button
            onClick={handleOpenSyncDialog}
            variant="ghost"
            size="sm"
            className="w-full gap-2 text-muted-foreground"
          >
            <RefreshCw className="h-4 w-4" />
            메뉴 동기화
          </Button>
        )}
      </div>

      {/* 트리 목록 */}
      <div className="flex-1 overflow-auto p-2">
        {/* 검색 결과 없음 표시 */}
        {searchTerm.trim() && getFilteredGroups.length === 0 && (
          <div className="py-8 text-center text-sm text-muted-foreground">
            &quot;{searchTerm}&quot;와 일치하는 폴더가 없습니다
          </div>
        )}
        
        {/* 그룹화된 화면들 (대분류만 먼저 렌더링) */}
        {getFilteredGroups
          .filter((g) => !(g as any).parent_group_id) // 대분류만 (parent_group_id가 null)
          .map((group) => {
          const groupId = String(group.id);
          const isExpanded = expandedGroups.has(groupId) || shouldAutoExpandForSearch.has(group.id); // 검색 시 상위 그룹만 자동 확장
          const groupScreens = getScreensInGroup(group.id);
          const isMatching = isGroupMatchingSearch(group.group_name); // 검색어 일치 여부
            
            // 하위 그룹들 찾기 (필터링된 그룹에서만)
            const childGroups = getFilteredGroups.filter((g) => (g as any).parent_group_id === group.id);

          return (
            <div key={groupId} className="mb-1">
              {/* 그룹 헤더 */}
              <div
                className={cn(
                  "flex items-center gap-2 rounded-lg px-2 py-1.5 cursor-pointer hover:bg-muted/40 transition-colors",
                  "text-sm font-medium group/item",
                  isMatching && "bg-primary/5 dark:bg-primary/10" // 검색 일치 하이라이트 (연한 배경)
                )}
                onClick={() => toggleGroup(groupId)}
                onContextMenu={(e) => handleGroupContextMenu(e, group)}
              >
                {isExpanded ? (
                  <ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground" />
                ) : (
                  <ChevronRight className="h-4 w-4 shrink-0 text-muted-foreground" />
                )}
                {isExpanded ? (
                  <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-warning/15"><FolderOpen className="h-3.5 w-3.5 text-warning" /></span>
                ) : (
                  <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-warning/15"><Folder className="h-3.5 w-3.5 text-warning" /></span>
                )}
                <span className={cn("truncate flex-1", isMatching && "font-medium text-primary/80")}>{group.group_name}</span>
                <Badge variant="secondary" className="text-xs font-mono">
                  {groupScreens.length}
                </Badge>
                {/* 그룹 메뉴 버튼 */}
                <DropdownMenu>
                  <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                    <Button
                      variant="ghost"
                      size="icon"
                      className="h-6 w-6 opacity-0 group-hover/item:opacity-100"
                    >
                      <MoreVertical className="h-3 w-3" />
                    </Button>
                  </DropdownMenuTrigger>
                  <DropdownMenuContent align="end">
                    <DropdownMenuItem onClick={(e) => handleEditGroup(group, e as any)}>
                      <Edit className="mr-2 h-4 w-4" />
                      수정
                    </DropdownMenuItem>
                    <DropdownMenuSeparator />
                    <DropdownMenuItem
                      onClick={(e) => handleDeleteGroup(group, e as any)}
                      className="text-destructive"
                    >
                      <Trash2 className="mr-2 h-4 w-4" />
                      삭제
                    </DropdownMenuItem>
                  </DropdownMenuContent>
                </DropdownMenu>
              </div>

              {/* 그룹 내 하위 그룹들 */}
              {isExpanded && childGroups.length > 0 && (
                <div className="relative ml-6 mt-1 space-y-0.5">
                  <div className="absolute left-[14px] top-0 bottom-0 w-px bg-border/40" />
                  {childGroups.map((childGroup) => {
                    const childGroupId = String(childGroup.id);
                    const isChildExpanded = expandedGroups.has(childGroupId) || shouldAutoExpandForSearch.has(childGroup.id); // 검색 시 상위 그룹만 자동 확장
                    const childScreens = getScreensInGroup(childGroup.id);
                    const isChildMatching = isGroupMatchingSearch(childGroup.group_name);
                    
                    // 손자 그룹들 (3단계) - 필터링된 그룹에서만
                    const grandChildGroups = getFilteredGroups.filter((g) => (g as any).parent_group_id === childGroup.id);

                    return (
                      <div key={childGroupId}>
                        {/* 중분류 헤더 */}
                        <div
                          className={cn(
                            "flex items-center gap-2 rounded-lg px-2 py-1.5 cursor-pointer hover:bg-muted/40 transition-colors",
                            "text-xs font-medium group/item",
                            isChildMatching && "bg-primary/5 dark:bg-primary/10"
                          )}
                          onClick={() => toggleGroup(childGroupId)}
                          onContextMenu={(e) => handleGroupContextMenu(e, childGroup)}
                        >
                          {isChildExpanded ? (
                            <ChevronDown className="h-3 w-3 shrink-0 text-muted-foreground" />
                          ) : (
                            <ChevronRight className="h-3 w-3 shrink-0 text-muted-foreground" />
                          )}
                          {isChildExpanded ? (
                            <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-primary/15"><FolderOpen className="h-3.5 w-3.5 text-primary" /></span>
                          ) : (
                            <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-primary/15"><Folder className="h-3.5 w-3.5 text-primary" /></span>
                          )}
                          <span className={cn("truncate flex-1", isChildMatching && "font-medium text-primary/80")}>{childGroup.group_name}</span>
                          <Badge variant="secondary" className="text-[10px] h-4 font-mono">
                            {childScreens.length}
                          </Badge>
                          <DropdownMenu>
                            <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-5 w-5 opacity-0 group-hover/item:opacity-100"
                              >
                                <MoreVertical className="h-3 w-3" />
                              </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end">
                              <DropdownMenuItem onClick={(e) => handleEditGroup(childGroup, e as any)}>
                                <Edit className="mr-2 h-4 w-4" />
                                수정
                              </DropdownMenuItem>
                              <DropdownMenuSeparator />
                              <DropdownMenuItem
                                onClick={(e) => handleDeleteGroup(childGroup, e as any)}
                                className="text-destructive"
                              >
                                <Trash2 className="mr-2 h-4 w-4" />
                                삭제
                              </DropdownMenuItem>
                            </DropdownMenuContent>
                          </DropdownMenu>
                        </div>

                        {/* 중분류 내 손자 그룹들 (소분류) */}
                        {isChildExpanded && grandChildGroups.length > 0 && (
                          <div className="relative ml-6 mt-1 space-y-0.5">
                            <div className="absolute left-[14px] top-0 bottom-0 w-px bg-border/30" />
                            {grandChildGroups.map((grandChild) => {
                              const grandChildId = String(grandChild.id);
                              const isGrandExpanded = expandedGroups.has(grandChildId) || shouldAutoExpandForSearch.has(grandChild.id); // 검색 시 상위 그룹만 자동 확장
                              const grandScreens = getScreensInGroup(grandChild.id);
                              const isGrandMatching = isGroupMatchingSearch(grandChild.group_name);

                              return (
                                <div key={grandChildId}>
                                  {/* 소분류 헤더 */}
                                  <div
                                    className={cn(
                                      "flex items-center gap-2 rounded-lg px-2 py-1.5 cursor-pointer hover:bg-muted/40 transition-colors",
                                      "text-xs group/item",
                                      isGrandMatching && "bg-primary/5 dark:bg-primary/10"
                                    )}
                                    onClick={() => toggleGroup(grandChildId)}
                                    onContextMenu={(e) => handleGroupContextMenu(e, grandChild)}
                                  >
                                    {isGrandExpanded ? (
                                      <ChevronDown className="h-3 w-3 shrink-0 text-muted-foreground" />
                                    ) : (
                                      <ChevronRight className="h-3 w-3 shrink-0 text-muted-foreground" />
                                    )}
                                    {isGrandExpanded ? (
                                      <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-success/15"><FolderOpen className="h-3.5 w-3.5 text-success" /></span>
                                    ) : (
                                      <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-success/15"><Folder className="h-3.5 w-3.5 text-success" /></span>
                                    )}
                                    <span className={cn("truncate flex-1", isGrandMatching && "font-medium text-primary/80")}>{grandChild.group_name}</span>
                                    <Badge variant="outline" className="text-[10px] h-4 font-mono">
                                      {grandScreens.length}
                                    </Badge>
                                    <DropdownMenu>
                                      <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
                                        <Button
                                          variant="ghost"
                                          size="icon"
                                          className="h-5 w-5 opacity-0 group-hover/item:opacity-100"
                                        >
                                          <MoreVertical className="h-3 w-3" />
                                        </Button>
                                      </DropdownMenuTrigger>
                                      <DropdownMenuContent align="end">
                                        <DropdownMenuItem onClick={(e) => handleEditGroup(grandChild, e as any)}>
                                          <Edit className="mr-2 h-4 w-4" />
                                          수정
                                        </DropdownMenuItem>
                                        <DropdownMenuSeparator />
                                        <DropdownMenuItem
                                          onClick={(e) => handleDeleteGroup(grandChild, e as any)}
                                          className="text-destructive"
                                        >
                                          <Trash2 className="mr-2 h-4 w-4" />
                                          삭제
                                        </DropdownMenuItem>
                                      </DropdownMenuContent>
                                    </DropdownMenu>
                                  </div>

                                  {/* 소분류 내 화면들 */}
                                  {isGrandExpanded && (
                                    <div className="ml-6 mt-1 space-y-0.5">
                                      {grandScreens.length === 0 ? (
                                        <div className="pl-6 py-2 text-xs text-muted-foreground">
                                          화면이 없습니다
                                        </div>
                                      ) : (
                                        grandScreens.map((screen) => (
                                          <div
                                            key={screen.screenId}
                                            className={cn(
                                              "flex items-center gap-2 rounded-md px-2 py-1.5 cursor-pointer transition-colors duration-150",
                                              "text-xs hover:bg-muted/60",
                                              selectedScreen?.screenId === screen.screenId && "bg-primary/10 border-l-2 border-primary"
                                            )}
                                            onClick={() => handleScreenClickInGroup(screen, grandChild)}
                                            onDoubleClick={() => handleScreenDoubleClick(screen)}
                                            onContextMenu={(e) => handleContextMenu(e, screen)}
                                          >
                                            <Monitor className="h-3 w-3 shrink-0 text-primary" />
                                            <span className="truncate flex-1">{screen.screenName}</span>
                                            <span className="text-[10px] text-muted-foreground truncate max-w-[80px]">
                                              {screen.screenCode}
                                            </span>
                                          </div>
                                        ))
                                      )}
                                    </div>
                                  )}
                                </div>
                              );
                            })}
                          </div>
                        )}

                        {/* 중분류 내 화면들 */}
                        {isChildExpanded && (
                          <div className="ml-6 mt-1 space-y-0.5">
                            {childScreens.length === 0 && grandChildGroups.length === 0 ? (
                              <div className="pl-6 py-2 text-xs text-muted-foreground">
                                화면이 없습니다
                              </div>
                            ) : (
                              childScreens.map((screen) => (
                                <div
                                  key={screen.screenId}
                                  className={cn(
                                    "flex items-center gap-2 rounded-md px-2 py-1.5 cursor-pointer transition-colors duration-150",
                                    "text-xs hover:bg-muted/60",
                                    selectedScreen?.screenId === screen.screenId && "bg-primary/10 border-l-2 border-primary"
                                  )}
                                  onClick={() => handleScreenClickInGroup(screen, childGroup)}
                                  onDoubleClick={() => handleScreenDoubleClick(screen)}
                                  onContextMenu={(e) => handleContextMenu(e, screen)}
                                >
                                  <Monitor className="h-3 w-3 shrink-0 text-primary" />
                                  <span className="truncate flex-1">{screen.screenName}</span>
                                  <span className="text-[10px] text-muted-foreground truncate max-w-[80px]">
                                    {screen.screenCode}
                                  </span>
                                </div>
                              ))
                            )}
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
              )}

              {/* 그룹 내 화면들 (대분류 직속) */}
              {isExpanded && (
                <div className="ml-4 mt-1 space-y-0.5">
                  {groupScreens.length === 0 && childGroups.length === 0 ? (
                    <div className="pl-6 py-2 text-xs text-muted-foreground">
                      화면이 없습니다
                    </div>
                  ) : (
                    groupScreens.map((screen) => (
                      <div
                        key={screen.screenId}
                        className={cn(
                          "flex items-center gap-2 rounded-md px-2 py-1.5 cursor-pointer transition-colors duration-150",
                          "text-sm hover:bg-muted/60 group/screen",
                          selectedScreen?.screenId === screen.screenId && "bg-primary/10 border-l-2 border-primary"
                        )}
                        onClick={() => handleScreenClickInGroup(screen, group)}
                        onDoubleClick={() => handleScreenDoubleClick(screen)}
                        onContextMenu={(e) => handleContextMenu(e, screen)}
                      >
                        <Monitor className="h-4 w-4 shrink-0 text-primary" />
                        <span className="truncate flex-1">{screen.screenName}</span>
                        <span className="text-xs text-muted-foreground truncate max-w-[100px]">
                          {screen.screenCode}
                        </span>
                      </div>
                    ))
                  )}
                </div>
              )}
            </div>
          );
        })}

        {/* 미분류 화면들 */}
        {ungroupedScreens.length > 0 && (
          <div className="mb-1">
            <div
              className={cn(
                "flex items-center gap-2 rounded-lg px-2 py-1.5 cursor-pointer hover:bg-muted/40 transition-colors",
                "text-sm font-medium text-muted-foreground"
              )}
              onClick={() => toggleGroup("ungrouped")}
            >
              {expandedGroups.has("ungrouped") ? (
                <ChevronDown className="h-4 w-4 shrink-0" />
              ) : (
                <ChevronRight className="h-4 w-4 shrink-0" />
              )}
              <Folder className="h-4 w-4 shrink-0" />
              <span className="truncate flex-1">미분류</span>
              <Badge variant="outline" className="text-xs font-mono">
                {ungroupedScreens.length}
              </Badge>
            </div>

            {expandedGroups.has("ungrouped") && (
              <div className="ml-4 mt-1 space-y-0.5">
                {ungroupedScreens.map((screen) => (
                  <div
                    key={screen.screenId}
                    className={cn(
                      "flex items-center gap-2 rounded-md px-2 py-1.5 cursor-pointer transition-colors duration-150",
                      "text-sm hover:bg-muted/60",
                      selectedScreen?.screenId === screen.screenId && "bg-primary/10 border-l-2 border-primary"
                    )}
                    onClick={() => handleScreenClick(screen)}
                    onDoubleClick={() => handleScreenDoubleClick(screen)}
                    onContextMenu={(e) => handleContextMenu(e, screen)}
                  >
                    <Monitor className="h-4 w-4 shrink-0 text-primary" />
                    <span className="truncate flex-1">{screen.screenName}</span>
                    <span className="text-xs text-muted-foreground truncate max-w-[100px]">
                      {screen.screenCode}
                    </span>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}

        {groups.length === 0 && ungroupedScreens.length === 0 && (
          <div className="flex flex-col items-center justify-center py-8 text-center">
            <Monitor className="h-12 w-12 text-muted-foreground/50 mb-2" />
            <p className="text-sm text-muted-foreground">등록된 화면이 없습니다</p>
          </div>
        )}
      </div>

      {/* 그룹 추가/수정 모달 */}
      <ScreenGroupModal
        isOpen={isGroupModalOpen}
        onClose={() => {
          setIsGroupModalOpen(false);
          setEditingGroup(null);
        }}
        onSuccess={loadGroupsData}
        group={editingGroup}
      />

      {/* 화면/그룹 복제 모달 (CopyScreenModal 사용) */}
      <CopyScreenModal
        isOpen={isCopyModalOpen}
        onClose={() => {
          setIsCopyModalOpen(false);
          setCopyingScreen(null);
          setCopyingGroup(null);
        }}
        sourceScreen={copyMode === "screen" ? copyingScreen : null}
        onCopySuccess={handleCopySuccess}
        mode={copyMode}
        sourceGroup={copyMode === "group" ? copyingGroup : null}
        groups={groups}
        targetGroupId={copyTargetGroupId}
        allScreens={screens}
      />

      {/* 그룹 삭제 확인 다이얼로그 */}
      <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
        <AlertDialogContent className="max-w-[95vw] sm:max-w-[500px] border-destructive/50">
          <AlertDialogHeader>
            <AlertDialogTitle className="text-base sm:text-lg flex items-center gap-2 text-destructive">
              <AlertTriangle className="h-5 w-5" />
              그룹 삭제 경고
            </AlertDialogTitle>
            <AlertDialogDescription asChild>
              <div className="text-xs sm:text-sm">
                <div className="mt-2 rounded-md bg-destructive/10 border border-destructive/30 p-3">
                  <p className="font-semibold text-destructive">
                    &quot;{deletingGroup?.group_name}&quot; 그룹을 정말 삭제하시겠습니까?
                  </p>
                  <p className="mt-2 text-destructive/80">
                    {deleteScreensWithGroup 
                      ? "그룹에 속한 모든 화면, 플로우, 관련 데이터가 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다."
                      : "그룹에 속한 화면들은 미분류로 이동됩니다."
                    }
                  </p>
                </div>
              </div>
            </AlertDialogDescription>
          </AlertDialogHeader>
          
          {/* 그룹 정보 표시 */}
          {deletingGroup && (
            <div className="rounded-md border bg-muted/50 p-3 text-xs space-y-1">
              <div className="flex justify-between">
                <span className="text-muted-foreground">하위 그룹 수:</span>
                <span className="font-medium">{getAllChildGroupIds(deletingGroup.id).length}개</span>
              </div>
              <div className="flex justify-between">
                <span className="text-muted-foreground">총 화면 수 (하위 포함):</span>
                <span className="font-medium">{getAllScreensInGroupRecursively(deletingGroup.id).length}개</span>
              </div>
            </div>
          )}
          
          {/* 화면도 함께 삭제 체크박스 */}
          {deletingGroup && getAllScreensInGroupRecursively(deletingGroup.id).length > 0 && (
            <div className="flex items-center space-x-2 py-2">
              <input
                type="checkbox"
                id="deleteScreensWithGroup"
                checked={deleteScreensWithGroup}
                onChange={(e) => setDeleteScreensWithGroup(e.target.checked)}
                className="h-4 w-4 rounded border-input text-destructive focus:ring-destructive"
              />
              <label 
                htmlFor="deleteScreensWithGroup" 
                className="text-sm text-muted-foreground cursor-pointer"
              >
                화면도 함께 삭제 ({getAllScreensInGroupRecursively(deletingGroup.id).length}개)
              </label>
            </div>
          )}

          {/* 최상위 그룹일 때 채번 삭제 경고 */}
          {deletingGroup && !deletingGroup.parent_group_id && (
            <div className="space-y-3">
              <div className="rounded-md border-2 border-destructive bg-destructive/5 p-4">
                <div className="flex items-start gap-3">
                  <AlertTriangle className="mt-0.5 h-6 w-6 shrink-0 text-destructive" />
                  <div className="space-y-2">
                    <p className="text-sm font-bold text-destructive">
                      최상위 그룹 삭제 - 채번 규칙 경고
                    </p>
                    <p className="text-xs text-destructive/90 leading-relaxed">
                      이 그룹은 최상위 그룹입니다.
                      아래 체크박스를 선택하면 해당 회사의 <span className="font-bold underline">모든 채번 규칙과 채번 파트가 영구적으로 삭제</span>됩니다.
                      삭제된 채번 데이터는 복구할 수 없으며, 채번이 필요한 모든 기능이 중단됩니다.
                    </p>
                  </div>
                </div>
              </div>

              <div className="flex items-center space-x-2 rounded-md border border-destructive/30 bg-destructive/5 p-3">
                <input
                  type="checkbox"
                  id="deleteNumberingRules"
                  checked={deleteNumberingRules}
                  onChange={(e) => setDeleteNumberingRules(e.target.checked)}
                  className="h-4 w-4 rounded border-destructive text-destructive focus:ring-destructive"
                />
                <label 
                  htmlFor="deleteNumberingRules" 
                  className="cursor-pointer text-sm font-semibold text-destructive"
                >
                  채번 규칙도 함께 삭제 (위험)
                </label>
              </div>
            </div>
          )}
          
          {/* 로딩 오버레이 */}
          {isDeleting && (
            <div className="absolute inset-0 z-50 flex flex-col items-center justify-center rounded-lg bg-background/90 backdrop-blur-sm">
              <Loader2 className="h-10 w-10 animate-spin text-destructive" />
              <p className="mt-4 text-sm font-medium">{deleteProgress.message}</p>
              {deleteProgress.total > 0 && (
                <>
                  <div className="mt-3 h-2 w-48 overflow-hidden rounded-full bg-secondary">
                    <div
                      className="h-full bg-destructive transition-all duration-300"
                      style={{ width: `${Math.round((deleteProgress.current / deleteProgress.total) * 100)}%` }}
                    />
                  </div>
                  <p className="mt-2 text-xs text-muted-foreground">
                    {deleteProgress.current} / {deleteProgress.total}
                  </p>
                </>
              )}
            </div>
          )}

          <AlertDialogFooter className="gap-2 sm:gap-0">
            <AlertDialogCancel 
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
              disabled={isDeleting}
            >
              취소
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={(e) => {
                e.preventDefault();
                confirmDeleteGroup();
              }}
              disabled={isDeleting}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm bg-destructive hover:bg-destructive/90"
            >
              {isDeleting ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  삭제 중...
                </>
              ) : (
                "삭제"
              )}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 단일 화면 삭제 확인 다이얼로그 */}
      <AlertDialog open={isScreenDeleteDialogOpen} onOpenChange={setIsScreenDeleteDialogOpen}>
        <AlertDialogContent className="max-w-[95vw] sm:max-w-[500px]">
          {/* 로딩 오버레이 */}
          {isScreenDeleting && (
            <div className="absolute inset-0 z-50 flex flex-col items-center justify-center rounded-lg bg-background/90 backdrop-blur-sm">
              <Loader2 className="h-8 w-8 animate-spin text-destructive" />
              <p className="mt-3 text-sm font-medium">화면 삭제 중...</p>
            </div>
          )}
          
          <AlertDialogHeader>
            <AlertDialogTitle className="text-base sm:text-lg flex items-center gap-2 text-destructive">
              <AlertTriangle className="h-5 w-5" />
              화면 삭제 경고
            </AlertDialogTitle>
            <AlertDialogDescription asChild>
              <div className="text-xs sm:text-sm">
                <div className="mt-2 rounded-md bg-destructive/10 border border-destructive/30 p-3">
                  <p className="font-semibold text-destructive">
                    &quot;{deletingScreen?.screenName}&quot; 화면을 정말 삭제하시겠습니까?
                  </p>
                  <p className="mt-2 text-destructive/80">
                    ⚠️ 화면과 연결된 플로우, 레이아웃 데이터가 모두 삭제됩니다. 삭제된 화면은 휴지통으로 이동됩니다.
                  </p>
                </div>
              </div>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter className="gap-2 sm:gap-0">
            <AlertDialogCancel 
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
              disabled={isScreenDeleting}
            >
              취소
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={(e) => {
                e.preventDefault(); // 자동 닫힘 방지
                confirmDeleteScreen();
              }}
              disabled={isScreenDeleting}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm bg-destructive hover:bg-destructive/90"
            >
              {isScreenDeleting ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  삭제 중...
                </>
              ) : (
                "삭제"
              )}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* 화면 수정 모달 (이름 변경 + 그룹 이동) */}
      <Dialog open={isEditScreenModalOpen} onOpenChange={setIsEditScreenModalOpen}>
        <DialogContent className="max-w-[95vw] sm:max-w-[400px]">
          <DialogHeader>
            <DialogTitle className="text-base sm:text-lg">화면 수정</DialogTitle>
            <DialogDescription className="text-xs sm:text-sm">
              화면 정보를 수정하세요
            </DialogDescription>
          </DialogHeader>
          
          <div className="space-y-3 sm:space-y-4">
            {/* 화면 이름 */}
            <div>
              <Label htmlFor="edit-screen-name" className="text-xs sm:text-sm">
                화면 이름 *
              </Label>
              <Input
                id="edit-screen-name"
                value={editScreenName}
                onChange={(e) => setEditScreenName(e.target.value)}
                placeholder="화면 이름을 입력하세요"
                className="h-8 text-xs sm:h-10 sm:text-sm"
              />
            </div>

            {/* 그룹 선택 (트리 구조 + 검색) */}
            <div>
              <Label htmlFor="target-group" className="text-xs sm:text-sm">
                그룹 선택 *
              </Label>
              <Popover open={isGroupSelectOpen} onOpenChange={setIsGroupSelectOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={isGroupSelectOpen}
                    className="h-8 w-full justify-between text-xs sm:h-10 sm:text-sm"
                  >
                    {selectedGroupForMove === null
                      ? "미분류"
                      : getGroupPath(selectedGroupForMove) || "그룹 선택"}
                    <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 py-2 text-center">
                        그룹을 찾을 수 없습니다
                      </CommandEmpty>
                      <CommandGroup>
                        {/* 미분류 옵션 */}
                        <CommandItem
                          value="none"
                          onSelect={() => {
                            setSelectedGroupForMove(null);
                            setIsGroupSelectOpen(false);
                          }}
                          className="text-xs sm:text-sm"
                        >
                          <Check
                            className={cn(
                              "mr-2 h-4 w-4",
                              selectedGroupForMove === null ? "opacity-100" : "opacity-0"
                            )}
                          />
                          <Folder className="mr-2 h-4 w-4 text-muted-foreground" />
                          미분류
                        </CommandItem>
                        {/* 계층 구조로 그룹 표시 */}
                        {getSortedGroups().map((group) => (
                          <CommandItem
                            key={group.id}
                            value={`${group.group_name} ${getGroupPath(group.id)}`}
                            onSelect={() => {
                              setSelectedGroupForMove(group.id);
                              setIsGroupSelectOpen(false);
                            }}
                            className="text-xs sm:text-sm"
                          >
                            <Check
                              className={cn(
                                "mr-2 h-4 w-4",
                                selectedGroupForMove === group.id ? "opacity-100" : "opacity-0"
                              )}
                            />
                            {/* 들여쓰기로 계층 표시 */}
                            <span
                              style={{ marginLeft: `${((group.group_level || 1) - 1) * 16}px` }}
                              className="flex items-center"
                            >
                              <Folder className="mr-2 h-4 w-4 text-muted-foreground" />
                              {group.group_name}
                            </span>
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
              <p className="text-muted-foreground mt-1 text-[10px] sm:text-xs">
                계층 구조로 표시됩니다. 검색으로 빠르게 찾을 수 있습니다.
              </p>
            </div>

            {/* 화면 역할 입력 (그룹이 선택된 경우만) */}
            {selectedGroupForMove !== null && (
              <>
                <div>
                  <Label htmlFor="screen-role" className="text-xs sm:text-sm">
                    화면 역할 (선택사항)
                  </Label>
                  <Input
                    id="screen-role"
                    value={screenRole}
                    onChange={(e) => setScreenRole(e.target.value)}
                    placeholder="예: 목록, 등록, 조회, 팝업..."
                    className="h-8 text-xs sm:h-10 sm:text-sm"
                  />
                  <p className="text-muted-foreground mt-1 text-[10px] sm:text-xs">
                    화면의 용도를 자유롭게 입력하세요
                  </p>
                </div>

                <div>
                  <Label htmlFor="display-order" className="text-xs sm:text-sm">
                    표시 순서 *
                  </Label>
                  <Input
                    id="display-order"
                    type="number"
                    value={displayOrder}
                    onChange={(e) => setDisplayOrder(parseInt(e.target.value) || 1)}
                    min={1}
                    className="h-8 text-xs sm:h-10 sm:text-sm"
                  />
                  <p className="text-muted-foreground mt-1 text-[10px] sm:text-xs">
                    화면 흐름 순서 (1: 메인 그리드 → 2: 등록 폼 → 3: 팝업)
                  </p>
                </div>
              </>
            )}
          </div>

          <DialogFooter className="gap-2 sm:gap-0">
            <Button
              variant="outline"
              onClick={() => {
                setIsEditScreenModalOpen(false);
                setEditingScreen(null);
                setEditScreenName("");
                setSelectedGroupForMove(null);
                setScreenRole("");
                setDisplayOrder(1);
              }}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              취소
            </Button>
            <Button
              onClick={saveScreenEdit}
              disabled={!editScreenName.trim()}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 커스텀 컨텍스트 메뉴 */}
      {contextMenuPosition && contextMenuScreen && (
        <>
          {/* 백드롭 - 클릭 시 메뉴 닫기 */}
          <div
            className="fixed inset-0 z-40"
            onClick={closeContextMenu}
            onContextMenu={(e) => {
              e.preventDefault();
              closeContextMenu();
            }}
          />
          {/* 컨텍스트 메뉴 */}
          <div
            className="fixed z-50 min-w-[150px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
            style={{
              left: contextMenuPosition.x,
              top: contextMenuPosition.y,
            }}
          >
            <div
              className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm hover:bg-accent"
              onClick={() => {
                handleOpenCopyModal(contextMenuScreen);
              }}
            >
              <Copy className="mr-2 h-4 w-4" />
              복제
            </div>
            <div className="my-1 h-px bg-border" />
              <div
                className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm hover:bg-accent"
                onClick={() => {
                  handleOpenEditScreenModal(contextMenuScreen);
                  closeContextMenu();
                }}
              >
                <Edit className="mr-2 h-4 w-4" />
                수정
              </div>
            <div className="my-1 h-px bg-border" />
            <div
              className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent"
              onClick={() => {
                handleDeleteScreen(contextMenuScreen);
                closeContextMenu();
              }}
            >
              <Trash2 className="mr-2 h-4 w-4" />
              삭제
            </div>
          </div>
        </>
      )}

      {/* 그룹 컨텍스트 메뉴 */}
      {contextMenuGroupPosition && contextMenuGroup && (
        <>
          {/* 백드롭 - 클릭 시 메뉴 닫기 */}
          <div
            className="fixed inset-0 z-40"
            onClick={closeGroupContextMenu}
            onContextMenu={(e) => {
              e.preventDefault();
              closeGroupContextMenu();
            }}
          />
          {/* 컨텍스트 메뉴 */}
          <div
            className="fixed z-50 min-w-[150px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
            style={{
              left: contextMenuGroupPosition.x,
              top: contextMenuGroupPosition.y,
            }}
          >
            <div
              className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm hover:bg-accent"
              onClick={() => handleOpenGroupCopyModal(contextMenuGroup)}
            >
              <Copy className="mr-2 h-4 w-4" />
              그룹 복제
            </div>
            <div className="my-1 h-px bg-border" />
              <div
                className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm hover:bg-accent"
                onClick={() => {
                  setEditingGroup(contextMenuGroup);
                  setIsGroupModalOpen(true);
                  closeGroupContextMenu();
                }}
              >
                <Edit className="mr-2 h-4 w-4" />
                수정
              </div>
            <div className="my-1 h-px bg-border" />
            <div
              className="flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm text-destructive hover:bg-accent"
              onClick={() => {
                handleDeleteGroup(contextMenuGroup);
                closeGroupContextMenu();
              }}
            >
              <Trash2 className="mr-2 h-4 w-4" />
              그룹 삭제
            </div>
          </div>
        </>
      )}

      {/* 메뉴-화면그룹 동기화 다이얼로그 */}
      <Dialog open={isSyncDialogOpen} onOpenChange={setIsSyncDialogOpen}>
        <DialogContent className="max-w-[95vw] sm:max-w-[500px] overflow-hidden">
          {/* 동기화 진행 중 오버레이 (삭제와 동일한 스타일) */}
          {isSyncing && (
            <div className="absolute inset-0 z-50 flex flex-col items-center justify-center rounded-lg bg-background/90 backdrop-blur-sm">
              <Loader2 className="h-10 w-10 animate-spin text-primary" />
              <p className="mt-4 text-sm font-medium">{syncProgress?.message || "동기화 중..."}</p>
              {syncProgress?.detail && (
                <p className="mt-1 text-xs text-muted-foreground">{syncProgress.detail}</p>
              )}
              <div className="mt-3 h-2 w-48 overflow-hidden rounded-full bg-secondary">
                <div
                  className="h-full bg-primary animate-pulse"
                  style={{ width: "100%" }}
                />
              </div>
            </div>
          )}
          <DialogHeader>
            <DialogTitle className="text-base sm:text-lg">메뉴-화면 동기화</DialogTitle>
            <DialogDescription className="text-xs sm:text-sm">
              화면관리의 폴더 구조와 메뉴관리를 연동합니다.
            </DialogDescription>
          </DialogHeader>

          {/* 최고 관리자: 회사 선택 */}
          {isSuperAdmin && (
            <div className="space-y-2">
              <Label className="text-xs sm:text-sm">
                <Building2 className="inline-block h-4 w-4 mr-1" />
                동기화할 회사 선택
              </Label>
              <Popover open={isSyncCompanySelectOpen} onOpenChange={setIsSyncCompanySelectOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={isSyncCompanySelectOpen}
                    className="h-10 w-full justify-between text-sm"
                  >
                    {selectedCompanyCode
                      ? companies.find((c) => c.company_code === selectedCompanyCode)?.company_name || selectedCompanyCode
                      : "회사를 선택하세요"}
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="p-0 w-full" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                  <Command>
                    <CommandInput placeholder="회사 검색..." className="text-sm" />
                    <CommandList>
                      <CommandEmpty className="text-sm py-2 text-center">회사를 찾을 수 없습니다.</CommandEmpty>
                      <CommandGroup>
                        {companies.map((company) => (
                          <CommandItem
                            key={company.company_code}
                            value={company.company_code}
                            onSelect={() => handleCompanySelect(company.company_code)}
                            className="text-sm"
                          >
                            <Check
                              className={cn(
                                "mr-2 h-4 w-4",
                                selectedCompanyCode === company.company_code ? "opacity-100" : "opacity-0"
                              )}
                            />
                            {company.company_name}
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>
          )}

          {/* 현재 상태 표시 */}
          {syncStatus ? (
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="rounded-md border p-3">
                  <div className="text-xs text-muted-foreground mb-1">화면관리</div>
                  <div className="text-lg font-semibold">{syncStatus.screenGroups.total}개</div>
                  <div className="text-xs text-muted-foreground">
                    연결됨: {syncStatus.screenGroups.linked} / 미연결: {syncStatus.screenGroups.unlinked}
                  </div>
                </div>
                <div className="rounded-md border p-3">
                  <div className="text-xs text-muted-foreground mb-1">사용자 메뉴</div>
                  <div className="text-lg font-semibold">{syncStatus.menuItems.total}개</div>
                  <div className="text-xs text-muted-foreground">
                    연결됨: {syncStatus.menuItems.linked} / 미연결: {syncStatus.menuItems.unlinked}
                  </div>
                </div>
              </div>

              {syncStatus.potentialMatches.length > 0 && (
                <div className="rounded-md border p-3 bg-muted/50">
                  <div className="text-xs font-medium mb-2">자동 매칭 가능 ({syncStatus.potentialMatches.length}개)</div>
                  <div className="text-xs text-muted-foreground space-y-1 max-h-24 overflow-auto">
                    {syncStatus.potentialMatches.slice(0, 5).map((match, i) => (
                      <div key={i}>
                        {match.menuName} = {match.groupName}
                      </div>
                    ))}
                    {syncStatus.potentialMatches.length > 5 && (
                      <div>...외 {syncStatus.potentialMatches.length - 5}개</div>
                    )}
                  </div>
                </div>
              )}

              {/* 동기화 버튼 */}
              <div className="space-y-2">
                <Button
                  onClick={() => handleSync("screen-to-menu")}
                  disabled={isSyncing}
                  variant="outline"
                  className="w-full justify-start gap-2 border-primary/20 bg-primary/10/50 hover:bg-primary/10/70 hover:border-primary/40"
                >
                  {isSyncing && syncDirection === "screen-to-menu" ? (
                    <Loader2 className="h-4 w-4 animate-spin text-primary" />
                  ) : (
                    <FolderTree className="h-4 w-4 text-primary" />
                  )}
                  <span className="flex-1 text-left text-primary">화면관리 → 메뉴 동기화</span>
                  <span className="text-xs text-primary/70">
                    폴더 구조를 메뉴에 반영
                  </span>
                </Button>
                <Button
                  onClick={() => handleSync("menu-to-screen")}
                  disabled={isSyncing}
                  variant="outline"
                  className="w-full justify-start gap-2 border-success/20 bg-success/5 hover:bg-success/10 hover:border-success/30"
                >
                  {isSyncing && syncDirection === "menu-to-screen" ? (
                    <Loader2 className="h-4 w-4 animate-spin text-success" />
                  ) : (
                    <FolderInput className="h-4 w-4 text-success" />
                  )}
                  <span className="flex-1 text-left text-success">메뉴 → 화면관리 동기화</span>
                  <span className="text-xs text-success/70">
                    메뉴 구조를 폴더에 반영
                  </span>
                </Button>
              </div>

              {/* 전체 동기화 (최고 관리자만) */}
              {isSuperAdmin && (
                <div className="border-t pt-3 mt-3">
                  <Button
                    onClick={handleSyncAll}
                    disabled={isSyncing}
                    variant="default"
                    className="w-full justify-start gap-2"
                  >
                    {isSyncing && syncDirection === "all" ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <RefreshCw className="h-4 w-4" />
                    )}
                    <span className="flex-1 text-left">전체 회사 동기화</span>
                    <span className="text-xs text-primary-foreground/70">
                      모든 회사 양방향 동기화
                    </span>
                  </Button>
                </div>
              )}
            </div>
          ) : isSuperAdmin && !selectedCompanyCode ? (
            <div className="flex flex-col items-center justify-center py-8 text-center">
              <Building2 className="h-10 w-10 text-muted-foreground mb-3" />
              <p className="text-sm text-muted-foreground mb-4">
                개별 회사 동기화를 하려면 회사를 선택해주세요.
              </p>
              
              {/* 전체 회사 동기화 버튼 (회사 선택 없이도 표시) */}
              <div className="w-full border-t pt-4">
                <Button
                  onClick={handleSyncAll}
                  disabled={isSyncing}
                  variant="default"
                  className="w-full justify-start gap-2"
                >
                  {isSyncing && syncDirection === "all" ? (
                    <Loader2 className="h-4 w-4 animate-spin" />
                  ) : (
                    <RefreshCw className="h-4 w-4" />
                  )}
                  <span className="flex-1 text-left">전체 회사 동기화</span>
                  <span className="text-xs text-primary-foreground/70">
                    모든 회사 양방향 동기화
                  </span>
                </Button>
              </div>
            </div>
          ) : (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
            </div>
          )}

          <DialogFooter>
            <Button
              variant="ghost"
              onClick={() => setIsSyncDialogOpen(false)}
              disabled={isSyncing}
            >
              닫기
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

    </div>
  );
}