import { useState, useMemo, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { ChevronLeft, ChevronRight, Search } from 'lucide-react';
import { useIsMobile, useScheduleData, useCategories, useCalendar } from '@/hooks';
import { useScheduleStore } from '@/stores';
import { Loading, ScheduleCard } from '@/components';
import { cn, getTodayKST, decodeHtmlEntities } from '@/utils';
import { WEEKDAYS, MIN_YEAR } from '@/constants';

/**
 * PC 캘린더 컴포넌트
 */
function PCCalendar({ selectedDate, schedules, categories, onSelectDate, onMonthChange }) {
  const { days, year, month, canGoPrev } = useCalendar(selectedDate);

  // 날짜별 일정 맵
  const scheduleDates = useMemo(() => {
    const dateMap = {};
    schedules?.forEach((schedule) => {
      const date = schedule.date?.split('T')[0];
      if (!dateMap[date]) dateMap[date] = [];
      const cat = categories?.find((c) => c.id === (schedule.category_id || schedule.category?.id));
      dateMap[date].push(cat?.color || '#6b7280');
    });
    return dateMap;
  }, [schedules, categories]);

  const isToday = (date) => {
    const today = new Date();
    return (
      date.getDate() === today.getDate() &&
      date.getMonth() === today.getMonth() &&
      date.getFullYear() === today.getFullYear()
    );
  };

  const isSelected = (date) => {
    const sel = new Date(selectedDate);
    return (
      date.getDate() === sel.getDate() &&
      date.getMonth() === sel.getMonth() &&
      date.getFullYear() === sel.getFullYear()
    );
  };

  const formatDateStr = (date) => {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
  };

  return (
    <div className="bg-white rounded-2xl shadow-sm p-6">
      {/* 헤더 */}
      <div className="flex items-center justify-between mb-6">
        <button
          onClick={() => canGoPrev && onMonthChange(-1)}
          disabled={!canGoPrev}
          className={cn('p-2 rounded-lg hover:bg-gray-100', !canGoPrev && 'opacity-30 cursor-not-allowed')}
        >
          <ChevronLeft size={20} />
        </button>
        <h2 className="text-lg font-bold">
          {year}년 {month + 1}월
        </h2>
        <button onClick={() => onMonthChange(1)} className="p-2 rounded-lg hover:bg-gray-100">
          <ChevronRight size={20} />
        </button>
      </div>

      {/* 요일 헤더 */}
      <div className="grid grid-cols-7 gap-1 mb-2">
        {WEEKDAYS.map((day, i) => (
          <div
            key={day}
            className={cn(
              'text-center text-xs font-medium py-2',
              i === 0 ? 'text-red-400' : i === 6 ? 'text-blue-400' : 'text-gray-500'
            )}
          >
            {day}
          </div>
        ))}
      </div>

      {/* 날짜 그리드 */}
      <div className="grid grid-cols-7 gap-1">
        {days.map((item, index) => {
          const dayOfWeek = index % 7;
          const dateStr = formatDateStr(item.date);
          const colors = scheduleDates[dateStr] || [];

          return (
            <button
              key={index}
              onClick={() => onSelectDate(item.date)}
              className="flex flex-col items-center py-2"
            >
              <span
                className={cn(
                  'w-9 h-9 flex items-center justify-center text-sm font-medium rounded-full transition-all',
                  !item.isCurrentMonth
                    ? 'text-gray-300'
                    : isSelected(item.date)
                    ? 'bg-primary text-white font-bold'
                    : isToday(item.date)
                    ? 'text-primary font-bold'
                    : dayOfWeek === 0
                    ? 'text-red-500 hover:bg-red-50'
                    : dayOfWeek === 6
                    ? 'text-blue-500 hover:bg-blue-50'
                    : 'text-gray-700 hover:bg-gray-100'
                )}
              >
                {item.day}
              </span>
              {/* 일정 점 */}
              {!isSelected(item.date) && colors.length > 0 && (
                <div className="flex gap-0.5 mt-1 h-1.5">
                  {colors.slice(0, 3).map((color, i) => (
                    <div
                      key={i}
                      className="w-1 h-1 rounded-full"
                      style={{ backgroundColor: color }}
                    />
                  ))}
                </div>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/**
 * 스케줄 페이지 (PC/Mobile 통합)
 */
function Schedule() {
  const navigate = useNavigate();
  const isMobile = useIsMobile();

  // Zustand store
  const { currentDate, setCurrentDate, selectedDate, setSelectedDate } = useScheduleStore();

  // 초기값 설정
  const today = getTodayKST();
  const actualSelectedDate = selectedDate || today;

  // 데이터 로드
  const year = currentDate.getFullYear();
  const month = currentDate.getMonth() + 1;
  const { data: schedules, isLoading: schedulesLoading } = useScheduleData(year, month);
  const { data: categories } = useCategories();

  // 선택된 날짜의 일정
  const selectedDateSchedules = useMemo(() => {
    if (!schedules) return [];
    const sel = new Date(actualSelectedDate);
    const dateStr = `${sel.getFullYear()}-${String(sel.getMonth() + 1).padStart(2, '0')}-${String(sel.getDate()).padStart(2, '0')}`;
    return schedules
      .filter((s) => s.date?.split('T')[0] === dateStr)
      .sort((a, b) => {
        const aIsBirthday = a.is_birthday || String(a.id).startsWith('birthday-');
        const bIsBirthday = b.is_birthday || String(b.id).startsWith('birthday-');
        if (aIsBirthday && !bIsBirthday) return -1;
        if (!aIsBirthday && bIsBirthday) return 1;
        return 0;
      });
  }, [schedules, actualSelectedDate]);

  // 월 변경
  const changeMonth = (delta) => {
    const newDate = new Date(currentDate);
    newDate.setMonth(newDate.getMonth() + delta);

    // 2017년 1월 이전으로 이동 불가
    if (newDate.getFullYear() < MIN_YEAR || (newDate.getFullYear() === MIN_YEAR && newDate.getMonth() < 0)) {
      return;
    }

    setCurrentDate(newDate);

    // 이번 달이면 오늘 날짜, 다른 달이면 1일 선택
    const now = new Date();
    if (newDate.getFullYear() === now.getFullYear() && newDate.getMonth() === now.getMonth()) {
      setSelectedDate(getTodayKST());
    } else {
      const firstDay = `${newDate.getFullYear()}-${String(newDate.getMonth() + 1).padStart(2, '0')}-01`;
      setSelectedDate(firstDay);
    }
  };

  // 날짜 선택
  const handleSelectDate = (date) => {
    const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    setSelectedDate(dateStr);

    // 월이 다르면 currentDate도 변경
    if (date.getMonth() !== currentDate.getMonth() || date.getFullYear() !== currentDate.getFullYear()) {
      setCurrentDate(date);
    }
  };

  // PC 레이아웃
  if (!isMobile) {
    return (
      <div className="flex-1 flex overflow-hidden">
        {/* 좌측: 캘린더 */}
        <div className="w-80 flex-shrink-0 p-6 border-r overflow-y-auto">
          <PCCalendar
            selectedDate={actualSelectedDate}
            schedules={schedules}
            categories={categories}
            onSelectDate={handleSelectDate}
            onMonthChange={changeMonth}
          />
        </div>

        {/* 우측: 일정 목록 */}
        <div className="flex-1 flex flex-col overflow-hidden">
          {/* 헤더 */}
          <div className="flex items-center justify-between px-6 py-4 border-b">
            <div className="flex items-center gap-3">
              <h2 className="text-lg font-bold">
                {new Date(actualSelectedDate).getMonth() + 1}월{' '}
                {new Date(actualSelectedDate).getDate()}일{' '}
                {WEEKDAYS[new Date(actualSelectedDate).getDay()]}요일
              </h2>
              <span className="text-sm text-gray-500">
                {selectedDateSchedules.length}개의 일정
              </span>
            </div>
            <button className="p-2 hover:bg-gray-100 rounded-lg">
              <Search size={20} className="text-gray-500" />
            </button>
          </div>

          {/* 일정 목록 */}
          <div className="flex-1 overflow-y-auto p-6">
            {schedulesLoading ? (
              <div className="flex justify-center py-12">
                <Loading text="일정 로딩 중..." />
              </div>
            ) : selectedDateSchedules.length === 0 ? (
              <div className="text-center py-12 text-gray-400">
                {new Date(actualSelectedDate).getMonth() + 1}월{' '}
                {new Date(actualSelectedDate).getDate()}일 일정이 없습니다
              </div>
            ) : (
              <div className="space-y-4">
                {selectedDateSchedules.map((schedule) => (
                  <ScheduleCard
                    key={schedule.id}
                    schedule={schedule}
                    variant="public"
                    showDate={false}
                    onClick={() => navigate(`/schedule/${schedule.id}`)}
                  />
                ))}
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }

  // 모바일 레이아웃 (간소화된 버전)
  return (
    <>
      {/* 모바일 툴바 */}
      <div className="mobile-toolbar-schedule shadow-sm z-50">
        <div className="flex items-center justify-between px-4 py-3">
          <button
            onClick={() => changeMonth(-1)}
            className="p-2"
            disabled={currentDate.getFullYear() === MIN_YEAR && currentDate.getMonth() === 0}
          >
            <ChevronLeft size={20} />
          </button>
          <span className="font-bold">
            {currentDate.getFullYear()}년 {currentDate.getMonth() + 1}월
          </span>
          <div className="flex items-center gap-1">
            <button onClick={() => changeMonth(1)} className="p-2">
              <ChevronRight size={20} />
            </button>
            <button className="p-2">
              <Search size={20} />
            </button>
          </div>
        </div>
      </div>

      {/* 모바일 컨텐츠 */}
      <div className="mobile-content">
        <div className="px-4 py-4">
          {schedulesLoading ? (
            <div className="flex justify-center py-8">
              <Loading size="sm" />
            </div>
          ) : selectedDateSchedules.length === 0 ? (
            <div className="text-center py-8 text-gray-400">
              {new Date(actualSelectedDate).getMonth() + 1}월{' '}
              {new Date(actualSelectedDate).getDate()}일 일정이 없습니다
            </div>
          ) : (
            <div className="space-y-3">
              {selectedDateSchedules.map((schedule) => (
                <ScheduleCard
                  key={schedule.id}
                  schedule={schedule}
                  variant="public"
                  showDate={false}
                  onClick={() => navigate(`/schedule/${schedule.id}`)}
                />
              ))}
            </div>
          )}
        </div>
      </div>
    </>
  );
}

export default Schedule;
