'use client';

import { useMenuStore, useMenuItems, useActiveMenu, useSidebarCollapsed, useMenuHydrated } from '@/stores/menuStore';
import type { SerializableMenuItem } from '@/stores/menuStore';
import type { MenuItem } from '@/stores/menuStore';
import { useRouter, usePathname } from 'next/navigation';
import Image from 'next/image';
import { useEffect, useState, useMemo, useCallback, useRef } from 'react';
import {
  Menu,
  Search,
  User,
  LogOut,
  LayoutDashboard,
  Sun,
  Moon,
  Accessibility,
  ShoppingCart,
  Building2,
  Receipt,
  Package,
  Settings,
  DollarSign,
  ChevronLeft,
  Home,
  Bell,
  Clock,
  Minus,
  Plus,
  Type,
  CalendarDays,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Sheet, SheetContent, SheetTrigger, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import Sidebar from '@/components/layout/Sidebar';
import HeaderFavoritesBar from '@/components/layout/HeaderFavoritesBar';
import CommandMenuSearch, { type CommandMenuSearchRef } from '@/components/layout/CommandMenuSearch';
import NoticePopupContainer from '@/components/common/NoticePopupModal/NoticePopupContainer';
import { useTheme, useSetTheme } from '@/stores/themeStore';
import { useAuthStore } from '@/stores/authStore';
import { deserializeMenuItems } from '@/lib/utils/menuTransform';
import { stripLocalePrefix } from '@/lib/utils/locale';
import { safeJsonParse } from '@/lib/utils';
import { useMenuPolling } from '@/hooks/useMenuPolling';
import { useCalendarScheduleInit } from '@/hooks/useCalendarScheduleInit';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';

// TodayIssue 타입 및 API
import type { TodayIssueUnreadItem } from '@/types/today-issue';
import {
  getUnreadTodayIssues,
  markTodayIssueAsRead,
  markAllTodayIssuesAsRead,
} from '@/lib/api/today-issue';

// 목업 회사 데이터
const MOCK_COMPANIES = [
  { id: 'all', name: '전체' },
  { id: 'company1', name: '(주)삼성건설' },
  { id: 'company2', name: '현대건설(주)' },
  { id: 'company3', name: '대우건설(주)' },
  { id: 'company4', name: 'GS건설(주)' },
];

// 알림 폴링 간격 (30초)
const NOTIFICATION_POLLING_INTERVAL = 30000;

// 뱃지 색상 매핑 (TodayIssueSection과 동기화)
const BADGE_COLORS: Record<string, string> = {
  '수주등록': 'bg-blue-100 text-blue-700',
  '추심이슈': 'bg-purple-100 text-purple-700',
  '안전재고': 'bg-orange-100 text-orange-700',
  '지출승인': 'bg-green-100 text-green-700',
  '세금신고': 'bg-red-100 text-red-700',
  '결재요청': 'bg-yellow-100 text-yellow-700',
  '신규업체': 'bg-emerald-100 text-emerald-700',
  '입금': 'bg-cyan-100 text-cyan-700',
  '출금': 'bg-pink-100 text-pink-700',
  '기타': 'bg-gray-100 text-gray-700',
};

interface AuthenticatedLayoutProps {
  children: React.ReactNode;
}

export default function AuthenticatedLayout({ children }: AuthenticatedLayoutProps) {
  const menuItems = useMenuItems();
  const activeMenu = useActiveMenu();
  const sidebarCollapsed = useSidebarCollapsed();
  const _hasHydrated = useMenuHydrated();
  const setActiveMenu = useMenuStore((s) => s.setActiveMenu);
  const setMenuItems = useMenuStore((s) => s.setMenuItems);
  const toggleSidebar = useMenuStore((s) => s.toggleSidebar);
  const theme = useTheme();
  const setTheme = useSetTheme();
  const logout = useAuthStore((state) => state.logout);
  const router = useRouter();
  const pathname = usePathname(); // 현재 경로 추적

  // 올해 공휴일/세무일정 데이터를 Zustand 스토어에 로드
  useCalendarScheduleInit(new Date().getFullYear());

  // 폰트 크기 조절 (12~20px, 기본 16px)
  const [fontSize, setFontSize] = useState(16);

  useEffect(() => {
    // 초기값: localStorage 또는 CSS 변수에서 읽기
    const saved = localStorage.getItem('sam-font-size');
    if (saved) {
      const size = parseInt(saved, 10);
      if (size >= 12 && size <= 20) {
        setFontSize(size);
        document.documentElement.style.setProperty('--font-size', `${size}px`);
      }
    }
  }, []);

  const handleFontSizeChange = useCallback((size: number) => {
    const clamped = Math.max(12, Math.min(20, size));
    setFontSize(clamped);
    document.documentElement.style.setProperty('--font-size', `${clamped}px`);
    localStorage.setItem('sam-font-size', String(clamped));
  }, []);

  // 확장된 서브메뉴 관리 (기본적으로 sales, master-data 확장)
  const [expandedMenus, setExpandedMenus] = useState<string[]>(['sales', 'master-data']);

  // 모바일 상태 관리
  const [isMobile, setIsMobile] = useState(false);
  const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);

  // 사용자 정보 상태
  const [userName, setUserName] = useState<string>("사용자");
  const [userPosition, setUserPosition] = useState<string>("직책");
  const [_userEmail, setUserEmail] = useState<string>("");
  const [_userCompany, setUserCompany] = useState<string>("");

  // 회사 선택 상태 (목업)
  const [selectedCompany, setSelectedCompany] = useState<string>("all");

  // Command Menu Search ref
  const commandMenuRef = useRef<CommandMenuSearchRef>(null);

  // 알림 관련 상태
  const [notificationEnabled, setNotificationEnabled] = useState(true);
  const [notifications, setNotifications] = useState<TodayIssueUnreadItem[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [isPollingPaused, setIsPollingPaused] = useState(false); // 토큰 갱신 중 폴링 일시 중지

  // 알림 벨 애니메이션 (알림 켜져 있고 읽지 않은 알림이 있을 때만)
  const bellAnimating = useMemo(() => notificationEnabled && unreadCount > 0, [notificationEnabled, unreadCount]);

  // 🔧 클라이언트 마운트 상태 (새로고침 시 스피너 표시용)
  const [isMounted, setIsMounted] = useState(false);

  // 🔧 클라이언트 마운트 확인 (새로고침 시 스피너 표시)
  useEffect(() => {
    setIsMounted(true);
  }, []);

  // 🔧 스크롤바 자동 숨김 - 스크롤 시에만 스크롤바 thumb 표시
  useEffect(() => {
    const scrollTimers = new WeakMap<Element, ReturnType<typeof setTimeout>>();

    const handleScroll = (e: Event) => {
      const target = e.target === document
        ? document.documentElement
        : e.target as Element;
      if (!target || !(target instanceof Element)) return;

      target.classList.add('is-scrolling');

      const existing = scrollTimers.get(target);
      if (existing) clearTimeout(existing);

      const timer = setTimeout(() => {
        target.classList.remove('is-scrolling');
        scrollTimers.delete(target);
      }, 1500);

      scrollTimers.set(target, timer);
    };

    document.addEventListener('scroll', handleScroll, { capture: true, passive: true });

    return () => {
      document.removeEventListener('scroll', handleScroll, { capture: true });
    };
  }, []);

  // 토큰 갱신 함수
  const refreshToken = useCallback(async (): Promise<boolean> => {
    try {
      const response = await fetch('/api/auth/refresh', {
        method: 'POST',
        credentials: 'include',
      });

      if (response.ok) {
        return true;
      } else {
        console.warn('[Notification] 토큰 갱신 실패:', response.status);
        return false;
      }
    } catch (error) {
      console.error('[Notification] 토큰 갱신 오류:', error);
      return false;
    }
  }, []);

  // 알림 데이터 가져오기 함수
  const fetchNotifications = useCallback(async (isRetry: boolean = false) => {
    // 폴링이 일시 중지 상태면 건너뛰기
    if (isPollingPaused && !isRetry) {
      return;
    }

    try {
      const response = await getUnreadTodayIssues(10);

      // 인증 에러인 경우
      if (response.authError) {
        console.warn('[Notification] 인증 에러 감지 - 토큰 갱신 시도');

        // 이미 재시도 중이면 무한 루프 방지
        if (isRetry) {
          console.error('[Notification] 토큰 갱신 후에도 인증 에러 - 폴링 중지');
          setIsPollingPaused(true);
          return;
        }

        // 폴링 일시 중지
        setIsPollingPaused(true);

        // 토큰 갱신 시도
        const refreshSuccess = await refreshToken();

        if (refreshSuccess) {
          // 토큰 갱신 성공 - 폴링 재개 및 재시도
          setIsPollingPaused(false);
          await fetchNotifications(true); // 재시도 플래그로 호출
        } else {
          // 토큰 갱신 실패 - 폴링 유지 중지 (로그인 필요)
          console.error('[Notification] 토큰 갱신 실패 - 폴링 중지, 재로그인 필요');
          // 여기서 로그아웃하거나 알림을 보여줄 수 있음
        }
        return;
      }

      // 정상 응답
      if (response.success && response.data) {
        setNotifications(response.data.items);
        setUnreadCount(response.data.total);

        // 혹시 이전에 폴링이 중지되어 있었다면 재개
        if (isPollingPaused) {
          setIsPollingPaused(false);
        }
      }
    } catch (error) {
      console.error('[Notification] 알림 조회 실패:', error);
    }
  }, [isPollingPaused, refreshToken]);

  // 알림 폴링 (30초마다)
  useEffect(() => {
    if (!isMounted) return;

    // 초기 로드
    fetchNotifications();

    // 폴링 시작 (폴링이 중지되지 않은 경우에만)
    const intervalId = setInterval(() => {
      if (!isPollingPaused) {
        fetchNotifications();
      }
    }, NOTIFICATION_POLLING_INTERVAL);

    return () => {
      clearInterval(intervalId);
    };
  }, [isMounted, fetchNotifications, isPollingPaused]);

  // 알림 클릭 핸들러 (읽음 처리 + 페이지 이동)
  const handleNotificationClick = useCallback(async (notification: TodayIssueUnreadItem) => {
    try {
      // 읽음 처리
      await markTodayIssueAsRead(notification.id);

      // 로컬 상태 업데이트 (해당 알림 제거)
      setNotifications(prev => prev.filter(n => n.id !== notification.id));
      setUnreadCount(prev => Math.max(0, prev - 1));

      // 페이지 이동 (path가 있으면)
      if (notification.path) {
        router.push(notification.path);
      }
    } catch (error) {
      console.error('[Notification] 읽음 처리 실패:', error);
    }
  }, [router]);

  // 모두 읽음 처리 핸들러
  const handleMarkAllAsRead = useCallback(async () => {
    try {
      const response = await markAllTodayIssuesAsRead();
      if (response.success) {
        // 로컬 상태 초기화
        setNotifications([]);
        setUnreadCount(0);
      }
    } catch (error) {
      console.error('[Notification] 모두 읽음 처리 실패:', error);
    }
  }, []);

  // 메뉴 폴링 (30초마다 메뉴 변경 확인)
  // 백엔드 GET /api/v1/menus API 준비되면 자동 동작
  const { restartAfterAuth } = useMenuPolling({
    enabled: true,
    interval: 30000, // 30초
    onMenuUpdated: () => {
    },
    onSessionExpired: () => {
    },
  });

  // 로그인 성공 후 메뉴 폴링 재시작
  useEffect(() => {
    const justLoggedIn = sessionStorage.getItem('auth_just_logged_in');
    if (justLoggedIn === 'true') {
      sessionStorage.removeItem('auth_just_logged_in');
      restartAfterAuth();
    }
  }, [restartAfterAuth]);

  // 모바일 감지 + 폴더블 기기 대응 (Galaxy Fold 등)
  // 🔧 Debounce 적용: resize 시 API 중복 호출 방지
  // - isMobile 상태 변경 시 전체 자식 컴포넌트가 리마운트됨
  // - debounce 없이 빠른 resize 시 API가 여러 번 호출되는 문제 해결
  useEffect(() => {
    let debounceTimer: ReturnType<typeof setTimeout> | null = null;

    const updateViewport = () => {
      // visualViewport API 우선 사용 (폴더블 기기에서 더 정확)
      const width = window.visualViewport?.width ?? window.innerWidth;
      const height = window.visualViewport?.height ?? window.innerHeight;

      // CSS 변수는 즉시 업데이트 (레이아웃 깨짐 방지)
      document.documentElement.style.setProperty('--app-width', `${width}px`);
      document.documentElement.style.setProperty('--app-height', `${height}px`);

      // isMobile 상태 변경은 debounce 적용 (컴포넌트 리마운트 최소화)
      if (debounceTimer) {
        clearTimeout(debounceTimer);
      }
      debounceTimer = setTimeout(() => {
        setIsMobile(width < 768);
      }, 300); // 300ms debounce - 데이터 로딩 안정성 개선
    };

    // 초기 값 설정 (debounce 없이 즉시)
    const width = window.visualViewport?.width ?? window.innerWidth;
    const height = window.visualViewport?.height ?? window.innerHeight;
    setIsMobile(width < 768);
    document.documentElement.style.setProperty('--app-width', `${width}px`);
    document.documentElement.style.setProperty('--app-height', `${height}px`);

    // resize 이벤트
    window.addEventListener('resize', updateViewport);

    // visualViewport resize 이벤트 (폴더블 기기 화면 전환 감지)
    window.visualViewport?.addEventListener('resize', updateViewport);

    return () => {
      if (debounceTimer) {
        clearTimeout(debounceTimer);
      }
      window.removeEventListener('resize', updateViewport);
      window.visualViewport?.removeEventListener('resize', updateViewport);
    };
  }, []);

  // 서버에서 받은 사용자 정보로 초기화
  useEffect(() => {
    // ⚠️ Allow rendering even before hydration (Zustand persist rehydration can be slow)
    // Commenting out the hydration check prevents infinite loading spinner
    // if (!_hasHydrated) return;

    // localStorage에서 사용자 정보 가져오기
    const userDataStr = localStorage.getItem("user");
    if (userDataStr) {
      const userData = safeJsonParse<Record<string, unknown> | null>(userDataStr, null);
      if (!userData) return;

      // 사용자 이름, 직책, 이메일, 회사 설정
      setUserName((userData.name as string) || "사용자");
      setUserPosition((userData.position as string) || "직책");
      setUserEmail((userData.email as string) || "");
      setUserCompany((userData.company as string) || (userData.company_name as string) || "");

      // 서버에서 받은 메뉴 배열이 있으면 사용, 없으면 기본 메뉴 사용
      if (userData.menu && Array.isArray(userData.menu) && userData.menu.length > 0) {
        // SerializableMenuItem (iconName string)을 MenuItem (icon component)로 변환
        const deserializedMenus = deserializeMenuItems(userData.menu as SerializableMenuItem[]);
        setMenuItems(deserializedMenus);
      } else {
        // API가 준비될 때까지 임시 기본 메뉴
        const defaultMenu: MenuItem[] = [
          { id: "dashboard", label: "대시보드", icon: LayoutDashboard, path: "/dashboard" },
          {
            id: "sales",
            label: "판매관리",
            icon: ShoppingCart,
            path: "#",
            children: [
              { id: "customer-management", label: "거래처관리", icon: Building2, path: "/sales/client-management-sales-admin" },
              { id: "quote-management", label: "견적관리", icon: Receipt, path: "/sales/quote-management" },
              { id: "pricing-management", label: "단가관리", icon: DollarSign, path: "/sales/pricing-management" },
            ],
          },
          {
            id: "master-data",
            label: "기준정보",
            icon: Settings,
            path: "#",
            children: [
              { id: "item-master", label: "품목기준관리", icon: Package, path: "/master-data/item-master-data-management" },
              { id: "calendar-management", label: "달력관리", icon: CalendarDays, path: "/settings/calendar-management" },
            ],
          },
        ];
        setMenuItems(defaultMenu);
      }
      // 즐겨찾기는 사용자가 사이드바에서 별표로 직접 추가
      // useFavoritesStore.getState().initializeIfEmpty(DEFAULT_FAVORITES);
    }
  }, [_hasHydrated, setMenuItems]);

  // 현재 경로에 맞는 메뉴 자동 활성화 (URL 직접 입력, 뒤로가기 대응)
  // 3depth 이상 메뉴 구조 지원
  useEffect(() => {
    if (!pathname || menuItems.length === 0) return;

    // 경로 정규화 (로케일 제거)
    const normalizedPath = stripLocalePrefix(pathname);

    // 메뉴 탐색 함수: 메인 메뉴와 서브메뉴 모두 탐색
    // 경로 매칭: 정확히 일치하거나 하위 경로인 경우만 매칭
    const isPathMatch = (menuPath: string, currentPath: string): boolean => {
      if (currentPath === menuPath) return true;
      return currentPath.startsWith(menuPath + '/');
    };

    // 재귀적으로 모든 depth의 메뉴를 탐색 (3depth 이상 지원)
    type MenuMatch = { menuId: string; ancestorIds: string[]; pathLength: number };

    const findMenuRecursive = (
      items: MenuItem[],
      currentPath: string,
      ancestors: string[] = []
    ): MenuMatch[] => {
      const matches: MenuMatch[] = [];

      for (const item of items) {
        // 현재 메뉴의 경로 매칭 확인
        if (item.path && item.path !== '#' && isPathMatch(item.path, currentPath)) {
          matches.push({
            menuId: item.id,
            ancestorIds: ancestors,
            pathLength: item.path.length,
          });
        }

        // 자식 메뉴가 있으면 재귀적으로 탐색
        if (item.children && item.children.length > 0) {
          const childMatches = findMenuRecursive(
            item.children,
            currentPath,
            [...ancestors, item.id] // 현재 메뉴를 조상 목록에 추가
          );
          matches.push(...childMatches);
        }
      }

      return matches;
    };

    const matches = findMenuRecursive(menuItems, normalizedPath);

    if (matches.length > 0) {
      // 가장 긴 경로(가장 구체적인 매칭) 선택
      matches.sort((a, b) => b.pathLength - a.pathLength);
      const result = matches[0];

      // 활성 메뉴 설정
      setActiveMenu(result.menuId);

      // 모든 조상 메뉴를 확장 (3depth 이상 지원)
      if (result.ancestorIds.length > 0) {
        setExpandedMenus(prev => {
          const newExpanded = [...prev];
          result.ancestorIds.forEach(id => {
            if (!newExpanded.includes(id)) {
              newExpanded.push(id);
            }
          });
          return newExpanded;
        });
      }
    }
     
  }, [pathname, menuItems, setActiveMenu]);

  const handleMenuClick = (menuId: string, path: string) => {
    // 네비게이션 우선 실행 - setActiveMenu는 pathname 기반 useEffect가 처리
    router.push(path);
  };

  // 접힌 사이드바 자동 펼침 (아이콘 클릭 시)
  const expandSidebar = useCallback(() => {
    if (sidebarCollapsed) {
      toggleSidebar();
    }
  }, [sidebarCollapsed, toggleSidebar]);

  // 서브메뉴 토글 함수
  const toggleSubmenu = (menuId: string) => {
    setExpandedMenus(prev =>
      prev.includes(menuId)
        ? prev.filter(id => id !== menuId)
        : [...prev, menuId]
    );
  };

  // 전체 메뉴 열기/닫기 토글 함수
  const toggleAllMenus = useCallback(() => {
    if (expandedMenus.length > 0) {
      // 하나라도 열려있으면 전부 닫기
      setExpandedMenus([]);
    } else {
      // 전부 닫혀있으면 children 있는 메뉴 전부 열기
      const menusWithChildren = menuItems
        .filter(item => item.children && item.children.length > 0)
        .map(item => item.id);
      setExpandedMenus(menusWithChildren);
    }
  }, [expandedMenus, menuItems]);

  const handleLogout = async () => {
    try {
      // AuthContext의 logout() 호출 (완전한 캐시 정리 수행)
      // - Zustand 스토어 초기화
      // - sessionStorage 캐시 삭제 (page_config_*, mes-*)
      // - localStorage 사용자 데이터 삭제
      // - 서버 로그아웃 API 호출 (HttpOnly 쿠키 삭제)
      await logout();

      // 로그인 페이지로 리다이렉트
      router.push('/login');
    } catch (error) {
      console.error('로그아웃 처리 중 오류:', error);
      // 에러가 나도 로그인 페이지로 이동
      router.push('/login');
    }
  };

  // ⚠️ FIXED: Removed hydration check to prevent infinite loading spinner
  // The hydration check was causing the dashboard to show a loading spinner indefinitely
  // because Zustand persist rehydration was taking too long or not completing properly.
  // By removing this check, we allow the component to render immediately with default values
  // and update once hydration completes through the useEffect above.

  // 🔧 새로고침 시 스켈레톤 표시 (hydration 전)
  if (!isMounted) {
    return (
      <>
        {/* 모바일 스켈레톤 (md 미만) */}
        <div className="md:hidden flex flex-col bg-background min-h-screen">
          {/* 모바일 헤더 스켈레톤 */}
          <header className="m-2 p-3 rounded-2xl bg-card border animate-pulse">
            <div className="flex items-center justify-between">
              {/* 왼쪽: 햄버거 + 로고 */}
              <div className="flex items-center space-x-2">
                <div className="w-9 h-9 rounded-xl bg-muted" />
                <div className="w-9 h-9 rounded-xl bg-muted" />
                <div className="space-y-1">
                  <div className="h-4 w-10 rounded bg-muted" />
                  <div className="h-2.5 w-20 rounded bg-muted" />
                </div>
              </div>
              {/* 오른쪽: 버튼들 */}
              <div className="flex items-center space-x-1.5">
                <div className="w-8 h-8 rounded-lg bg-muted" />
                <div className="w-8 h-8 rounded-lg bg-muted" />
                <div className="w-8 h-8 rounded-lg bg-muted" />
                <div className="w-8 h-8 rounded-lg bg-muted" />
              </div>
            </div>
          </header>
          {/* 모바일 콘텐츠 스켈레톤 */}
          <div className="flex-1 px-3 space-y-4 animate-pulse">
            <div className="flex items-center gap-2">
              <div className="h-8 w-8 rounded-lg bg-muted" />
              <div className="h-6 w-32 rounded bg-muted" />
            </div>
            <div className="rounded-lg border bg-card p-4 space-y-3">
              {[1, 2, 3, 4].map((i) => (
                <div key={i} className="space-y-2">
                  <div className="h-4 w-16 rounded bg-muted" />
                  <div className="h-10 w-full rounded bg-muted" />
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* 데스크톱 스켈레톤 (md 이상) */}
        <div className="hidden md:flex min-h-screen flex-col w-full bg-background">
          {/* 헤더 스켈레톤 - 상세 버전 */}
          <header className="px-8 py-5 mx-3 mt-3 mb-0 rounded-2xl bg-card border animate-pulse">
            <div className="flex items-center justify-between">
              {/* 왼쪽: 로고 + 메뉴버튼 + 검색바 */}
              <div className="flex items-center space-x-6">
                {/* 로고 영역 */}
                <div className="flex items-center space-x-4 pr-6 border-r border-border/30">
                  <div className="w-12 h-12 rounded-xl bg-muted" />
                  <div className="space-y-1.5">
                    <div className="h-5 w-12 rounded bg-muted" />
                    <div className="h-3 w-32 rounded bg-muted" />
                  </div>
                </div>
                {/* 메뉴 버튼 */}
                <div className="w-11 h-11 rounded-xl bg-muted" />
                {/* 검색바 */}
                <div className="hidden lg:block w-96 h-11 rounded-xl bg-muted" />
              </div>
              {/* 오른쪽: 버튼들 */}
              <div className="flex items-center space-x-3">
                <div className="w-28 h-9 rounded-xl bg-muted" />
                <div className="w-32 h-9 rounded-xl bg-muted" />
                <div className="w-10 h-10 rounded-xl bg-muted" />
                <div className="w-10 h-10 rounded-xl bg-muted" />
              </div>
            </div>
          </header>

          {/* 사이드바 + 콘텐츠 스켈레톤 */}
          <div className="flex flex-1 gap-3 px-3 pb-3">
            {/* 사이드바 스켈레톤 - 상세 버전 */}
            <div className="w-[65px] mt-3 flex-shrink-0">
              <div className="h-[calc(100vh-118px)] rounded-2xl bg-card border p-2 animate-pulse">
                <div className="space-y-1 mt-2">
                  {/* 메뉴 아이콘 스켈레톤 (13개) */}
                  {[...Array(13)].map((_, i) => (
                    <div key={i} className="w-full aspect-square rounded-xl bg-muted" />
                  ))}
                </div>
              </div>
            </div>

            {/* 콘텐츠 스켈레톤 */}
            <div className="flex-1 p-3 md:p-6 space-y-6 animate-pulse">
              {/* 페이지 헤더 */}
              <div className="flex items-center gap-3">
                <div className="h-10 w-10 rounded-lg bg-muted" />
                <div className="space-y-2">
                  <div className="h-7 w-40 rounded bg-muted" />
                  <div className="h-4 w-56 rounded bg-muted" />
                </div>
              </div>
              {/* 콘텐츠 카드 */}
              <div className="rounded-lg border bg-card p-6">
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                  {[1, 2, 3, 4, 5, 6].map((i) => (
                    <div key={i} className="space-y-2">
                      <div className="h-4 w-20 rounded bg-muted" />
                      <div className="h-10 w-full rounded bg-muted" />
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>
      </>
    );
  }

  // 현재 페이지가 대시보드인지 확인
  const isDashboard = pathname?.includes('/dashboard') || activeMenu === 'dashboard';

  // 이전 페이지로 이동
  const handleGoBack = () => {
    router.back();
  };

  // 홈(대시보드)으로 이동
  const handleGoHome = () => {
    router.push('/dashboard');
  };

  // 모바일 레이아웃
  if (isMobile) {
    return (
      <div className="flex flex-col bg-background min-h-screen">
        {/* 모바일 헤더 - sam-design 스타일 */}
        <header className="sticky top-0 z-40 px-1.5 py-1.5 m-1.5 min-[320px]:px-2 min-[320px]:py-2 min-[320px]:m-2 sm:px-4 sm:py-4 sm:m-3 rounded-2xl clean-shadow bg-background border border-border">
          <div className="flex items-center justify-between">
            {/* 좌측 영역: 햄버거 메뉴 + (대시보드일 때는 로고, 다른 페이지일 때는 이전/홈 버튼) */}
            <div className="flex items-center space-x-1 min-[320px]:space-x-2">
              {/* 햄버거 메뉴 - 좌측 맨 앞 */}
              <Sheet open={isMobileSidebarOpen} onOpenChange={setIsMobileSidebarOpen}>
                <SheetTrigger asChild>
                  <Button variant="ghost" size="sm" className="min-w-[28px] min-h-[28px] min-[320px]:min-w-[36px] min-[320px]:min-h-[36px] sm:min-w-[44px] sm:min-h-[44px] p-0 rounded-xl hover:bg-accent transition-all duration-200 flex items-center justify-center">
                    <Menu className="h-4 w-4 min-[320px]:h-5 min-[320px]:w-5 sm:h-6 sm:w-6" />
                  </Button>
                </SheetTrigger>
                <SheetContent side="left" className="w-[calc(100vw-24px)] min-[320px]:w-80 p-1 bg-transparent border-none">
                  <SheetHeader className="sr-only">
                    <SheetTitle>메뉴</SheetTitle>
                  </SheetHeader>
                  <Sidebar
                    menuItems={menuItems}
                    activeMenu={activeMenu}
                    expandedMenus={expandedMenus}
                    sidebarCollapsed={false}
                    isMobile={true}
                    onMenuClick={handleMenuClick}
                    onToggleSubmenu={toggleSubmenu}
                    onToggleAll={toggleAllMenus}
                    onCloseMobileSidebar={() => setIsMobileSidebarOpen(false)}
                  />
                </SheetContent>
              </Sheet>

              {isDashboard ? (
                // 대시보드: 로고만 표시
                <div
                  className="flex items-center space-x-1 min-[320px]:space-x-2 sm:space-x-3 cursor-pointer hover:opacity-80 transition-opacity"
                  onClick={handleGoHome}
                  title="대시보드로 이동"
                >
                  <div className="w-6 h-6 min-w-6 min-h-6 min-[320px]:w-8 min-[320px]:h-8 min-[320px]:min-w-8 min-[320px]:min-h-8 sm:w-10 sm:h-10 sm:min-w-10 sm:min-h-10 flex-shrink-0 aspect-square rounded-lg min-[320px]:rounded-xl flex items-center justify-center shadow-md relative overflow-hidden">
                    <Image src="/sam-logo.png" alt="SAM" fill className="object-contain p-0.5" />
                  </div>
                  <div>
                    <h1 className="font-bold text-foreground text-left text-xs min-[320px]:text-sm sm:text-base">SAM</h1>
                  </div>
                </div>
              ) : (
                // 다른 페이지: 이전/홈 버튼 표시
                <div className="flex items-center space-x-0.5 sm:space-x-1">
                  <Button
                    variant="ghost"
                    size="sm"
                    className="min-w-[28px] min-h-[28px] min-[320px]:min-w-[36px] min-[320px]:min-h-[36px] sm:min-w-[44px] sm:min-h-[44px] p-0 rounded-xl hover:bg-accent transition-all duration-200 flex items-center justify-center"
                    onClick={handleGoBack}
                    title="이전 페이지"
                  >
                    <ChevronLeft className="h-3.5 w-3.5 min-[320px]:h-4 min-[320px]:w-4 sm:h-5 sm:w-5" />
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="min-w-[28px] min-h-[28px] min-[320px]:min-w-[36px] min-[320px]:min-h-[36px] sm:min-w-[44px] sm:min-h-[44px] p-0 rounded-xl hover:bg-accent transition-all duration-200 flex items-center justify-center"
                    onClick={handleGoHome}
                    title="홈으로"
                  >
                    <Home className="h-3.5 w-3.5 min-[320px]:h-4 min-[320px]:w-4 sm:h-5 sm:w-5" />
                  </Button>
                </div>
              )}
            </div>

            {/* 우측 영역: 즐겨찾기, 유저 드롭다운, 메뉴 */}
            <div className="flex items-center space-x-0.5 sm:space-x-1">
              {/* 즐겨찾기 바로가기 */}
              <HeaderFavoritesBar isMobile={true} />

              {/* 알림 버튼 - 드롭다운 */}
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="min-w-[28px] min-h-[28px] min-[320px]:min-w-[36px] min-[320px]:min-h-[36px] sm:min-w-[44px] sm:min-h-[44px] p-0 rounded-lg min-[320px]:rounded-xl hover:bg-accent transition-all duration-200 flex items-center justify-center relative"
                  >
                    <Bell className={`h-3.5 w-3.5 min-[320px]:h-4 min-[320px]:w-4 sm:h-5 sm:w-5 text-amber-600 ${bellAnimating ? 'animate-bell-ring' : ''}`} />
                    {/* 새 알림 표시 */}
                    {unreadCount > 0 && (
                      <span className="absolute top-1 right-1 min-[320px]:top-1.5 min-[320px]:right-1.5 sm:top-2 sm:right-2 w-1 h-1 min-[320px]:w-1.5 min-[320px]:h-1.5 sm:w-2 sm:h-2 bg-red-500 rounded-full" />
                    )}
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end" className="w-80 p-0">
                  {/* 헤더: 알림 토글 + 모두 읽음 */}
                  <div className="flex items-center justify-between px-4 py-3 border-b border-border bg-muted">
                    <div className="flex items-center gap-2">
                      <span className="font-semibold text-foreground">알림</span>
                      {unreadCount > 0 && (
                        <span className="text-xs text-muted-foreground">({unreadCount})</span>
                      )}
                    </div>
                    <div className="flex items-center gap-1">
                      {notifications.length > 0 && (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={(e) => {
                            e.preventDefault();
                            handleMarkAllAsRead();
                          }}
                          className="h-7 px-2 text-xs text-blue-600 hover:text-blue-700"
                        >
                          모두 읽음
                        </Button>
                      )}
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={(e) => {
                          e.preventDefault();
                          setNotificationEnabled(!notificationEnabled);
                        }}
                        className="h-7 px-2 text-xs"
                      >
                        {notificationEnabled ? '🔔' : '🔕'}
                      </Button>
                    </div>
                  </div>
                  {/* 알림 리스트 - 3개 초과시 스크롤 */}
                  <div className="max-h-[216px] overflow-y-auto">
                    {notifications.length === 0 ? (
                      <div className="p-6 text-center text-muted-foreground text-sm">
                        새로운 알림이 없습니다
                      </div>
                    ) : (
                      notifications.map((notification) => (
                        <div
                          key={notification.id}
                          onClick={() => handleNotificationClick(notification)}
                          className="flex items-start gap-3 p-3 border-b border-border hover:bg-accent/50 cursor-pointer"
                        >
                          {/* 배지 */}
                          <div className="flex-shrink-0">
                            <span className={`inline-flex items-center justify-center px-2 py-1 text-xs font-medium rounded-md ${
                              BADGE_COLORS[notification.badge] || BADGE_COLORS['기타']
                            }`}>
                              {notification.badge}
                            </span>
                          </div>
                          {/* 내용 */}
                          <div className="flex-1 min-w-0">
                            <p className="text-foreground font-medium text-sm truncate">{notification.content}</p>
                            <span className="text-muted-foreground text-xs">{notification.time}</span>
                          </div>
                          {/* 승인 필요 표시 */}
                          {notification.needs_approval && (
                            <span className="flex-shrink-0 w-4 h-4 rounded-full bg-red-500 text-white text-xs flex items-center justify-center font-bold">
                              !
                            </span>
                          )}
                        </div>
                      ))
                    )}
                  </div>
                </DropdownMenuContent>
              </DropdownMenu>

              {/* 유저 프로필 드롭다운 */}
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="min-w-[28px] min-h-[28px] min-[320px]:min-w-[36px] min-[320px]:min-h-[36px] sm:min-w-[44px] sm:min-h-[44px] p-0 rounded-lg min-[320px]:rounded-xl hover:bg-accent transition-all duration-200 flex items-center justify-center"
                  >
                    <div className="w-6 h-6 min-[320px]:w-8 min-[320px]:h-8 sm:w-10 sm:h-10 bg-blue-100 rounded-full flex items-center justify-center">
                      <User className="h-3.5 w-3.5 min-[320px]:h-4 min-[320px]:w-4 sm:h-5 sm:w-5 text-blue-600" />
                    </div>
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end" className="w-64 p-0 overflow-hidden">
                  {/* 사용자 정보 헤더 */}
                  <div className="bg-muted px-4 py-4 flex items-center gap-3">
                    <div className="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center flex-shrink-0">
                      <User className="h-6 w-6 text-blue-600" />
                    </div>
                    <div>
                      <p className="font-semibold text-foreground">{userName}</p>
                      <p className="text-sm text-muted-foreground">{userPosition}</p>
                    </div>
                  </div>

                  {/* 출근하기 버튼 */}
                  <div className="px-4 py-3 border-b border-border">
                    <Button
                      variant="default"
                      size="sm"
                      onClick={() => router.push('/hr/attendance')}
                      className="w-full h-10 bg-blue-500 hover:bg-blue-600 text-white rounded-lg flex items-center justify-center gap-2"
                    >
                      <Clock className="h-4 w-4" />
                      출근하기
                    </Button>
                  </div>

                  {/* 회사 선택 (목업) */}
                  <div className="px-4 py-3 border-b border-border">
                    <p className="text-xs text-muted-foreground mb-1">회사 선택</p>
                    <Select value={selectedCompany} onValueChange={setSelectedCompany}>
                      <SelectTrigger className="w-full h-9 text-sm">
                        <SelectValue placeholder="회사 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {MOCK_COMPANIES.map((company) => (
                          <SelectItem key={company.id} value={company.id}>
                            {company.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  {/* 테마 선택 */}
                  <div className="px-2 py-3">
                    <DropdownMenuItem onClick={() => setTheme('light')} className="rounded-lg">
                      <Sun className="mr-2 h-4 w-4" />
                      일반모드
                      {theme === 'light' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>
                    <DropdownMenuItem onClick={() => setTheme('dark')} className="rounded-lg">
                      <Moon className="mr-2 h-4 w-4" />
                      다크모드
                      {theme === 'dark' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>
                    <DropdownMenuItem onClick={() => setTheme('senior')} className="rounded-lg">
                      <Accessibility className="mr-2 h-4 w-4" />
                      시니어모드
                      {theme === 'senior' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>

                    {/* 구분선 */}
                    <div className="my-2 border-t border-border" />

                    {/* 글자 크기 조절 */}
                    <div className="px-2 py-1">
                      <div className="flex items-center gap-2">
                        <Type className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
                        <span className="text-xs font-medium text-muted-foreground">글자 크기</span>
                        <div className="flex items-center gap-1 ml-auto">
                          <Button
                            variant="outline"
                            size="sm"
                            className="h-7 w-7 p-0 shrink-0"
                            onClick={(e) => { e.preventDefault(); handleFontSizeChange(fontSize - 1); }}
                            disabled={fontSize <= 12}
                          >
                            <Minus className="h-3 w-3" />
                          </Button>
                          <span className="text-sm font-semibold text-foreground w-10 text-center">{fontSize}px</span>
                          <Button
                            variant="outline"
                            size="sm"
                            className="h-7 w-7 p-0 shrink-0"
                            onClick={(e) => { e.preventDefault(); handleFontSizeChange(fontSize + 1); }}
                            disabled={fontSize >= 20}
                          >
                            <Plus className="h-3 w-3" />
                          </Button>
                        </div>
                      </div>
                    </div>

                    {/* 구분선 */}
                    <div className="my-2 border-t border-border" />

                    {/* 로그아웃 */}
                    <DropdownMenuItem onClick={handleLogout} className="rounded-lg text-red-600 hover:text-red-700 hover:bg-red-50">
                      <LogOut className="mr-2 h-4 w-4" />
                      로그아웃
                    </DropdownMenuItem>
                  </div>
                </DropdownMenuContent>
              </DropdownMenu>

            </div>
          </div>
        </header>

        {/* 모바일 콘텐츠 */}
        <main className="flex-1 px-3">
          {children}
        </main>

        {/* 메뉴 검색 Command Palette (Ctrl+K / Cmd+K) */}
        <CommandMenuSearch ref={commandMenuRef} />

        {/* 공지 팝업 자동 표시 */}
        <NoticePopupContainer />
      </div>
    );
  }

  // 데스크톱 레이아웃
  return (
    <div className="min-h-screen flex flex-col w-full">
      {/* 헤더 - 전체 너비 상단 고정 */}
      <header className="clean-glass px-8 py-3 mx-3 mt-3 mb-0 rounded-2xl clean-shadow relative overflow-hidden flex-shrink-0 sticky top-3 z-50 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
          <div className="flex items-center gap-4 relative z-10">
            <div className="flex items-center space-x-6 shrink-0">
              {/* SAM 로고 섹션 - 클릭 시 대시보드로 이동 */}
              <div
                className="flex items-center space-x-4 pr-6 border-r border-border/30 cursor-pointer hover:opacity-80 transition-opacity"
                onClick={handleGoHome}
                title="대시보드로 이동"
              >
                <div className="w-12 h-12 rounded-xl flex items-center justify-center shadow-md relative overflow-hidden flex-shrink-0">
                  <Image src="/sam-logo.png" alt="SAM" fill className="object-contain p-1" />
                </div>
                <div>
                  <h1 className="text-xl font-bold text-foreground">SAM</h1>
                  <p className="text-xs text-muted-foreground font-medium">Smart Automation Management</p>
                </div>
              </div>

              {/* Menu 버튼 - 사이드바 토글 */}
              <Button
                variant="ghost"
                size="sm"
                onClick={toggleSidebar}
                className="rounded-xl transition-all duration-200 hover:bg-accent p-3"
              >
                <Menu className="h-5 w-5" />
              </Button>

              {/* 검색바 - 클릭 시 Command Palette 열기 */}
              <div
                className="relative hidden lg:block cursor-pointer"
                onClick={() => commandMenuRef.current?.open()}
              >
                <Search className="absolute left-5 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5" />
                <div className="pl-14 pr-4 w-96 h-11 clean-input border-0 bg-input-background/60 text-base rounded-xl flex items-center justify-between">
                  <span className="text-muted-foreground">메뉴 검색...</span>
                  <kbd className="hidden xl:inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">
                    <span className="text-xs">⌘</span>K
                  </kbd>
                </div>
              </div>
            </div>

            {/* 즐겨찾기 바로가기 - 남은 공간 채움 */}
            <HeaderFavoritesBar isMobile={false} />

            <div className="flex items-center space-x-3 shrink-0 ml-auto">
              {/* 알림 버튼 - 드롭다운 */}
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="p-1 rounded-xl hover:bg-transparent transition-all duration-200 relative focus-visible:ring-0 focus-visible:ring-offset-0"
                  >
                    <div className="w-14 h-14 bg-amber-50 rounded-full flex items-center justify-center">
                      <Bell className={`text-amber-500 ${bellAnimating ? 'animate-bell-ring' : ''}`} style={{ width: 23, height: 23 }} />
                    </div>
                    {/* 새 알림 표시 */}
                    {unreadCount > 0 && (
                      <span className="absolute top-0 right-0 w-3.5 h-3.5 bg-red-500 rounded-full border-2 border-background" />
                    )}
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end" className="w-80 p-0">
                  {/* 헤더: 알림 토글 + 모두 읽음 */}
                  <div className="flex items-center justify-between px-4 py-3 border-b border-border bg-muted">
                    <div className="flex items-center gap-2">
                      <span className="font-semibold text-foreground">알림</span>
                      {unreadCount > 0 && (
                        <span className="text-xs text-muted-foreground">({unreadCount})</span>
                      )}
                    </div>
                    <div className="flex items-center gap-1">
                      {notifications.length > 0 && (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={(e) => {
                            e.preventDefault();
                            handleMarkAllAsRead();
                          }}
                          className="h-7 px-2 text-xs text-blue-600 hover:text-blue-700"
                        >
                          모두 읽음
                        </Button>
                      )}
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={(e) => {
                          e.preventDefault();
                          setNotificationEnabled(!notificationEnabled);
                        }}
                        className="h-7 px-2 text-xs"
                      >
                        {notificationEnabled ? '🔔' : '🔕'}
                      </Button>
                    </div>
                  </div>
                  {/* 알림 리스트 - 3개 초과시 스크롤 */}
                  <div className="max-h-[216px] overflow-y-auto">
                    {notifications.length === 0 ? (
                      <div className="p-6 text-center text-muted-foreground text-sm">
                        새로운 알림이 없습니다
                      </div>
                    ) : (
                      notifications.map((notification) => (
                        <div
                          key={notification.id}
                          onClick={() => handleNotificationClick(notification)}
                          className="flex items-start gap-3 p-3 border-b border-border hover:bg-accent/50 cursor-pointer"
                        >
                          {/* 배지 */}
                          <div className="flex-shrink-0">
                            <span className={`inline-flex items-center justify-center px-2 py-1 text-xs font-medium rounded-md ${
                              BADGE_COLORS[notification.badge] || BADGE_COLORS['기타']
                            }`}>
                              {notification.badge}
                            </span>
                          </div>
                          {/* 내용 */}
                          <div className="flex-1 min-w-0">
                            <p className="text-foreground font-medium text-sm truncate">{notification.content}</p>
                            <span className="text-muted-foreground text-xs">{notification.time}</span>
                          </div>
                          {/* 승인 필요 표시 */}
                          {notification.needs_approval && (
                            <span className="flex-shrink-0 w-4 h-4 rounded-full bg-red-500 text-white text-xs flex items-center justify-center font-bold">
                              !
                            </span>
                          )}
                        </div>
                      ))
                    )}
                  </div>
                </DropdownMenuContent>
              </DropdownMenu>

              {/* 유저 프로필 드롭다운 */}
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" size="sm" className="hidden md:flex items-center space-x-3 pl-3 border-l border-border/30 h-auto py-2 px-3 rounded-xl hover:bg-accent transition-all duration-200">
                    <div className="w-11 h-11 bg-blue-100 rounded-full flex items-center justify-center">
                      <User className="h-5 w-5 text-blue-600" />
                    </div>
                    <div className="text-sm text-left">
                      <p className="font-bold text-foreground text-base">{userName}</p>
                      <p className="text-muted-foreground text-sm">{userPosition}</p>
                    </div>
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end" className="w-64 p-0 overflow-hidden">
                  {/* 사용자 정보 헤더 */}
                  <div className="bg-muted px-4 py-4 flex items-center gap-3">
                    <div className="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center flex-shrink-0">
                      <User className="h-6 w-6 text-blue-600" />
                    </div>
                    <div>
                      <p className="font-semibold text-foreground">{userName}</p>
                      <p className="text-sm text-muted-foreground">{userPosition}</p>
                    </div>
                  </div>

                  {/* 회사 선택 (목업) */}
                  <div className="px-4 py-3 border-b border-border">
                    <p className="text-xs text-muted-foreground mb-1">회사 선택</p>
                    <Select value={selectedCompany} onValueChange={setSelectedCompany}>
                      <SelectTrigger className="w-full h-9 text-sm">
                        <SelectValue placeholder="회사 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {MOCK_COMPANIES.map((company) => (
                          <SelectItem key={company.id} value={company.id}>
                            {company.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>

                  {/* 테마 선택 */}
                  <div className="px-2 py-3">
                    <DropdownMenuItem onClick={() => setTheme('light')} className="rounded-lg">
                      <Sun className="mr-2 h-4 w-4" />
                      일반모드
                      {theme === 'light' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>
                    <DropdownMenuItem onClick={() => setTheme('dark')} className="rounded-lg">
                      <Moon className="mr-2 h-4 w-4" />
                      다크모드
                      {theme === 'dark' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>
                    <DropdownMenuItem onClick={() => setTheme('senior')} className="rounded-lg">
                      <Accessibility className="mr-2 h-4 w-4" />
                      시니어모드
                      {theme === 'senior' && <span className="ml-auto text-primary">✓</span>}
                    </DropdownMenuItem>

                    {/* 구분선 */}
                    <div className="my-2 border-t border-border" />

                    {/* 글자 크기 조절 */}
                    <div className="px-2 py-1">
                      <div className="flex items-center gap-2">
                        <Type className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
                        <span className="text-xs font-medium text-muted-foreground">글자 크기</span>
                        <div className="flex items-center gap-1 ml-auto">
                          <Button
                            variant="outline"
                            size="sm"
                            className="h-7 w-7 p-0 shrink-0"
                            onClick={(e) => { e.preventDefault(); handleFontSizeChange(fontSize - 1); }}
                            disabled={fontSize <= 12}
                          >
                            <Minus className="h-3 w-3" />
                          </Button>
                          <span className="text-sm font-semibold text-foreground w-10 text-center">{fontSize}px</span>
                          <Button
                            variant="outline"
                            size="sm"
                            className="h-7 w-7 p-0 shrink-0"
                            onClick={(e) => { e.preventDefault(); handleFontSizeChange(fontSize + 1); }}
                            disabled={fontSize >= 20}
                          >
                            <Plus className="h-3 w-3" />
                          </Button>
                        </div>
                      </div>
                    </div>

                    {/* 구분선 */}
                    <div className="my-2 border-t border-border" />

                    {/* 로그아웃 */}
                    <DropdownMenuItem onClick={handleLogout} className="rounded-lg text-red-600 hover:text-red-700 hover:bg-red-50">
                      <LogOut className="mr-2 h-4 w-4" />
                      로그아웃
                    </DropdownMenuItem>
                  </div>
                </DropdownMenuContent>
              </DropdownMenu>
            </div>
          </div>

          {/* Subtle gradient overlay */}
          <div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-transparent via-primary/30 to-transparent"></div>
        </header>

      {/* 사이드바 + 메인 콘텐츠 영역 */}
      <div className="flex flex-1 gap-3 px-3 pb-3">
        {/* 데스크톱 사이드바 */}
        <div
          className={`sticky top-[106px] self-start h-[calc(100vh-118px)] mt-3 border-none bg-transparent transition-all duration-300 flex-shrink-0 ${
            sidebarCollapsed ? 'w-[65px]' : 'w-64'
          }`}
        >
          <Sidebar
            menuItems={menuItems}
            activeMenu={activeMenu}
            expandedMenus={expandedMenus}
            sidebarCollapsed={sidebarCollapsed}
            isMobile={false}
            onMenuClick={handleMenuClick}
            onToggleSubmenu={toggleSubmenu}
            onToggleAll={toggleAllMenus}
            onExpandSidebar={expandSidebar}
          />
        </div>

        {/* 메인 콘텐츠 */}
        <main className="flex-1 overflow-auto pl-3 md:pl-6 pr-3 pt-3 md:pt-6 pb-0">
          {children}
        </main>
      </div>

      {/* 메뉴 검색 Command Palette (Ctrl+K / Cmd+K) */}
      <CommandMenuSearch ref={commandMenuRef} />

      {/* 공지 팝업 자동 표시 */}
      <NoticePopupContainer />
    </div>
  );
}