import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import { Search, ArrowLeft, X, Tag } from 'lucide-react';
import { useQuery, useInfiniteQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useInView } from 'react-intersection-observer';

import {
  Calendar,
  CategoryFilter,
  ScheduleCard,
  UndatedScheduleCard,
  BirthdayCard,
  DebutCard,
} from '@/components/pc/public';
import { DebutCelebrationDialog, BirthdayCelebrationDialog } from '@/components/common';
import { fireBirthdayConfetti, fireDebutConfetti } from '@/utils';
import { getSchedules, searchSchedules } from '@/api';
import { useScheduleStore } from '@/stores';
import { getTodayKST } from '@/utils';
import { SEARCH_LIMIT } from '@/constants';

/**
 * PC 스케줄 페이지
 */
function PCSchedule() {
  const navigate = useNavigate();
  const scrollContainerRef = useRef(null);
  const searchContainerRef = useRef(null);
  const categoryRef = useRef(null);

  // 상태 관리 (zustand store)
  const {
    currentDate,
    setCurrentDate,
    selectedDate: storedSelectedDate,
    setSelectedDate: setStoredSelectedDate,
    selectedCategories,
    setSelectedCategories,
    isSearchMode,
    setIsSearchMode,
    searchInput,
    setSearchInput,
    searchTerm,
    setSearchTerm,
  } = useScheduleStore();

  // 초기값 설정
  const selectedDate = storedSelectedDate === undefined ? getTodayKST() : storedSelectedDate;
  const setSelectedDate = setStoredSelectedDate;

  // 로컬 상태
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1);
  const [suggestions, setSuggestions] = useState([]);
  const [originalSearchQuery, setOriginalSearchQuery] = useState('');
  const [showCategoryTooltip, setShowCategoryTooltip] = useState(false);
  const [showDebutDialog, setShowDebutDialog] = useState(false);
  const [debutDialogInfo, setDebutDialogInfo] = useState({ isDebut: false, anniversaryYear: 0 });
  const [showBirthdayDialog, setShowBirthdayDialog] = useState(false);
  const [birthdayInfo, setBirthdayInfo] = useState({ title: '', memberImage: '', date: '' });

  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();

  // 월별 일정 데이터
  const { data: schedules = [], isLoading: loading } = useQuery({
    queryKey: ['schedules', year, month + 1],
    queryFn: () => getSchedules(year, month + 1),
  });

  // 검색 무한 스크롤
  const { ref: loadMoreRef, inView } = useInView({ threshold: 0, rootMargin: '100px' });

  const {
    data: searchData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading: isSearchLoading,
  } = useInfiniteQuery({
    queryKey: ['scheduleSearch', searchTerm],
    queryFn: async ({ pageParam = 0 }) => {
      return searchSchedules(searchTerm, { offset: pageParam, limit: SEARCH_LIMIT });
    },
    getNextPageParam: (lastPage) => {
      if (lastPage.hasMore) {
        return lastPage.offset + lastPage.schedules.length;
      }
      return undefined;
    },
    enabled: !!searchTerm && isSearchMode,
  });

  const searchResults = useMemo(() => {
    if (!searchData?.pages) return [];
    return searchData.pages.flatMap((page) => page.schedules);
  }, [searchData]);

  // 무한 스크롤 트리거
  const prevInViewRef = useRef(false);
  useEffect(() => {
    if (inView && !prevInViewRef.current && hasNextPage && !isFetchingNextPage && isSearchMode && searchTerm) {
      fetchNextPage();
    }
    prevInViewRef.current = inView;
  }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]);

  // 검색어 자동완성
  useEffect(() => {
    if (!originalSearchQuery?.trim()) {
      setSuggestions([]);
      return;
    }
    const timeoutId = setTimeout(async () => {
      try {
        const response = await fetch(`/api/schedules/suggestions?q=${encodeURIComponent(originalSearchQuery)}&limit=10`);
        if (response.ok) {
          const data = await response.json();
          setSuggestions(data.suggestions || []);
        }
      } catch {
        setSuggestions([]);
      }
    }, 200);
    return () => clearTimeout(timeoutId);
  }, [originalSearchQuery]);

  // 오늘 생일 폭죽
  useEffect(() => {
    if (loading || schedules.length === 0) return;
    const today = getTodayKST();
    const confettiKey = `birthday-confetti-${today}`;
    if (localStorage.getItem(confettiKey)) return;
    const hasBirthdayToday = schedules.some((s) => s.is_birthday && s.date === today);
    if (hasBirthdayToday) {
      const birthdaySchedule = schedules.find((s) => s.is_birthday && s.date === today);
      const timer = setTimeout(() => {
        fireBirthdayConfetti();
        setBirthdayInfo({
          title: birthdaySchedule.title || '',
          memberImage: birthdaySchedule.member_image || '',
          date: birthdaySchedule.date,
        });
        setShowBirthdayDialog(true);
        localStorage.setItem(confettiKey, 'true');
      }, 500);
      return () => clearTimeout(timer);
    }
  }, [schedules, loading]);

  // 오늘 데뷔/주년 폭죽 및 다이얼로그
  useEffect(() => {
    if (loading || schedules.length === 0) return;
    const today = getTodayKST();
    const confettiKey = `debut-confetti-${today}`;
    if (localStorage.getItem(confettiKey)) return;
    const debutSchedule = schedules.find((s) => (s.is_debut || s.is_anniversary) && s.date === today);
    if (debutSchedule) {
      const timer = setTimeout(() => {
        fireDebutConfetti();
        setDebutDialogInfo({
          isDebut: debutSchedule.is_debut,
          anniversaryYear: debutSchedule.anniversary_year || 0,
        });
        setShowDebutDialog(true);
        localStorage.setItem(confettiKey, 'true');
      }, 500);
      return () => clearTimeout(timer);
    }
  }, [schedules, loading]);

  // 외부 클릭 처리
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (categoryRef.current && !categoryRef.current.contains(event.target)) {
        setShowCategoryTooltip(false);
      }
      if (searchContainerRef.current && !searchContainerRef.current.contains(event.target)) {
        setShowSuggestions(false);
        setSelectedSuggestionIndex(-1);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  // 날짜 변경 시 스크롤 초기화
  useEffect(() => {
    if (scrollContainerRef.current) {
      scrollContainerRef.current.scrollTop = 0;
    }
  }, [selectedDate]);

  // 카테고리 추출
  const categories = useMemo(() => {
    const categoryMap = new Map();
    schedules.forEach((s) => {
      if (s.category_id && !categoryMap.has(s.category_id)) {
        categoryMap.set(s.category_id, {
          id: s.category_id,
          name: s.category_name,
          color: s.category_color,
        });
      }
    });
    return Array.from(categoryMap.values());
  }, [schedules]);

  // 카테고리별 카운트 (선택 날짜와 무관하게 해당 달 전체 기준)
  const categoryCounts = useMemo(() => {
    const source = isSearchMode && searchTerm ? searchResults : schedules;
    const counts = new Map();
    let total = 0;

    source.forEach((s) => {
      const catId = s.category_id;
      if (catId) {
        counts.set(catId, (counts.get(catId) || 0) + 1);
        total++;
      }
    });
    counts.set('total', total);
    return counts;
  }, [schedules, searchResults, isSearchMode, searchTerm]);

  // 카테고리 색상/이름 가져오기
  const getCategoryColor = useCallback(
    (categoryId, schedule = null) => {
      if (schedule?.category_color) return schedule.category_color;
      const cat = categories.find((c) => c.id === categoryId);
      return cat?.color || '#808080';
    },
    [categories]
  );

  const getCategoryName = useCallback(
    (categoryId, schedule = null) => {
      if (schedule?.category_name) return schedule.category_name;
      const cat = categories.find((c) => c.id === categoryId);
      return cat?.name || '';
    },
    [categories]
  );

  // 필터링된 스케줄
  const currentYearMonth = `${year}-${String(month + 1).padStart(2, '0')}`;

  const filteredSchedules = useMemo(() => {
    // 백엔드에서 이미 정렬된 상태로 전달됨 (특수 일정 우선)
    if (isSearchMode) {
      if (!searchTerm) return [];
      if (selectedCategories.length === 0) return searchResults;
      return searchResults.filter((s) => selectedCategories.includes(s.category_id));
    }

    return schedules.filter((s) => {
      if (s.datePrecision === 'month') return false; // 날짜 미정은 별도 처리
      const matchesDate = selectedDate ? s.date === selectedDate : s.date?.startsWith(currentYearMonth);
      const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id);
      return matchesDate && matchesCategory;
    });
  }, [schedules, selectedDate, currentYearMonth, selectedCategories, isSearchMode, searchTerm, searchResults]);

  // 날짜 미정(월만 확정) 일정 — 선택 날짜와 무관하게 해당 월이면 항상 하단에 표시
  const undatedSchedules = useMemo(() => {
    if (isSearchMode) return [];
    return schedules.filter((s) => {
      if (s.datePrecision !== 'month') return false;
      const matchesMonth = s.date?.startsWith(currentYearMonth);
      const matchesCategory = selectedCategories.length === 0 || selectedCategories.includes(s.category_id);
      return matchesMonth && matchesCategory;
    });
  }, [schedules, currentYearMonth, selectedCategories, isSearchMode]);

  // 달력 점 표시용 (카테고리만 필터링, 날짜는 한 달 전체 유지)
  // 날짜 미정 일정은 점을 찍지 않음 (특정 날짜에 속하지 않으므로)
  const calendarSchedules = useMemo(() => {
    return schedules.filter((s) => {
      if (s.datePrecision === 'month') return false;
      return selectedCategories.length === 0 || selectedCategories.includes(s.category_id);
    });
  }, [schedules, selectedCategories]);

  // 가상 스크롤
  const virtualizer = useVirtualizer({
    count: isSearchMode && searchTerm ? filteredSchedules.length : 0,
    getScrollElement: () => scrollContainerRef.current,
    estimateSize: () => 120,
    overscan: 5,
  });

  // 일정 클릭 핸들러
  const handleScheduleClick = useCallback((schedule) => {
    // 생일, 데뷔, 주년 등 특수 일정
    if (schedule.is_birthday || schedule.is_debut || schedule.is_anniversary) {
      navigate(`/schedule/${schedule.id}`);
      return;
    }
    // 유튜브(2), X(3), 콘서트(6) 카테고리
    if ([2, 3, 6].includes(schedule.category_id)) {
      navigate(`/schedule/${schedule.id}`);
      return;
    }
    // 소스 URL이 있으면 외부 링크로
    if (!schedule.description && schedule.source?.url) {
      window.open(schedule.source.url, '_blank');
    } else {
      navigate(`/schedule/${schedule.id}`);
    }
  }, [navigate]);

  // 카테고리 토글
  const toggleCategory = (categoryId) => {
    if (selectedCategories.includes(categoryId)) {
      setSelectedCategories(selectedCategories.filter((id) => id !== categoryId));
    } else {
      setSelectedCategories([...selectedCategories, categoryId]);
    }
  };

  // 검색 모드 종료
  const exitSearchMode = () => {
    setIsSearchMode(false);
    setSearchInput('');
    setOriginalSearchQuery('');
    setSearchTerm('');
    setShowSuggestions(false);
    setSelectedSuggestionIndex(-1);
    if (scrollContainerRef.current) {
      scrollContainerRef.current.scrollTop = 0;
    }
  };

  // 검색 실행
  const executeSearch = () => {
    if (searchInput.trim()) {
      setSearchTerm(searchInput);
      setShowSuggestions(false);
      setSelectedSuggestionIndex(-1);
    }
  };

  return (
    <div className="h-[calc(100vh-64px)] overflow-hidden flex flex-col">
      <div className="flex-1 flex flex-col overflow-hidden max-w-7xl mx-auto px-6 pt-16 pb-8 w-full">
        {/* 헤더 */}
        <div className="flex-shrink-0 text-center mb-8">
          <motion.h1 initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }} className="text-4xl font-bold mb-4">
            일정
          </motion.h1>
          <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.2 }} className="text-gray-500">
            프로미스나인의 다가오는 일정을 확인하세요
          </motion.p>
        </div>

        <div className="flex-1 min-h-0 grid grid-cols-3 gap-8">
          {/* 왼쪽: 달력 + 카테고리 */}
          <motion.div
            initial={{ opacity: 0, x: -20 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ delay: 0.3, duration: 0.4 }}
            className="flex flex-col gap-6 min-h-0"
          >
            <div className="flex-shrink-0">
              <Calendar
                currentDate={currentDate}
                onDateChange={setCurrentDate}
                selectedDate={selectedDate}
                onSelectDate={setSelectedDate}
                schedules={calendarSchedules}
                getCategoryColor={getCategoryColor}
                disabled={isSearchMode}
              />
            </div>
            <CategoryFilter
              categories={categories}
              selectedCategories={selectedCategories}
              onToggle={toggleCategory}
              onClear={() => setSelectedCategories([])}
              categoryCounts={categoryCounts}
              disabled={isSearchMode && searchResults.length === 0}
            />
          </motion.div>

          {/* 오른쪽: 스케줄 리스트 */}
          <motion.div
            initial={{ opacity: 0, x: 20 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ delay: 0.4, duration: 0.4 }}
            className="col-span-2 flex flex-col min-h-0"
          >
            {/* 헤더 */}
            <div className="flex items-center justify-between h-11 mb-2">
              <AnimatePresence mode="wait">
                {isSearchMode ? (
                  <motion.div
                    key="search-mode"
                    initial={{ opacity: 0, scale: 0.95 }}
                    animate={{ opacity: 1, scale: 1 }}
                    exit={{ opacity: 0, scale: 0.95 }}
                    transition={{ duration: 0.15 }}
                    className="flex items-center flex-1"
                  >
                    <div className="flex-1 relative" ref={searchContainerRef}>
                      <div className="flex items-center border border-gray-200 rounded-xl overflow-hidden">
                        <button
                          onClick={exitSearchMode}
                          className="flex items-center justify-center px-3 bg-gray-50 border-r border-gray-200 hover:bg-gray-100 transition-colors self-stretch"
                        >
                          <ArrowLeft size={18} className="text-gray-500" />
                        </button>
                        <div className="flex-1 flex items-center bg-white px-3 py-2.5">
                          <input
                            type="text"
                            placeholder="제목, 멤버, 카테고리로 검색..."
                            value={searchInput}
                            autoFocus
                            onChange={(e) => {
                              setSearchInput(e.target.value);
                              setOriginalSearchQuery(e.target.value);
                              setShowSuggestions(true);
                              setSelectedSuggestionIndex(-1);
                            }}
                            onFocus={() => setShowSuggestions(true)}
                            onKeyDown={(e) => {
                              if (e.key === 'ArrowDown') {
                                e.preventDefault();
                                const newIndex = selectedSuggestionIndex < suggestions.length - 1 ? selectedSuggestionIndex + 1 : 0;
                                setSelectedSuggestionIndex(newIndex);
                                if (suggestions[newIndex]) setSearchInput(suggestions[newIndex]);
                              } else if (e.key === 'ArrowUp') {
                                e.preventDefault();
                                const newIndex = selectedSuggestionIndex > 0 ? selectedSuggestionIndex - 1 : suggestions.length - 1;
                                setSelectedSuggestionIndex(newIndex);
                                if (suggestions[newIndex]) setSearchInput(suggestions[newIndex]);
                              } else if (e.key === 'Enter') {
                                if (selectedSuggestionIndex >= 0 && suggestions[selectedSuggestionIndex]) {
                                  setSearchInput(suggestions[selectedSuggestionIndex]);
                                  setSearchTerm(suggestions[selectedSuggestionIndex]);
                                } else if (searchInput.trim()) {
                                  setSearchTerm(searchInput);
                                }
                                setShowSuggestions(false);
                                setSelectedSuggestionIndex(-1);
                              } else if (e.key === 'Escape') {
                                exitSearchMode();
                              }
                            }}
                            className="flex-1 bg-transparent focus:outline-none text-gray-700 placeholder-gray-400 text-sm"
                          />
                          <button
                            onClick={() => {
                              setSearchInput('');
                              setOriginalSearchQuery('');
                              setShowSuggestions(false);
                            }}
                            className={`p-1 rounded transition-colors ${searchInput ? 'hover:bg-gray-100 opacity-100' : 'opacity-0 pointer-events-none'}`}
                          >
                            <X size={16} className="text-gray-400" />
                          </button>
                        </div>
                        <button
                          onClick={executeSearch}
                          className="flex items-center justify-center px-6 bg-primary hover:bg-primary/90 transition-colors self-stretch"
                        >
                          <Search size={18} className="text-white" />
                        </button>
                      </div>

                      {/* 검색어 추천 */}
                      {showSuggestions && suggestions.length > 0 && (
                        <div
                          className="absolute top-full mt-2 bg-white rounded-xl shadow-lg border border-gray-200 py-1 z-50 overflow-hidden"
                          style={{ left: '44px', right: '66px' }}
                        >
                          {suggestions.map((suggestion, index) => (
                            <button
                              key={index}
                              onClick={() => {
                                setSearchInput(suggestion);
                                setSearchTerm(suggestion);
                                setShowSuggestions(false);
                              }}
                              onMouseEnter={() => setSelectedSuggestionIndex(index)}
                              className={`w-full px-4 py-2.5 text-left flex items-center gap-3 transition-colors ${
                                selectedSuggestionIndex === index ? 'bg-primary/10 text-primary' : 'hover:bg-gray-50 text-gray-700'
                              }`}
                            >
                              <Search size={15} className={selectedSuggestionIndex === index ? 'text-primary' : 'text-gray-400'} />
                              <span className="text-sm">{suggestion}</span>
                            </button>
                          ))}
                        </div>
                      )}
                    </div>
                  </motion.div>
                ) : (
                  <motion.div
                    key="normal-mode"
                    initial={{ opacity: 0, scale: 0.95 }}
                    animate={{ opacity: 1, scale: 1 }}
                    exit={{ opacity: 0, scale: 0.95 }}
                    transition={{ duration: 0.15 }}
                    className="flex items-center gap-3 w-full"
                  >
                    <button
                      onClick={() => setIsSearchMode(true)}
                      className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
                      title="일정 검색"
                    >
                      <Search size={20} className="text-gray-500" />
                    </button>
                    <h2 className="text-lg font-bold text-gray-900">
                      {selectedDate
                        ? (() => {
                            const d = new Date(selectedDate);
                            const dayNames = ['일', '월', '화', '수', '목', '금', '토'];
                            return `${d.getMonth() + 1}월 ${d.getDate()}일 ${dayNames[d.getDay()]}요일`;
                          })()
                        : `${month + 1}월 전체 일정`}
                    </h2>
                    <div className="flex-1" />
                    {selectedCategories.length > 0 && (
                      <div className="relative" ref={categoryRef}>
                        <button
                          onClick={() => setShowCategoryTooltip(!showCategoryTooltip)}
                          className="flex items-center gap-1 px-2 py-1 bg-gray-100 rounded-md text-sm text-gray-600 hover:bg-gray-200 transition-colors"
                        >
                          <Tag size={14} />
                          <span>{selectedCategories.length}개 카테고리</span>
                        </button>
                        <AnimatePresence>
                          {showCategoryTooltip && (
                            <motion.div
                              initial={{ opacity: 0, y: -5 }}
                              animate={{ opacity: 1, y: 0 }}
                              exit={{ opacity: 0, y: -5 }}
                              className="absolute top-full left-0 mt-1 bg-white rounded-lg shadow-lg border border-gray-200 p-3 z-10 min-w-[150px]"
                            >
                              {selectedCategories.map((id) => {
                                const cat = categories.find((c) => c.id === id);
                                if (!cat) return null;
                                return (
                                  <div key={id} className="flex items-center gap-2 py-1">
                                    <span className="w-2 h-2 rounded-full" style={{ backgroundColor: cat.color }} />
                                    <span className="text-sm">{cat.name}</span>
                                  </div>
                                );
                              })}
                            </motion.div>
                          )}
                        </AnimatePresence>
                      </div>
                    )}
                    <span className="text-sm text-gray-400">{filteredSchedules.length + undatedSchedules.length}개 일정</span>
                  </motion.div>
                )}
              </AnimatePresence>
            </div>

            {/* 스케줄 목록 */}
            <div ref={scrollContainerRef} className="flex-1 min-h-0 overflow-y-auto space-y-4 py-2 pr-2">
              {loading ? (
                <div className="h-full flex items-center justify-center text-gray-500">로딩 중...</div>
              ) : filteredSchedules.length > 0 || undatedSchedules.length > 0 ? (
                isSearchMode && searchTerm ? (
                  <>
                    <div style={{ height: `${virtualizer.getTotalSize()}px`, width: '100%', position: 'relative' }}>
                      {virtualizer.getVirtualItems().map((virtualItem) => {
                        const schedule = filteredSchedules[virtualItem.index];
                        if (!schedule) return null;
                        return (
                          <div
                            key={virtualItem.key}
                            ref={virtualizer.measureElement}
                            data-index={virtualItem.index}
                            style={{
                              position: 'absolute',
                              top: 0,
                              left: 0,
                              width: '100%',
                              transform: `translateY(${virtualItem.start}px)`,
                            }}
                          >
                            <div className={virtualItem.index < filteredSchedules.length - 1 ? 'pb-4' : ''}>
                              {schedule.is_birthday ? (
                                <BirthdayCard schedule={schedule} showYear onClick={handleScheduleClick} />
                              ) : schedule.is_debut || schedule.is_anniversary ? (
                                <DebutCard schedule={schedule} showYear  />
                              ) : (
                                <ScheduleCard schedule={schedule} showYear onClick={handleScheduleClick} />
                              )}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                    <div ref={loadMoreRef} className="py-4">
                      {isFetchingNextPage && (
                        <div className="flex justify-center">
                          <div className="w-6 h-6 border-2 border-primary border-t-transparent rounded-full animate-spin" />
                        </div>
                      )}
                      {!hasNextPage && filteredSchedules.length > 0 && (
                        <div className="text-center text-sm text-gray-400">{filteredSchedules.length}개 표시 (모두 로드됨)</div>
                      )}
                    </div>
                  </>
                ) : (
                  <>
                    {filteredSchedules.map((schedule, index) => (
                      <motion.div
                        key={`${schedule.id}-${selectedDate || 'all'}`}
                        initial={{ opacity: 0 }}
                        animate={{ opacity: 1 }}
                        transition={{ delay: Math.min(index, 10) * 0.03 }}
                      >
                        {schedule.is_birthday ? (
                          <BirthdayCard schedule={schedule} onClick={handleScheduleClick} />
                        ) : schedule.is_debut || schedule.is_anniversary ? (
                          <DebutCard schedule={schedule}  />
                        ) : (
                          <ScheduleCard schedule={schedule} onClick={handleScheduleClick} />
                        )}
                      </motion.div>
                    ))}

                    {/* 날짜 미정 일정 — 우선순위 낮춰 기존 일정 아래 배치 */}
                    {undatedSchedules.length > 0 && filteredSchedules.length > 0 && (
                      <div className="flex items-center gap-3 pt-2 text-gray-300">
                        <div className="flex-1 border-t border-dashed border-gray-200" />
                        <span className="text-xs font-medium text-gray-400">날짜 미정</span>
                        <div className="flex-1 border-t border-dashed border-gray-200" />
                      </div>
                    )}
                    {undatedSchedules.map((schedule, index) => (
                      <motion.div
                        key={`undated-${schedule.id}`}
                        initial={{ opacity: 0 }}
                        animate={{ opacity: 1 }}
                        transition={{ delay: Math.min(filteredSchedules.length + index, 10) * 0.03 }}
                      >
                        <UndatedScheduleCard schedule={schedule} onClick={handleScheduleClick} />
                      </motion.div>
                    ))}
                  </>
                )
              ) : isSearchMode && searchTerm ? (
                isSearchLoading ? (
                  <div className="h-full flex items-center justify-center text-gray-500">검색 중...</div>
                ) : (
                  <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="h-full flex flex-col items-center justify-start pt-[20%]">
                    <div className="w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">
                      <svg className="w-12 h-12 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 21l-4.35-4.35M11 18a7 7 0 110-14 7 7 0 010 14z" />
                      </svg>
                    </div>
                    <p className="text-gray-400 text-lg font-medium mb-1">검색 결과가 없습니다</p>
                    <p className="text-gray-300 text-sm">
                      '<span className="text-gray-400">{searchTerm}</span>'
                      {selectedCategories.length > 0 ? ' 검색 결과가 없습니다' : '에 대한 일정을 찾을 수 없습니다'}
                    </p>
                  </motion.div>
                )
              ) : (
                !isSearchMode && (
                  <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="h-full flex flex-col items-center justify-start pt-[20%]">
                    <div className="w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">
                      <svg className="w-12 h-12 text-gray-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
                      </svg>
                    </div>
                    <p className="text-gray-400 text-lg font-medium mb-1">{selectedDate ? '일정이 없습니다' : '예정된 일정이 없습니다'}</p>
                    <p className="text-gray-300 text-sm">{selectedDate ? '다른 날짜를 선택해 보세요' : '다른 달을 확인해 보세요'}</p>
                  </motion.div>
                )
              )}
            </div>
          </motion.div>
        </div>
      </div>

      {/* 데뷔/주년 축하 다이얼로그 */}
      <DebutCelebrationDialog
        isOpen={showDebutDialog}
        onClose={() => setShowDebutDialog(false)}
        isDebut={debutDialogInfo.isDebut}
        anniversaryYear={debutDialogInfo.anniversaryYear}
      />
      <BirthdayCelebrationDialog
        isOpen={showBirthdayDialog}
        onClose={() => setShowBirthdayDialog(false)}
        title={birthdayInfo.title}
        memberImage={birthdayInfo.memberImage}
        date={birthdayInfo.date}
      />
    </div>
  );
}

export default PCSchedule;
