/**
 * Календарь занятий для Dashboard ментора
 * Реализация “с нуля” на Material UI (M3) в iOS-стиле:
 * - сетка месяца 7×6 с тонкими разделителями
 * - число дня в правом верхнем углу
 * - занятия плашками внутри ячейки (лимит + “+ ещё N”)
 * - без внутреннего скролла
 */

'use client';

import React, { useMemo, useState, useEffect, useCallback } from 'react';
import {
  addDays,
  addMonths,
  endOfMonth,
  format,
  isSameDay,
  isSameMonth,
  startOfDay,
  startOfMonth,
  startOfWeek,
  subMonths,
} from 'date-fns';
import { ru } from 'date-fns/locale';
import { Box, IconButton, Typography } from '@mui/material';
import { ChevronLeft, ChevronRight } from '@mui/icons-material';
import { parseISOToUserTimezone } from '@/utils/timezone';
import { LoadingSpinner } from '@/components/common/LoadingSpinner';

interface Lesson {
  id: string;
  title: string;
  start_time: string;
  end_time: string;
  status?: 'scheduled' | 'in_progress' | 'completed' | 'cancelled';
  client?: {
    id: string;
    name?: string;
    first_name?: string;
    last_name?: string;
  };
}

interface LessonsCalendarProps {
  lessons: Lesson[];
  onSelectEvent?: (lesson: Lesson) => void;
  onSelectSlot?: (date: Date) => void;
  onMonthChange?: (start: Date, end: Date) => void;
  selectedDate?: Date;
  userTimezone?: string;
  /** Идёт загрузка данных (запрос нового месяца) — блокирует навигацию */
  loading?: boolean;
}

