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

import { getTodayKST, getCategoryInfo } from '@/utils';
import { getSchedules, searchSchedules } from '@/api';
import { useScheduleStore } from '@/stores';
import { MIN_YEAR, SEARCH_LIMIT } from '@/constants';
import {
  Calendar as MobileCalendar,
  ScheduleListCard as MobileScheduleListCard,
  UndatedScheduleListCard as MobileUndatedScheduleListCard,
  ScheduleSearchCard as MobileScheduleSearchCard,
  BirthdayCard as MobileBirthdayCard,
  DebutCard as MobileDebutCard,
} from '@/components/mobile';
import { DebutCelebrationDialog, BirthdayCelebrationDialog } from '@/components/common';
import { fireBirthdayConfetti, fireDebutConfetti } from '@/utils';

/**
 * 모바일 일정 페이지
 */
function MobileSchedule() {
  const navigate = useNavigate();

  // zustand store에서 상태 가져오기
  const {
    selectedDate: storedSelectedDate,
    setSelectedDate: setStoredSelectedDate,
    selectedCategories,
    setSelectedCategories,
    toggleCategory,
  } = useScheduleStore();

  // 선택된 날짜 (store에 없으면 오늘 날짜). 매 렌더 새 Date 생성을 막아
  // 다수 useMemo/useEffect가 불필요하게 재실행되지 않도록 참조 안정화.
  const selectedDate = useMemo(
    () => storedSelectedDate || new Date(),
    [storedSelectedDate]
  );
  const setSelectedDate = (date) => setStoredSelectedDate(date);

  // 카드 클릭 핸들러 (안정적 참조로 카드 React.memo 유지)
  const handleCardClick = useCallback((schedule) => {
    navigate(`/schedule/${schedule.id}`);
  }, [navigate]);

  const [isSearchMode, setIsSearchMode] = useState(false);
  const [searchInput, setSearchInput] = useState('');
  const [searchTerm, setSearchTerm] = useState('');
  const [showCalendar, setShowCalendar] = useState(false);
  const [calendarViewDate, setCalendarViewDate] = useState(() => new Date(selectedDate));
  const [calendarShowYearMonth, setCalendarShowYearMonth] = useState(false);
  const contentRef = useRef(null);
  const searchContainerRef = useRef(null);
  const searchInputRef = useRef(null);

  // 검색 추천 관련 상태
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1);
  const [originalSearchQuery, setOriginalSearchQuery] = useState('');
  const [suggestions, setSuggestions] = useState([]);
  const [lastSearchTerm, setLastSearchTerm] = useState('');
  const [showSuggestionsScreen, setShowSuggestionsScreen] = 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 enterSearchMode = () => {
    setIsSearchMode(true);
    window.history.pushState({ searchMode: true }, '');
  };

  const exitSearchMode = () => {
    setIsSearchMode(false);
    setSearchInput('');
    setOriginalSearchQuery('');
    setSearchTerm('');
    setLastSearchTerm('');
    setShowSuggestions(false);
    setShowSuggestionsScreen(false);
    setSelectedSuggestionIndex(-1);
  };

  const hideSuggestionsScreen = () => {
    setShowSuggestionsScreen(false);
    setSearchInput(lastSearchTerm);
    setOriginalSearchQuery(lastSearchTerm);
  };

  // 뒤로가기 버튼 처리
  useEffect(() => {
    const handlePopState = () => {
      if (isSearchMode) {
        if (showSuggestionsScreen && searchTerm) {
          hideSuggestionsScreen();
          window.history.pushState({ searchMode: true }, '');
        } else {
          exitSearchMode();
        }
      }
    };

    window.addEventListener('popstate', handlePopState);
    return () => window.removeEventListener('popstate', handlePopState);
  }, [isSearchMode, showSuggestionsScreen, searchTerm, lastSearchTerm]);

  // 달력 월 변경
  const changeCalendarMonth = (delta) => {
    const newDate = new Date(calendarViewDate);
    newDate.setMonth(newDate.getMonth() + delta);
    setCalendarViewDate(newDate);
  };

  const scrollContainerRef = useRef(null);
  const { ref: loadMoreRef, inView } = useInView({ threshold: 0, rootMargin: '100px' });

  // 검색 무한 스크롤
  const {
    data: searchData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading: searchLoading,
  } = useInfiniteQuery({
    queryKey: ['mobileScheduleSearch', 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 virtualizer = useVirtualizer({
    count: isSearchMode && searchTerm ? searchResults.length : 0,
    getScrollElement: () => scrollContainerRef.current,
    estimateSize: () => 100,
    overscan: 5,
  });

  // 검색어 변경 시 스크롤 위치 초기화
  useEffect(() => {
    if (searchTerm && !showSuggestionsScreen) {
      requestAnimationFrame(() => {
        virtualizer.scrollToOffset(0);
        if (scrollContainerRef.current) {
          scrollContainerRef.current.scrollTop = 0;
        }
      });
    }
  }, [searchTerm, showSuggestionsScreen]);

  useEffect(() => {
    if (inView && hasNextPage && !isFetchingNextPage && isSearchMode && searchTerm) {
      fetchNextPage();
    }
  }, [inView, hasNextPage, isFetchingNextPage, fetchNextPage, isSearchMode, searchTerm]);

  // 일정 데이터 로드
  const viewYear = selectedDate.getFullYear();
  const viewMonth = selectedDate.getMonth() + 1;

  const { data: schedules = [], isLoading: loading } = useQuery({
    queryKey: ['schedules', viewYear, viewMonth],
    queryFn: () => getSchedules(viewYear, viewMonth),
  });

  // 달력 표시용 일정 데이터
  const calendarYear = calendarViewDate.getFullYear();
  const calendarMonth = calendarViewDate.getMonth() + 1;
  const isSameMonth = viewYear === calendarYear && viewMonth === calendarMonth;

  const { data: calendarSchedules = [] } = useQuery({
    queryKey: ['schedules', calendarYear, calendarMonth],
    queryFn: () => getSchedules(calendarYear, calendarMonth),
    enabled: !isSameMonth,
  });

  // 생일 폭죽 효과
  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) => {
      if (!s.is_birthday) return false;
      const scheduleDate = s.date ? s.date.split('T')[0] : '';
      return scheduleDate === today;
    });

    if (hasBirthdayToday) {
      const birthdaySchedule = schedules.find((s) => {
        if (!s.is_birthday) return false;
        const scheduleDate = s.date ? s.date.split('T')[0] : '';
        return scheduleDate === 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) => {
      if (!s.is_debut && !s.is_anniversary) return false;
      const scheduleDate = s.date ? s.date.split('T')[0] : '';
      return scheduleDate === 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]);

  // 2017년 1월 이전으로 이동 불가
  const canGoPrevMonth = !(selectedDate.getFullYear() === MIN_YEAR && selectedDate.getMonth() === 0);

  // 월 변경
  const changeMonth = (delta) => {
    if (delta < 0 && !canGoPrevMonth) return;

    const newDate = new Date(selectedDate);
    newDate.setMonth(newDate.getMonth() + delta);

    const today = new Date();
    if (newDate.getFullYear() === today.getFullYear() && newDate.getMonth() === today.getMonth()) {
      newDate.setDate(today.getDate());
    } else {
      newDate.setDate(1);
    }

    setSelectedDate(newDate);
    setCalendarViewDate(newDate);
  };

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

  // 캘린더 열릴 때 배경 스크롤 방지
  useEffect(() => {
    const preventScroll = (e) => e.preventDefault();

    if (showCalendar) {
      document.addEventListener('touchmove', preventScroll, { passive: false });
    } else {
      document.removeEventListener('touchmove', preventScroll);
    }
    return () => {
      document.removeEventListener('touchmove', preventScroll);
    };
  }, [showCalendar]);

  // 검색 추천 드롭다운 외부 클릭 감지
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (searchContainerRef.current && !searchContainerRef.current.contains(event.target)) {
        setShowSuggestions(false);
        setSelectedSuggestionIndex(-1);
      }
    };

    if (showSuggestions) {
      document.addEventListener('mousedown', handleClickOutside);
      document.addEventListener('touchstart', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
      document.removeEventListener('touchstart', handleClickOutside);
    };
  }, [showSuggestions]);

  // 검색어 자동완성 API 호출
  useEffect(() => {
    if (!originalSearchQuery || originalSearchQuery.trim().length === 0) {
      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 (error) {
        console.error('추천 검색어 API 오류:', error);
        setSuggestions([]);
      }
    }, 200);

    return () => clearTimeout(timeoutId);
  }, [originalSearchQuery]);

  // 해당 달의 모든 날짜 배열
  const daysInMonth = useMemo(() => {
    const year = selectedDate.getFullYear();
    const month = selectedDate.getMonth();
    const lastDay = new Date(year, month + 1, 0).getDate();
    const days = [];
    for (let d = 1; d <= lastDay; d++) {
      days.push(new Date(year, month, d));
    }
    return days;
  }, [selectedDate]);

  // 선택된 날짜의 일정 (생일 우선) — 카테고리 필터 반영
  const selectedDateSchedules = useMemo(() => {
    const year = selectedDate.getFullYear();
    const month = String(selectedDate.getMonth() + 1).padStart(2, '0');
    const day = String(selectedDate.getDate()).padStart(2, '0');
    const dateStr = `${year}-${month}-${day}`;
    // 백엔드에서 이미 정렬된 상태로 전달됨 (특수 일정 우선)
    return schedules.filter((s) => {
      if (s.datePrecision === 'month') return false; // 날짜 미정은 별도 처리
      if (s.date.split('T')[0] !== dateStr) return false;
      return selectedCategories.length === 0 || selectedCategories.includes(s.category_id);
    });
  }, [schedules, selectedDate, selectedCategories]);

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

  // 해당 달 카테고리 목록 (카운트 포함, 날짜 점 필터용 calendarSchedules도 생성)
  const monthCategories = useMemo(() => {
    const map = new Map();
    schedules.forEach((s) => {
      if (!s.category_id) return;
      const existing = map.get(s.category_id);
      if (existing) existing.count += 1;
      else map.set(s.category_id, { id: s.category_id, name: s.category_name, color: s.category_color, count: 1 });
    });
    return Array.from(map.values()).sort((a, b) => {
      if (a.name === '기타') return 1;
      if (b.name === '기타') return -1;
      return b.count - a.count;
    });
  }, [schedules]);

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

  // 요일 이름
  const getDayName = (date) => ['일', '월', '화', '수', '목', '금', '토'][date.getDay()];

  // 오늘 여부
  const isToday = (date) => {
    const today = new Date();
    return (
      date.getDate() === today.getDate() &&
      date.getMonth() === today.getMonth() &&
      date.getFullYear() === today.getFullYear()
    );
  };

  // 선택된 날짜 여부
  const isSelected = (date) => {
    return (
      date.getDate() === selectedDate.getDate() &&
      date.getMonth() === selectedDate.getMonth() &&
      date.getFullYear() === selectedDate.getFullYear()
    );
  };

  // 날짜 선택 컨테이너 ref
  const dateScrollRef = useRef(null);

  // 선택된 날짜로 자동 스크롤
  useEffect(() => {
    if (!isSearchMode && dateScrollRef.current) {
      const selectedDay = selectedDate.getDate();
      const buttons = dateScrollRef.current.querySelectorAll('button');
      if (buttons[selectedDay - 1]) {
        setTimeout(() => {
          buttons[selectedDay - 1].scrollIntoView({
            behavior: 'smooth',
            inline: 'center',
            block: 'nearest',
          });
        }, 50);
      }
    }
  }, [selectedDate, isSearchMode]);

  // 검색 실행 핸들러
  const handleSearch = (term) => {
    if (term) {
      setSearchInput(term);
      setSearchTerm(term);
      setLastSearchTerm(term);
      setShowSuggestionsScreen(false);
    }
    setShowSuggestions(false);
    setSelectedSuggestionIndex(-1);
    searchInputRef.current?.blur();
  };

  return (
    <>
      {/* 툴바 (헤더 + 날짜 선택기) */}
      <div className="mobile-toolbar-schedule shadow-sm z-50">
        {isSearchMode ? (
          <div className="flex items-center gap-3 px-4 py-3 relative" ref={searchContainerRef}>
            <div className="flex-1 flex items-center gap-2 bg-gray-100 rounded-full px-4 py-2 min-w-0">
              <Search size={18} className="text-gray-400 flex-shrink-0" />
              <input
                ref={searchInputRef}
                type="text"
                inputMode="search"
                enterKeyHint="search"
                placeholder="일정 검색..."
                value={searchInput}
                onChange={(e) => {
                  setSearchInput(e.target.value);
                  setOriginalSearchQuery(e.target.value);
                  setShowSuggestions(true);
                  setShowSuggestionsScreen(true);
                  setSelectedSuggestionIndex(-1);
                }}
                onFocus={() => {
                  setShowSuggestions(true);
                  setShowSuggestionsScreen(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') {
                    e.preventDefault();
                    const term =
                      selectedSuggestionIndex >= 0 && suggestions[selectedSuggestionIndex]
                        ? suggestions[selectedSuggestionIndex]
                        : searchInput.trim();
                    handleSearch(term);
                  }
                }}
                className="flex-1 bg-transparent outline-none text-sm min-w-0 [&::-webkit-search-cancel-button]:hidden"
                autoFocus={!searchTerm}
              />
              {searchInput && (
                <button
                  onClick={() => {
                    setSearchInput('');
                    setOriginalSearchQuery('');
                    setShowSuggestions(true);
                    setShowSuggestionsScreen(true);
                    setSelectedSuggestionIndex(-1);
                  }}
                  className="flex-shrink-0"
                >
                  <X size={18} className="text-gray-400" />
                </button>
              )}
            </div>
            <button onClick={exitSearchMode} className="text-sm text-gray-500 flex-shrink-0">
              취소
            </button>
          </div>
        ) : (
          <div className="relative flex items-center justify-between px-4 py-3">
            {showCalendar ? (
              <>
                <div className="flex items-center gap-1">
                  <button
                    onClick={() => {
                      setShowCalendar(false);
                      setCalendarShowYearMonth(false);
                    }}
                    className="p-2 rounded-lg hover:bg-gray-100"
                  >
                    <Calendar size={20} className="text-primary" />
                  </button>
                  <button onClick={() => changeCalendarMonth(-1)} className="p-2">
                    <ChevronLeft size={20} />
                  </button>
                </div>

                <button
                  onClick={() => setCalendarShowYearMonth(!calendarShowYearMonth)}
                  className={`absolute left-1/2 -translate-x-1/2 font-bold transition-colors ${
                    calendarShowYearMonth ? 'text-primary' : ''
                  }`}
                >
                  {calendarViewDate.getFullYear()}년 {calendarViewDate.getMonth() + 1}월
                </button>

                <button
                  onClick={() => setCalendarShowYearMonth(!calendarShowYearMonth)}
                  className={`absolute transition-colors ${
                    calendarShowYearMonth ? 'text-primary' : ''
                  }`}
                  style={{ left: 'calc(50% + 52px)' }}
                >
                  <ChevronDown
                    size={16}
                    className={`transition-transform duration-200 ${
                      calendarShowYearMonth ? 'rotate-180' : ''
                    }`}
                  />
                </button>

                <div className="flex items-center gap-1">
                  <button onClick={() => changeCalendarMonth(1)} className="p-2">
                    <ChevronRight size={20} />
                  </button>
                  <button onClick={enterSearchMode} className="p-2">
                    <Search size={20} />
                  </button>
                </div>
              </>
            ) : (
              <>
                <div className="flex items-center gap-1">
                  <button
                    onClick={() => {
                      setCalendarViewDate(selectedDate);
                      setShowCalendar(true);
                    }}
                    className="p-2 rounded-lg hover:bg-gray-100"
                  >
                    <Calendar size={20} className="text-gray-600" />
                  </button>
                  <button
                    onClick={() => changeMonth(-1)}
                    disabled={!canGoPrevMonth}
                    className={`p-2 ${!canGoPrevMonth ? 'opacity-30' : ''}`}
                  >
                    <ChevronLeft size={20} />
                  </button>
                </div>
                <span className="font-bold">
                  {selectedDate.getFullYear()}년 {selectedDate.getMonth() + 1}월
                </span>
                <div className="flex items-center gap-1">
                  <button onClick={() => changeMonth(1)} className="p-2">
                    <ChevronRight size={20} />
                  </button>
                  <button onClick={enterSearchMode} className="p-2">
                    <Search size={20} />
                  </button>
                </div>
              </>
            )}
          </div>
        )}

        {/* 가로 스크롤 날짜 선택기 */}
        {!isSearchMode && (
          <div
            ref={dateScrollRef}
            className="flex overflow-x-auto scrollbar-hide px-2 py-2 gap-1"
            style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
          >
            {daysInMonth.map((date) => {
              const dayOfWeek = date.getDay();
              const year = date.getFullYear();
              const month = String(date.getMonth() + 1).padStart(2, '0');
              const day = String(date.getDate()).padStart(2, '0');
              const dateStr = `${year}-${month}-${day}`;

              const daySchedules = dotSchedules
                .filter((s) => s.date?.split('T')[0] === dateStr)
                .slice(0, 3);

              return (
                <button
                  key={date.getDate()}
                  onClick={() => {
                    setSelectedDate(date);
                    setCalendarViewDate(date);
                  }}
                  className={`flex flex-col items-center min-w-[44px] h-[64px] py-2 px-1 rounded-xl transition-all ${
                    isSelected(date) ? 'bg-primary text-white' : 'hover:bg-gray-100'
                  }`}
                >
                  <span
                    className={`text-[10px] font-medium ${
                      isSelected(date)
                        ? 'text-white/80'
                        : dayOfWeek === 0
                        ? 'text-red-400'
                        : dayOfWeek === 6
                        ? 'text-blue-400'
                        : 'text-gray-400'
                    }`}
                  >
                    {getDayName(date)}
                  </span>
                  <span
                    className={`text-sm font-semibold mt-0.5 ${
                      isSelected(date)
                        ? 'text-white'
                        : isToday(date)
                        ? 'text-primary'
                        : 'text-gray-700'
                    }`}
                  >
                    {date.getDate()}
                  </span>
                  <div className="flex gap-0.5 mt-1 h-1.5">
                    {!isSelected(date) &&
                      daySchedules.map((schedule, i) => {
                        const categoryInfo = getCategoryInfo(schedule);
                        return (
                          <div
                            key={i}
                            className="w-1 h-1 rounded-full"
                            style={{ backgroundColor: categoryInfo.color }}
                          />
                        );
                      })}
                  </div>
                </button>
              );
            })}
          </div>
        )}

      </div>

      {/* 달력 팝업 */}
      <AnimatePresence>
        {showCalendar && !isSearchMode && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            className="fixed left-0 right-0 bg-white shadow-lg z-50 border-b overflow-hidden"
            style={{ top: '56px' }}
          >
            <MobileCalendar
              selectedDate={selectedDate}
              schedules={isSameMonth ? schedules : calendarSchedules}
              hideHeader={true}
              externalViewDate={calendarViewDate}
              onViewDateChange={setCalendarViewDate}
              externalShowYearMonth={calendarShowYearMonth}
              onShowYearMonthChange={setCalendarShowYearMonth}
              onSelectDate={(date) => {
                setSelectedDate(date);
                setCalendarViewDate(date);
                setCalendarShowYearMonth(false);
                setShowCalendar(false);
              }}
            />
          </motion.div>
        )}
      </AnimatePresence>

      {/* 캘린더 배경 오버레이 */}
      <AnimatePresence>
        {showCalendar && !isSearchMode && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            onClick={() => setShowCalendar(false)}
            className="fixed inset-0 bg-black/40 z-40"
            style={{ top: 0 }}
          />
        )}
      </AnimatePresence>

      {/* 컨텐츠 영역 */}
      <div
        className="mobile-content"
        ref={isSearchMode && searchTerm && !showSuggestionsScreen ? scrollContainerRef : contentRef}
      >
        <div className={`px-4 pb-4 min-h-full flex flex-col ${isSearchMode && showSuggestionsScreen ? 'pt-0' : 'pt-4'}`}>
          {isSearchMode ? (
            showSuggestionsScreen ? (
              // 추천 검색어 화면
              <div className="space-y-0">
                {suggestions.length === 0 ? (
                  <div className="text-center py-8 text-gray-400">검색어를 입력하세요</div>
                ) : (
                  suggestions.map((suggestion, index) => (
                    <button
                      key={suggestion}
                      onClick={() => handleSearch(suggestion)}
                      className={`w-full px-0 py-3.5 text-left flex items-center gap-4 border-b border-gray-100 active:bg-gray-50 ${
                        index === selectedSuggestionIndex ? 'bg-primary/5' : ''
                      }`}
                    >
                      <Search size={18} className="text-gray-400 shrink-0" />
                      <span className="text-[15px] text-gray-700 flex-1">{suggestion}</span>
                    </button>
                  ))
                )}
              </div>
            ) : !searchTerm ? (
              <div className="text-center py-8 text-gray-400">검색어를 입력하세요</div>
            ) : searchLoading ? (
              <div className="flex-1 flex items-center justify-center">
                <div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin" />
              </div>
            ) : searchResults.length === 0 ? (
              <div className="flex-1 flex flex-col items-center justify-center">
                <div className="w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-3">
                  <svg className="w-10 h-10 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-base font-medium mb-1">검색 결과가 없습니다</p>
                <p className="text-gray-300 text-sm">'<span className="text-gray-400">{searchTerm}</span>'에 대한 일정을 찾을 수 없습니다</p>
              </div>
            ) : (
              <>
                <div
                  style={{
                    height: `${virtualizer.getTotalSize()}px`,
                    width: '100%',
                    position: 'relative',
                  }}
                >
                  {virtualizer.getVirtualItems().map((virtualItem) => {
                    const schedule = searchResults[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 < searchResults.length - 1 ? 'pb-3' : ''}>
                          <MobileScheduleSearchCard
                            schedule={schedule}
                            onClick={() => navigate(`/schedule/${schedule.id}`)}
                          />
                        </div>
                      </div>
                    );
                  })}
                </div>
                <div ref={loadMoreRef} className="py-2">
                  {isFetchingNextPage && (
                    <div className="flex justify-center">
                      <div className="w-6 h-6 border-2 border-primary border-t-transparent rounded-full animate-spin" />
                    </div>
                  )}
                </div>
              </>
            )
          ) : (
            <>
              {/* 카테고리 필터 칩 (스크롤 방향 감지 자동 숨김) */}
              {monthCategories.length > 0 && (
                <div className="sticky top-0 z-20 bg-white -mx-4 px-4 -mt-4 pt-4 pb-3">
                  <div
                    className="flex overflow-x-auto scrollbar-hide gap-1.5"
                    style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
                  >
                    <button
                      onClick={() => setSelectedCategories([])}
                      className={`flex-shrink-0 px-3 py-1.5 rounded-full text-xs font-semibold transition-colors ${
                        selectedCategories.length === 0 ? 'bg-primary text-white' : 'bg-gray-100 text-gray-500'
                      }`}
                    >
                      전체
                    </button>
                    {monthCategories.map((cat) => {
                      const active = selectedCategories.includes(cat.id);
                      return (
                        <button
                          key={cat.id}
                          onClick={() => toggleCategory(cat.id)}
                          className={`flex-shrink-0 inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold transition-colors ${
                            active ? 'text-white' : 'bg-gray-100 text-gray-600'
                          }`}
                          style={active ? { backgroundColor: cat.color } : undefined}
                        >
                          <span className="w-2 h-2 rounded-full" style={{ backgroundColor: active ? '#fff' : cat.color }} />
                          {cat.name}
                        </button>
                      );
                    })}
                  </div>
                </div>
              )}

              {loading ? (
            <div className="flex-1 flex items-center justify-center">
              <div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin" />
            </div>
          ) : selectedDateSchedules.length === 0 && undatedSchedules.length === 0 ? (
            <div className="flex-1 flex flex-col items-center justify-center">
              <div className="w-20 h-20 bg-gray-100 rounded-full flex items-center justify-center mb-3">
                <svg className="w-10 h-10 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-base font-medium">
                {selectedDate.getMonth() + 1}월 {selectedDate.getDate()}일 일정이 없습니다
              </p>
            </div>
          ) : (
            <div className="space-y-3">
              {selectedDateSchedules.map((schedule, index) => {
                const isBirthday = schedule.is_birthday || String(schedule.id).startsWith('birthday-');
                const isDebut = schedule.is_debut || schedule.is_anniversary;

                if (isBirthday) {
                  return (
                    <MobileBirthdayCard
                      key={schedule.id}
                      schedule={schedule}
                      delay={index * 0.05}
                      onClick={handleCardClick}
                    />
                  );
                }

                if (isDebut) {
                  return (
                    <MobileDebutCard
                      key={schedule.id}
                      schedule={schedule}
                      delay={index * 0.05}
                    />
                  );
                }

                return (
                  <MobileScheduleListCard
                    key={schedule.id}
                    schedule={schedule}
                    delay={index * 0.05}
                    onClick={handleCardClick}
                  />
                );
              })}

              {/* 날짜 미정 일정 — 우선순위 낮춰 기존 일정 아래 배치 */}
              {undatedSchedules.length > 0 && selectedDateSchedules.length > 0 && (
                <div className="flex items-center gap-3 pt-1">
                  <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) => (
                <MobileUndatedScheduleListCard
                  key={`undated-${schedule.id}`}
                  schedule={schedule}
                  delay={(selectedDateSchedules.length + index) * 0.05}
                  onClick={handleCardClick}
                />
              ))}
            </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}
      />
    </>
  );
}

export default MobileSchedule;
