'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import {
  startOfDay,
  format,
  addDays,
  subDays,
  subMonths,
  addMonths,
  startOfMonth,
  endOfMonth,
  differenceInMinutes,
} from 'date-fns';
import { ru } from 'date-fns/locale';
import { Calendar } from '@/components/calendar/calendar';
import { CheckLesson } from '@/components/checklesson/checklesson';
import { getLessonsCalendar, getLesson, createLesson, updateLesson, deleteLesson } from '@/api/schedule';
import { getStudents } from '@/api/students';
import { useAuth } from '@/contexts/AuthContext';
import { createDateTimeInUserTimezone, parseISOToUserTimezone } from '@/utils/timezone';
import { useSelectedChild } from '@/contexts/SelectedChildContext';
import { getSubjects, getMentorSubjects } from '@/api/subjects';
import { loadComponent } from '@/lib/material-components';
import { LoadingSpinner } from '@/components/common/LoadingSpinner';
import { ErrorDisplay } from '@/components/common/ErrorDisplay';
import { getErrorMessage } from '@/lib/error-utils';
import type { CalendarLesson } from '@/components/calendar/calendar';
import type { CheckLessonFormData, CheckLessonProps } from '@/components/checklesson/checklesson';
import type { LessonPreview } from '@/api/dashboard';
import type { Student } from '@/api/students';
import type { Subject, MentorSubject } from '@/api/subjects';