export const LessonsCalendar: React.FC<LessonsCalendarProps> = ({
  lessons,
  onSelectEvent,
  onSelectSlot,
  onMonthChange,
  selectedDate,
  userTimezone,
  loading = false,
}) => {
  const safeSelectedDate = useMemo(() => {
    if (selectedDate && !Number.isNaN(selectedDate.getTime())) return startOfDay(selectedDate);
    return startOfDay(new Date());
  }, [selectedDate]);

  const [currentMonth, setCurrentMonth] = useState<Date>(() => startOfMonth(safeSelectedDate));
  const [slideDir, setSlideDir] = useState<'prev' | 'next' | 'today' | null>(null);

  useEffect(() => {
    setCurrentMonth(startOfMonth(safeSelectedDate));
  }, [safeSelectedDate]);

  useEffect(() => {
    if (!slideDir) return;
    const t = window.setTimeout(() => setSlideDir(null), 240);
    return () => window.clearTimeout(t);
  }, [slideDir]);

  useEffect(() => {
    const start = startOfMonth(currentMonth);
    const end = endOfMonth(currentMonth);
    onMonthChange?.(start, end);
  }, [currentMonth, onMonthChange]);

  // Группируем занятия по дате (ключ YYYY-MM-DD) с учётом timezone пользователя
  const lessonsByDay = useMemo(() => {
    const map = new Map<string, Lesson[]>();
    if (!lessons || lessons.length === 0) return map;

    lessons.forEach((lesson) => {
      try {
        // Используем timezone пользователя для определения дня
        const parsed = parseISOToUserTimezone(lesson.start_time, userTimezone);
        const key = parsed.date; // уже в формате 'yyyy-MM-dd'
        const existing = map.get(key) || [];
        existing.push(lesson);
        map.set(key, existing);
      } catch {
        /* ignore invalid date */
      }
    });

    // Сортируем занятия внутри каждого дня по времени
    map.forEach((dayLessons, key) => {
      dayLessons.sort((a, b) => 
        new Date(a.start_time).getTime() - new Date(b.start_time).getTime()
      );
      map.set(key, dayLessons);
    });

    return map;
  }, [lessons, userTimezone]);

  const monthLabel = useMemo(() => {
    const label = format(currentMonth, 'LLLL yyyy', { locale: ru });
    return label.charAt(0).toUpperCase() + label.slice(1);
  }, [currentMonth]);

  const weekdayLabels = useMemo(() => {
    const start = startOfWeek(new Date(), { weekStartsOn: 1, locale: ru });
    return Array.from({ length: 7 }).map((_, idx) => {
      const d = addDays(start, idx);
      return format(d, 'EE', { locale: ru }).substring(0, 2).toUpperCase();
    });
  }, []);

  const daysGrid = useMemo(() => {
    const monthStart = startOfMonth(currentMonth);
    const gridStart = startOfWeek(monthStart, { weekStartsOn: 1, locale: ru });
    return Array.from({ length: 42 }).map((_, i) => addDays(gridStart, i));
  }, [currentMonth]);

  const handleDayClick = useCallback(
    (day: Date) => {
      onSelectSlot?.(startOfDay(day));
    },
    [onSelectSlot]
  );

  const handleLessonClick = useCallback(
    (day: Date, lesson: Lesson, e: React.MouseEvent) => {
      e.stopPropagation();
      onSelectSlot?.(startOfDay(day));
      onSelectEvent?.(lesson);
    },
    [onSelectEvent, onSelectSlot]
  );

  const goToday = useCallback(() => {
    const today = startOfDay(new Date());
    const curr = startOfMonth(currentMonth).getTime();
    const target = startOfMonth(today).getTime();
    if (target < curr) setSlideDir('prev');
    else if (target > curr) setSlideDir('next');
    else setSlideDir('today');
    setCurrentMonth(startOfMonth(today));
    onSelectSlot?.(today);
  }, [currentMonth, onSelectSlot]);

  const goPrevMonth = useCallback(() => {
    setSlideDir('prev');
    setCurrentMonth((m) => subMonths(m, 1));
  }, []);

  const goNextMonth = useCallback(() => {
    setSlideDir('next');
    setCurrentMonth((m) => addMonths(m, 1));
  }, []);

  return (
    <Box sx={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* Header как в iOS */}
      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1.5 }}>
        <Typography sx={{ fontSize: 18, fontWeight: 700, color: 'var(--md-sys-color-on-surface)' }}>
          {monthLabel}
        </Typography>
        <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
          <IconButton
            onClick={loading ? undefined : goPrevMonth}
            size="small"
            disabled={loading}
            sx={{
              borderRadius: 2,
              border: '1px solid var(--md-sys-color-outline-variant)',
              backgroundColor: 'var(--md-sys-color-surface)',
              opacity: loading ? 0.6 : 1,
              pointerEvents: loading ? 'none' : 'auto',
            }}
          >
            <ChevronLeft fontSize="small" />
          </IconButton>
          <IconButton
            onClick={loading ? undefined : goToday}
            size="small"
            disabled={loading}
            sx={{
              borderRadius: 2,
              px: 1.25,
              border: '1px solid var(--md-sys-color-outline-variant)',
              backgroundColor: 'var(--md-sys-color-surface)',
              opacity: loading ? 0.6 : 1,
              pointerEvents: loading ? 'none' : 'auto',
            }}
          >
            <Typography sx={{ fontSize: 12, fontWeight: 700, color: 'var(--md-sys-color-on-surface)' }}>
              Сегодня
            </Typography>
          </IconButton>
          <IconButton
            onClick={loading ? undefined : goNextMonth}
            size="small"
            disabled={loading}
            sx={{
              borderRadius: 2,
              border: '1px solid var(--md-sys-color-outline-variant)',
              backgroundColor: 'var(--md-sys-color-surface)',
              opacity: loading ? 0.6 : 1,
              pointerEvents: loading ? 'none' : 'auto',
            }}
          >
            <ChevronRight fontSize="small" />
          </IconButton>
          {loading && (
            <Box sx={{ ml: 0.5, display: 'flex', alignItems: 'center' }}>
              <LoadingSpinner size="small" inline />
            </Box>
          )}
        </Box>
      </Box>

      {/* Grid */}
      <Box
        sx={{
          flex: 1,
          minHeight: 0,
          borderRadius: 2,
          border: '1px solid var(--md-sys-color-outline-variant)',
          backgroundColor: 'var(--md-sys-color-surface)',
          overflow: 'hidden',
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        {/* Weekdays */}
        <Box
          sx={{
            display: 'grid',
            gridTemplateColumns: 'repeat(7, 1fr)',
            borderBottom: '1px solid var(--md-sys-color-outline-variant)',
          }}
        >
          {weekdayLabels.map((label, idx) => (
            <Box
              key={`${label}-${idx}`}
              sx={{
                py: 1,
                textAlign: 'center',
                fontSize: 11,
                fontWeight: 800,
                letterSpacing: '0.04em',
                color: 'var(--md-sys-color-on-surface-variant)',
              }}
            >
              {label}
            </Box>
          ))}
        </Box>

        {/* Days */}
        <Box
          sx={{
            flex: 1,
            minHeight: 0,
            display: 'grid',
            gridTemplateColumns: 'repeat(7, 1fr)',
            gridTemplateRows: 'repeat(6, minmax(110px, 1fr))',
            // слайдер при переключении месяцев
            '@keyframes iosCalSlideNext': {
              from: { transform: 'translateX(16px)', opacity: 0.2 },
              to: { transform: 'translateX(0)', opacity: 1 },
            },
            '@keyframes iosCalSlidePrev': {
              from: { transform: 'translateX(-16px)', opacity: 0.2 },
              to: { transform: 'translateX(0)', opacity: 1 },
            },
            '@keyframes iosCalFade': {
              from: { opacity: 0.4 },
              to: { opacity: 1 },
            },
            animation:
              slideDir === 'next'
                ? 'iosCalSlideNext 220ms ease'
                : slideDir === 'prev'
                  ? 'iosCalSlidePrev 220ms ease'
                  : slideDir === 'today'
                    ? 'iosCalFade 180ms ease'
                    : 'none',
          }}
          key={`${currentMonth.getFullYear()}-${currentMonth.getMonth()}`}
        >
          {daysGrid.map((day) => {
            const dayKey = format(startOfDay(day), 'yyyy-MM-dd');
            const dayLessons = lessonsByDay.get(dayKey) || [];

            const inMonth = isSameMonth(day, currentMonth);
            const isToday = isSameDay(day, new Date());
            const isSelected = isSameDay(startOfDay(day), safeSelectedDate);

            const bg = !inMonth
              ? 'var(--md-sys-color-surface-variant)'
              : isSelected
                ? 'rgba(116, 68, 253, 0.10)'
                : 'var(--md-sys-color-surface)';

            return (
              <Box
                key={dayKey}
                role="button"
                tabIndex={0}
                onClick={() => handleDayClick(day)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter' || e.key === ' ') handleDayClick(day);
                }}
                sx={{
                  position: 'relative',
                  minHeight: '110px',
                  px: 1,
                  pt: 1,
                  pb: 0.75,
                  borderRight: '1px solid var(--md-sys-color-outline-variant)',
                  borderBottom: '1px solid var(--md-sys-color-outline-variant)',
                  backgroundColor: bg,
                  overflow: 'hidden',
                  cursor: 'pointer',
                  opacity: inMonth ? 1 : 0.55,
                  transition: 'background-color 120ms ease',
                  '&:hover': {
                    backgroundColor: isSelected ? 'rgba(116, 68, 253, 0.13)' : 'rgba(116, 68, 253, 0.06)',
                  },
                }}
              >
                {/* Day number */}
                <Box
                  sx={{
                    position: 'absolute',
                    top: 8,
                    right: 10,
                    fontSize: 12,
                    fontWeight: 800,
                    color: isToday ? 'var(--md-sys-color-primary)' : 'var(--md-sys-color-on-surface-variant)',
                    lineHeight: 1,
                  }}
                >
                  {format(day, 'd')}
                </Box>

                {/* Lessons (no scroll) */}
                <Box
                  sx={{
                    mt: 2.5,
                    display: 'flex',
                    flexDirection: 'column',
                    gap: 0.5,
                    height: 'calc(100% - 28px)',
                    overflow: 'hidden',
                  }}
                >
                  {dayLessons.slice(0, 2).map((lesson) => {
                    const timeStr = (() => {
                      try {
                        // Используем timezone пользователя для отображения времени
                        const parsed = parseISOToUserTimezone(lesson.start_time, userTimezone);
                        return parsed.time;
                      } catch {
                        return '';
                      }
                    })();
                    const baseTitle = lesson.client?.first_name || lesson.client?.name || lesson.title;
                    const title =
                      baseTitle && baseTitle.length > 18 ? baseTitle.substring(0, 16) + '…' : baseTitle;

                    return (
                      <Box
                        key={lesson.id}
                        onClick={(e) => handleLessonClick(day, lesson, e)}
                        sx={{
                          px: 0.75,
                          py: 0.25,
                          borderRadius: 1.25,
                          backgroundColor: 'rgba(116, 68, 253, 0.14)',
                          color: 'var(--md-sys-color-on-surface)',
                          fontSize: 11,
                          fontWeight: 700,
                          whiteSpace: 'nowrap',
                          overflow: 'hidden',
                          textOverflow: 'ellipsis',
                          border: '1px solid rgba(116, 68, 253, 0.20)',
                        }}
                      >
                        {timeStr ? `${timeStr} ${title}` : title}
                      </Box>
                    );
                  })}

                  {dayLessons.length > 2 && (
                    <Box sx={{ mt: 0.25, fontSize: 11, fontWeight: 800, color: 'var(--md-sys-color-primary)' }}>
                      + ещё {dayLessons.length - 2}
                    </Box>
                  )}
                </Box>
              </Box>
            );
          })}
        </Box>
      </Box>
    </Box>
  );
};