export default function SchedulePage() {
  const { user } = useAuth();
  const { selectedChild } = useSelectedChild();
  const isMentor = user?.role === 'mentor';
  const [selectedDate, setSelectedDate] = useState<Date>(startOfDay(new Date()));
  const [displayDate, setDisplayDate] = useState<Date>(startOfDay(new Date()));
  const [visibleMonth, setVisibleMonth] = useState<Date>(() => startOfMonth(new Date()));
  const [lessons, setLessons] = useState<CalendarLesson[]>([]);
  const [lessonsLoading, setLessonsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const formDataLoadedRef = useRef(false);
  const hasLoadedLessonsOnceRef = useRef(false);
  
  // Форма
  const [isFormVisible, setIsFormVisible] = useState(false);
  const [isEditingMode, setIsEditingMode] = useState(false);
  const [formLoading, setFormLoading] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);
  const [formData, setFormData] = useState<CheckLessonFormData>({
    client: '',
    title: '',
    description: '',
    start_date: format(selectedDate, 'yyyy-MM-dd'),
    start_time: '14:00',
    duration: 60,
    price: undefined,
    is_recurring: false,
  });
  const [selectedSubjectId, setSelectedSubjectId] = useState<number | null>(null);
  const [selectedMentorSubjectId, setSelectedMentorSubjectId] = useState<number | null>(null);
  const [editingLessonId, setEditingLessonId] = useState<string | null>(null);
  const [editingLessonStatus, setEditingLessonStatus] = useState<string | null>(null);

  // Компоненты Material Web
  const [buttonComponentsLoaded, setButtonComponentsLoaded] = useState(false);
  const [formComponentsLoaded, setFormComponentsLoaded] = useState(false);
  
  // Данные для формы
  const [students, setStudents] = useState<Student[]>([]);
  const [subjects, setSubjects] = useState<Subject[]>([]);
  const [mentorSubjects, setMentorSubjects] = useState<MentorSubject[]>([]);
  const [lessonEditLoading, setLessonEditLoading] = useState(false);

  useEffect(() => {
    Promise.all([
      loadComponent('elevated-card'),
      loadComponent('filled-button'),
      loadComponent('icon'),
    ]).then(() => {
      setButtonComponentsLoaded(true);
    });
    
    Promise.all([
      loadComponent('filled-button'),
      loadComponent('outlined-button'),
      loadComponent('text-field'),
      loadComponent('select'),
      loadComponent('switch'),
    ]).then(() => {
      setFormComponentsLoaded(true);
    });
  }, []);

  useEffect(() => {
    if (!isFormVisible || formDataLoadedRef.current) return;
    (async () => {
      try {
        const [studentsResp, subjectsResp, mentorSubjectsResp] = await Promise.all([
          getStudents({ page: 1, page_size: 200 }),
          getSubjects(),
          getMentorSubjects(),
        ]);
        setStudents(studentsResp.results || []);
        setSubjects(subjectsResp || []);
        setMentorSubjects(mentorSubjectsResp || []);
        formDataLoadedRef.current = true;
      } catch (err) {
        console.error('Error loading form data:', err);
      }
    })();
  }, [isFormVisible]);

  const loadLessons = useCallback(
    async (merge?: boolean) => {
      const start = startOfMonth(subMonths(visibleMonth, 1));
      const end = endOfMonth(addMonths(visibleMonth, 1));
      const doMerge = merge ?? hasLoadedLessonsOnceRef.current;
      const isInitial = !hasLoadedLessonsOnceRef.current && !doMerge;
      try {
        setLessonsLoading(true);
        setError(null);
        const { lessons: lessonsData } = await getLessonsCalendar({
          start_date: format(start, 'yyyy-MM-dd'),
          end_date: format(end, 'yyyy-MM-dd'),
          ...(selectedChild?.id && { child_id: selectedChild.id }),
        });
        const mappedLessons: CalendarLesson[] = (lessonsData || []).map((lesson: any) => ({
          id: lesson.id,
          title: lesson.title,
          start_time: lesson.start_time,
          end_time: lesson.end_time,
          status: lesson.status,
          client: lesson.client?.id,
          client_name: lesson.client_name ?? (lesson.client?.user
            ? `${lesson.client.user.first_name || ''} ${lesson.client.user.last_name || ''}`.trim()
            : undefined),
          mentor_name: lesson.mentor_name ?? (lesson.mentor?.first_name || lesson.mentor?.last_name
            ? `${lesson.mentor?.first_name || ''} ${lesson.mentor?.last_name || ''}`.trim()
            : undefined),
          subject: lesson.subject ?? lesson.subject_name ?? '',
        }));
        if (doMerge) {
          setLessons((prev) => {
            const startStr = format(start, 'yyyy-MM-dd');
            const endStr = format(end, 'yyyy-MM-dd');
            const byId = new Map<string, CalendarLesson>();
            prev.forEach((l) => {
              const lessonDateStr = l.start_time?.slice(0, 10) ?? '';
              if (lessonDateStr < startStr || lessonDateStr > endStr) {
                byId.set(String(l.id), l);
              }
            });
            mappedLessons.forEach((l) => byId.set(String(l.id), l));
            return Array.from(byId.values());
          });
        } else {
          setLessons(mappedLessons);
        }
        hasLoadedLessonsOnceRef.current = true;
      } catch (err: any) {
        console.error('Error loading lessons:', err);
        setError(err?.message || 'Ошибка загрузки занятий');
      } finally {
        setLessonsLoading(false);
      }
    },
    [visibleMonth, selectedChild?.id]
  );

  useEffect(() => {
    loadLessons();
  }, [loadLessons]);

  const handleMonthChange = useCallback((start: Date, _end: Date) => {
    const key = format(start, 'yyyy-MM');
    if (key === format(visibleMonth, 'yyyy-MM')) return;
    setVisibleMonth(startOfMonth(start));
  }, [visibleMonth]);

  const lessonsForSelectedDate: LessonPreview[] = lessons
    .filter((lesson) => {
      // Парсим дату в timezone пользователя для правильной фильтрации
      const parsed = parseISOToUserTimezone(lesson.start_time, user?.timezone);
      const lessonDate = startOfDay(parsed.dateObj);
      return lessonDate.getTime() === selectedDate.getTime();
    })
    .sort((a, b) => {
      // Сортируем по времени начала (раньше → первые)
      return new Date(a.start_time).getTime() - new Date(b.start_time).getTime();
    })
    .map((lesson) => ({
      id: String(lesson.id),
      title: lesson.title || 'Занятие',
      subject: lesson.subject ?? '',
      start_time: lesson.start_time,
      end_time: lesson.end_time,
      status: (lesson.status || 'scheduled') as 'scheduled' | 'in_progress' | 'completed' | 'cancelled',
      client: lesson.client_name
        ? {
            id: String(lesson.client || ''),
            name: lesson.client_name,
            first_name: lesson.client_name.split(' ')[0] || lesson.client_name,
            last_name: lesson.client_name.split(' ').slice(1).join(' ') || '',
          }
        : undefined,
    }));

  const handleSelectSlot = (date: Date) => {
    const dayStart = startOfDay(date);
    setSelectedDate(dayStart);
    setDisplayDate(dayStart);
    setIsFormVisible(false);
  };

  const handleSelectEvent = (lesson: { id: string }) => {
    if (isMentor) handleLessonClick(lesson);
  };

  const handlePrevDay = () => {
    const prev = subDays(displayDate, 1);
    setDisplayDate(prev);
    setSelectedDate(startOfDay(prev));
    setIsFormVisible(false);
  };

  const handleNextDay = () => {
    const next = addDays(displayDate, 1);
    setDisplayDate(next);
    setSelectedDate(startOfDay(next));
    setIsFormVisible(false);
  };

  const handleAddLesson = () => {
    setIsEditingMode(false);
    setFormData({
      client: '',
      title: '',
      description: '',
      start_date: format(selectedDate, 'yyyy-MM-dd'),
      start_time: '14:00',
      duration: 60,
      price: undefined,
      is_recurring: false,
    });
    setSelectedSubjectId(null);
    setSelectedMentorSubjectId(null);
    setIsFormVisible(true);
  };

  const handleLessonClick = (lesson: { id: string }) => {
    if (!isMentor) return; // Добавить/редактировать/просмотр — только для ментора
    setIsEditingMode(true);
    setIsFormVisible(true);
    setLessonEditLoading(true);
    setFormError(null);
    setEditingLessonId(lesson.id);

    (async () => {
      try {
        const details = await getLesson(String(lesson.id));
        
        // Парсим время в timezone пользователя
        const startParsed = parseISOToUserTimezone(details.start_time, user?.timezone);
        const safeStart = startOfDay(startParsed.dateObj);

        // синхронизируем правую панель с датой урока
        setSelectedDate(safeStart);
        setDisplayDate(safeStart);

        const duration = (() => {
          const start = new Date(details.start_time);
          const end = new Date(details.end_time);
          const mins = differenceInMinutes(end, start);
          return Number.isFinite(mins) && mins > 0 ? mins : 60;
        })();

        setFormData({
          client: details.client?.id ? String(details.client.id) : '',
          title: details.title ?? '',
          description: details.description ?? '',
          start_date: startParsed.date,
          start_time: startParsed.time,
          duration,
          price: typeof details.price === 'number' ? details.price : undefined,
          is_recurring: !!(details as any).is_recurring,
          status: (details as any).status ?? 'completed',
        });
        setEditingLessonStatus((details as any).status ?? null);

        // пробуем выставить предмет по названию
        const subjName = (details as any).subject_name || (details as any).subject || '';
        if (subjName) {
          const foundSubject = subjects.find((s) => s.name === subjName);
          const foundMentorSubject = mentorSubjects.find((s) => s.name === subjName);
          if (foundMentorSubject) {
            setSelectedSubjectId(null);
            setSelectedMentorSubjectId(foundMentorSubject.id);
          } else if (foundSubject) {
            setSelectedSubjectId(foundSubject.id);
            setSelectedMentorSubjectId(null);
          } else {
            setSelectedSubjectId(null);
            setSelectedMentorSubjectId(null);
          }
        } else {
          setSelectedSubjectId(null);
          setSelectedMentorSubjectId(null);
        }
      } catch (err: any) {
        console.error('Error loading lesson:', err);
        setFormError(err?.message || 'Не удалось загрузить данные занятия');
      } finally {
        setLessonEditLoading(false);
      }
    })();
  };

  const handleSubjectChange = (subjectId: number | null, mentorSubjectId: number | null) => {
    setSelectedSubjectId(subjectId);
    setSelectedMentorSubjectId(mentorSubjectId);
  };

  const getSubjectName = () => {
    if (selectedSubjectId) {
      const s = subjects.find((x) => x.id === selectedSubjectId);
      return s?.name ?? '';
    }
    if (selectedMentorSubjectId) {
      const s = mentorSubjects.find((x) => x.id === selectedMentorSubjectId);
      return s?.name ?? '';
    }
    return '';
  };

  const generateTitle = () => {
    const student = students.find((s) => String(s.id) === formData.client);
    const studentName = student
      ? `${student.user?.first_name || ''} ${student.user?.last_name || ''}`.trim() || student.user?.email
      : '';
    const subjectName = getSubjectName();
    if (studentName && subjectName) return `${subjectName} — ${studentName}`;
    if (studentName) return studentName;
    if (subjectName) return subjectName;
    return formData.title || 'Занятие';
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setFormLoading(true);
    setFormError(null);

    try {
      const isCompleted = editingLessonStatus === 'completed';
      if (!isCompleted) {
        if (!formData.client) {
          setFormError('Выберите ученика');
          setFormLoading(false);
          return;
        }
        if (!selectedSubjectId && !selectedMentorSubjectId) {
          setFormError('Выберите предмет');
          setFormLoading(false);
          return;
        }
        if (!formData.start_date || !formData.start_time) {
          setFormError('Укажите дату и время');
          setFormLoading(false);
          return;
        }
      }
      if (formData.price == null || formData.price < 0) {
        setFormError('Укажите стоимость занятия');
        setFormLoading(false);
        return;
      }

      const startUtc = !isCompleted
        ? createDateTimeInUserTimezone(formData.start_date, formData.start_time, user?.timezone)
        : '';
      const title = generateTitle();

      if (isEditingMode && editingLessonId) {
        if (editingLessonStatus === 'completed') {
          await updateLesson(editingLessonId, {
            price: formData.price,
            status: formData.status ?? 'completed',
          });
        } else {
          await updateLesson(editingLessonId, {
            title,
            description: formData.description,
            start_time: startUtc,
            duration: formData.duration,
            price: formData.price,
          });
        }
      } else {
        const payload: any = {
          client: formData.client,
          title,
          description: formData.description,
          start_time: startUtc,
          duration: formData.duration,
          price: formData.price,
          is_recurring: formData.is_recurring,
        };
        if (selectedSubjectId) payload.subject_id = selectedSubjectId;
        else if (selectedMentorSubjectId) payload.mentor_subject_id = selectedMentorSubjectId;

        await createLesson(payload);
      }

      setIsFormVisible(false);
      setEditingLessonId(null);
      setEditingLessonStatus(null);
      loadLessons();
    } catch (err: any) {
      setFormError(getErrorMessage(err, 'Не удалось сохранить занятие. Проверьте данные.'));
    } finally {
      setFormLoading(false);
    }
  };

  const handleDelete = async (deleteAllFuture: boolean) => {
    if (!editingLessonId) return;
    setFormLoading(true);
    setFormError(null);
    try {
      await deleteLesson(editingLessonId, deleteAllFuture);
      setIsFormVisible(false);
      setEditingLessonId(null);
      setEditingLessonStatus(null);
      loadLessons();
    } catch (err: any) {
      setFormError(getErrorMessage(err, 'Не удалось удалить занятие.'));
    } finally {
      setFormLoading(false);
    }
  };

  const handleCancel = () => {
    setIsFormVisible(false);
    setIsEditingMode(false);
    setFormError(null);
    setEditingLessonId(null);
    setEditingLessonStatus(null);
  };

  return (
    <div className="ios26-dashboard ios26-schedule-page" style={{ padding: '16px' }}>
      {error && <ErrorDisplay error={error} onRetry={loadLessons} />}
      
      <div className="ios26-schedule-layout" style={{
        display: 'grid',
        gridTemplateColumns: '5fr 2fr',
        gap: 'var(--ios26-spacing)',
        alignItems: 'stretch',
        // стабилизируем высоту секции (без фиксированных px),
        // чтобы календарь не “схлопывался” на месяцах с меньшим количеством контента
        minHeight: 'min(calc(100vh - 160px), 600px)',
      }}>
        <div className="ios26-schedule-calendar-wrap" data-tour="schedule-calendar">
          <Calendar
            lessons={lessons}
            lessonsLoading={lessonsLoading}
            selectedDate={selectedDate}
            onSelectSlot={handleSelectSlot}
            onSelectEvent={handleSelectEvent}
            onMonthChange={handleMonthChange}
            isMentor={isMentor}
            userTimezone={user?.timezone}
          />
        </div>
        <div className="ios26-schedule-right-wrap" data-tour="schedule-form">
          <CheckLesson
            selectedDate={selectedDate}
            displayDate={displayDate}
            lessonsLoading={lessonsLoading}
            lessonsForSelectedDate={lessonsForSelectedDate}
            isFormVisible={isFormVisible}
            isMentor={isMentor}
            onPrevDay={handlePrevDay}
            onNextDay={handleNextDay}
            onAddLesson={handleAddLesson}
            onLessonClick={handleLessonClick}
            buttonComponentsLoaded={buttonComponentsLoaded}
            formComponentsLoaded={formComponentsLoaded}
            lessonEditLoading={lessonEditLoading}
            isEditingMode={isEditingMode}
            formLoading={formLoading}
            formError={formError}
            formData={formData}
            setFormData={setFormData}
            selectedSubjectId={selectedSubjectId}
            selectedMentorSubjectId={selectedMentorSubjectId}
            onSubjectChange={handleSubjectChange}
            students={students}
            subjects={subjects}
            mentorSubjects={mentorSubjects}
            onSubmit={handleSubmit}
            onCancel={handleCancel}
            onDelete={isEditingMode ? handleDelete : undefined}
            isCompletedLesson={editingLessonStatus === 'completed'}
          />
        </div>
      </div>
    </div>
  );
}
