'use client';

import { useEffect, useState, useMemo } from 'react';
import { getLessons, type Lesson } from '@/api/schedule';
import { getHomeworkSubmissionsBySubject, type HomeworkSubmission } from '@/api/homework';
import { format, subMonths, startOfDay, endOfDay, addDays } from 'date-fns';
import dayjs from 'dayjs';
import dynamic from 'next/dynamic';
import { useSelectedChild } from '@/contexts/SelectedChildContext';
import { DashboardLayout, Panel, SectionHeader } from '@/components/dashboard/ui';
import { DateRangePicker } from '@/components/common/DateRangePicker';
import { LoadingSpinner } from '@/components/common/LoadingSpinner';

const Chart = dynamic(() => import('react-apexcharts').then((mod) => mod.default), {
  ssr: false,
  loading: () => (
    <div style={{ height: 260, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--md-sys-color-on-surface-variant)' }}>
      <LoadingSpinner size="medium" />
    </div>
  ),
});

const CHART_COLORS = ['#6750A4', '#7D5260'];

const defaultRange = {
  start_date: dayjs().subtract(7, 'day').format('YYYY-MM-DD'),
  end_date: dayjs().format('YYYY-MM-DD'),
};

function getSubjectFromLesson(lesson: Lesson): string {
  if (typeof lesson.subject === 'string' && lesson.subject?.trim()) return lesson.subject.trim();
  return '';
}

/** Все даты в диапазоне [startStr, endStr] включительно (формат YYYY-MM-DD) */
function getDatesInRange(startStr: string, endStr: string): string[] {
  const dates: string[] = [];
  let d = new Date(startStr);
  const end = new Date(endStr);
  while (d <= end) {
    dates.push(format(d, 'yyyy-MM-dd'));
    d = addDays(d, 1);
  }
  return dates;
}

export default function MyProgressPage() {
  const { selectedChild } = useSelectedChild();
  const [dateRangeValue, setDateRangeValue] = useState<{ start_date: string; end_date: string }>(() => defaultRange);
  const [selectedSubject, setSelectedSubject] = useState<string>('');

  const dateRange = useMemo(() => ({
    start: startOfDay(new Date(dateRangeValue.start_date)),
    end: endOfDay(new Date(dateRangeValue.end_date)),
  }), [dateRangeValue.start_date, dateRangeValue.end_date]);

  const startStr = format(dateRange.start, 'yyyy-MM-dd');
  const endStr = format(dateRange.end, 'yyyy-MM-dd');

  const [subjectsFromLessons, setSubjectsFromLessons] = useState<string[]>([]);
  const [subjectsLoading, setSubjectsLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    setSubjectsLoading(true);
    getLessons({
      start_date: format(subMonths(new Date(), 24), 'yyyy-MM-dd'),
      end_date: format(new Date(), 'yyyy-MM-dd'),
      ...(selectedChild?.id && { child_id: selectedChild.id }),
    })
      .then((res) => {
        if (cancelled) return;
        const set = new Set<string>();
        (res.results || []).forEach((l: Lesson) => {
          const sub = getSubjectFromLesson(l);
          if (sub) set.add(sub);
        });
        const list = Array.from(set).sort();
        setSubjectsFromLessons(list);
        if (list.length > 0 && !selectedSubject) setSelectedSubject(list[0]);
      })
      .catch(() => { if (!cancelled) setSubjectsFromLessons([]); })
      .finally(() => { if (!cancelled) setSubjectsLoading(false); });
    return () => { cancelled = true; };
  }, []);

  useEffect(() => {
    if (subjectsFromLessons.length > 0 && !selectedSubject) setSelectedSubject(subjectsFromLessons[0]);
  }, [subjectsFromLessons, selectedSubject]);

  const [lessons, setLessons] = useState<Lesson[]>([]);
  const [lessonsLoading, setLessonsLoading] = useState(false);

  useEffect(() => {
    if (!startStr || !endStr) return;
    let cancelled = false;
    setLessonsLoading(true);
    getLessons({
      start_date: startStr,
      end_date: endStr,
      ...(selectedChild?.id && { child_id: selectedChild.id }),
    })
      .then((res) => {
        if (cancelled) return;
        const list = (res.results || []).filter((l: Lesson) => {
          const sub = getSubjectFromLesson(l);
          return selectedSubject ? sub === selectedSubject : true;
        });
        list.sort((a: Lesson, b: Lesson) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime());
        setLessons(list);
      })
      .catch(() => { if (!cancelled) setLessons([]); })
      .finally(() => { if (!cancelled) setLessonsLoading(false); });
    return () => { cancelled = true; };
  }, [startStr, endStr, selectedSubject, selectedChild?.id]);

  const [homeworkSubmissions, setHomeworkSubmissions] = useState<HomeworkSubmission[]>([]);
  const [homeworkLoading, setHomeworkLoading] = useState(false);

  useEffect(() => {
    if (!selectedSubject) {
      setHomeworkSubmissions([]);
      return;
    }
    let cancelled = false;
    setHomeworkLoading(true);
    getHomeworkSubmissionsBySubject({
      subject: selectedSubject,
      start_date: startStr,
      end_date: endStr,
      ...(selectedChild?.id && { child_id: selectedChild.id }),
    })
      .then((res) => {
        if (cancelled) return;
        setHomeworkSubmissions(res.results || []);
      })
      .catch(() => { if (!cancelled) setHomeworkSubmissions([]); })
      .finally(() => { if (!cancelled) setHomeworkLoading(false); });
    return () => { cancelled = true; };
  }, [selectedSubject, startStr, endStr, selectedChild?.id]);

  const periodStats = useMemo(() => {
    const completed = lessons.filter((l) => l.status === 'completed').length;
    const total = lessons.length;
    const cancelled = lessons.filter((l) => l.status === 'cancelled').length;
    const attendanceRate = total > 0 ? Math.round((completed / total) * 100) : 0;

    const withGrades = lessons.filter((l) => l.status === 'completed' && (l.mentor_grade != null || l.school_grade != null));
    let sum = 0;
    let count = 0;
    withGrades.forEach((l) => {
      if (l.mentor_grade != null) { sum += l.mentor_grade; count++; }
      if (l.school_grade != null) { sum += l.school_grade; count++; }
    });
    const avgGrade = count > 0 ? Math.round((sum / count) * 10) / 10 : 0;

    const hwGraded = homeworkSubmissions.filter((s) => s.score != null && s.checked_at).length;

    return {
      completedLessons: completed,
      totalLessons: total,
      attendanceRate,
      cancelled,
      avgGrade,
      hwGraded,
    };
  }, [lessons, homeworkSubmissions]);

  const gradesChart = useMemo(() => {
    const allDates = getDatesInRange(startStr, endStr);
    const categories = allDates.map((d) => {
      const [, m, day] = d.split('-');
      return `${day}.${m}`;
    });
    const byDate: Record<string, { mentor: number | null; school: number | null }> = {};
    lessons
      .filter((l) => l.status === 'completed' && (l.mentor_grade != null || l.school_grade != null))
      .forEach((l) => {
        const key = l.start_time?.slice(0, 10) || '';
        if (!key) return;
        byDate[key] = { mentor: l.mentor_grade ?? null, school: l.school_grade ?? null };
      });
    const mentorGrades = allDates.map((d) => byDate[d]?.mentor ?? null);
    const schoolGrades = allDates.map((d) => byDate[d]?.school ?? null);
    return {
      series: [
        { name: 'Оценка репетитора', data: mentorGrades },
        { name: 'Оценка в школе', data: schoolGrades },
      ],
      categories,
    };
  }, [lessons, startStr, endStr]);

  const homeworkChart = useMemo(() => {
    const allDates = getDatesInRange(startStr, endStr);
    const categories = allDates.map((d) => {
      const [, m, day] = d.split('-');
      return `${day}.${m}`;
    });
    const byDate: Record<string, number | null> = {};
    homeworkSubmissions
      .filter((s) => s.checked_at && s.score != null)
      .forEach((s) => {
        const key = format(new Date(s.checked_at!), 'yyyy-MM-dd');
        byDate[key] = s.score ?? null;
      });
    const scores = allDates.map((d) => byDate[d] ?? null);
    return {
      series: [{ name: 'Оценка за ДЗ', data: scores }],
      categories,
    };
  }, [homeworkSubmissions, startStr, endStr]);

  // Посещаемость: по датам — сколько занятий было проведено; ось X = все даты периода
  const attendanceChart = useMemo(() => {
    const allDates = getDatesInRange(startStr, endStr);
    const categories = allDates.map((d) => {
      const [, m, day] = d.split('-');
      return `${day}.${m}`;
    });
    const byDate: Record<string, number> = {};
    lessons.forEach((l) => {
      if (l.status !== 'completed') return;
      const key = l.start_time?.slice(0, 10) || '';
      if (!key) return;
      byDate[key] = (byDate[key] ?? 0) + 1;
    });
    const data = allDates.map((d) => byDate[d] ?? 0);
    return {
      series: [{ name: 'Занятия проведены', data }],
      categories,
    };
  }, [lessons, startStr, endStr]);

  const subjects = subjectsFromLessons;
  const loading = lessonsLoading && lessons.length === 0;

  const chartOptionsBase = useMemo(
    () => ({
      chart: {
        toolbar: {
          show: true,
          tools: {
            download: true,
            zoom: true,
            zoomin: true,
            zoomout: true,
            pan: true,
            reset: true,
          },
        },
        zoom: { enabled: true, type: 'x' as const, allowMouseWheelZoom: true },
        pan: { enabled: true, type: 'x' as const },
        selection: { enabled: true, type: 'x' as const },
      },
      stroke: { curve: 'smooth' as const, width: 2 },
      colors: CHART_COLORS,
      dataLabels: { enabled: false },
      xaxis: {
        axisBorder: { show: false },
        axisTicks: { show: false },
        labels: { style: { colors: 'var(--md-sys-color-on-surface-variant)', fontSize: '12px' } },
      },
      yaxis: {
        labels: { style: { colors: 'var(--md-sys-color-on-surface-variant)', fontSize: '12px' } },
      },
      legend: {
        position: 'bottom' as const,
        horizontalAlign: 'center' as const,
        labels: { colors: 'var(--md-sys-color-on-surface-variant)' },
      },
      grid: { borderColor: 'var(--ios26-list-divider)', strokeDashArray: 4 },
    }),
    [],
  );

  const selectStyle = {
    padding: '8px 12px',
    borderRadius: 12,
    border: '1px solid var(--ios26-list-divider, rgba(0,0,0,0.12))',
    background: 'var(--md-sys-color-surface-container-low)',
    color: 'var(--md-sys-color-on-surface)',
    minWidth: 180,
    fontSize: 14,
    cursor: 'pointer' as const,
    outline: 'none' as const,
  };

  return (
    <div style={{ width: '100%' }}>
      <DashboardLayout className="ios26-dashboard-grid" data-tour="my-progress-root">
      {/* Ячейка 1: Общая статистика за период + выбор предмета и даты */}
      <Panel padding="md">
        <SectionHeader
          title="Прогресс за период"
          trailing={
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center' }}>
              <select
                value={selectedSubject}
                onChange={(e) => setSelectedSubject(e.target.value)}
                disabled={!subjects.length}
                style={{
                  ...selectStyle,
                  opacity: subjects.length ? 1 : 0.7,
                }}
              >
                {subjects.length === 0 ? (
                  <option value="">Нет предметов</option>
                ) : (
                  subjects.map((s) => (
                    <option key={s} value={s}>{s}</option>
                  ))
                )}
              </select>
              <DateRangePicker
                value={dateRangeValue}
                onChange={(v) => setDateRangeValue({ start_date: v.start_date, end_date: v.end_date })}
                disabled={subjectsLoading}
              />
            </div>
          }
        />
        {loading ? (
          <div style={{ minHeight: 200, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <LoadingSpinner size="medium" />
          </div>
        ) : (
          <div className="ios26-stat-grid my-progress-grid" style={{ gridTemplateColumns: 'repeat(2, minmax(0, 1fr))' }}>
            <div className="ios26-stat-tile">
              <div className="ios26-stat-label">Занятий проведено</div>
              <div className="ios26-stat-value ios26-stat-value--primary">{periodStats.completedLessons}</div>
              <div style={{ fontSize: 12, color: 'var(--md-sys-color-on-surface-variant)' }}>из {periodStats.totalLessons}</div>
            </div>
            <div className="ios26-stat-tile">
              <div className="ios26-stat-label">Посещаемость</div>
              <div className="ios26-stat-value ios26-stat-value--primary">{periodStats.attendanceRate}%</div>
            </div>
            <div className="ios26-stat-tile">
              <div className="ios26-stat-label">Средняя оценка</div>
              <div className="ios26-stat-value">{periodStats.avgGrade || '—'}</div>
            </div>
            <div className="ios26-stat-tile">
              <div className="ios26-stat-label">ДЗ с оценкой</div>
              <div className="ios26-stat-value">{periodStats.hwGraded}</div>
            </div>
          </div>
        )}
      </Panel>

      {/* Ячейка 2: Успеваемость (оценки репетитора и школы) */}
      <Panel padding="md">
        <SectionHeader title="Успеваемость (репетитор и школа)" />
        {gradesChart.categories.length === 0 ? (
          <div style={{ height: 260, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--md-sys-color-on-surface-variant)', fontSize: 14 }}>
            Нет оценок за период
          </div>
        ) : (
          <Chart
            type="line"
            height={260}
            series={gradesChart.series}
            options={{
              ...chartOptionsBase,
              xaxis: { ...chartOptionsBase.xaxis, categories: gradesChart.categories },
              yaxis: { ...chartOptionsBase.yaxis, min: 1, max: 5, title: { text: 'Оценка (1–5)' } },
            }}
          />
        )}
      </Panel>

      {/* Ячейка 3: Успеваемость по ДЗ */}
      <Panel padding="md">
        <SectionHeader title="Успеваемость по ДЗ" />
        {homeworkChart.categories.length === 0 ? (
          <div style={{ height: 260, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--md-sys-color-on-surface-variant)', fontSize: 14 }}>
            Нет оценок за ДЗ за период
          </div>
        ) : (
          <Chart
            type="line"
            height={260}
            series={homeworkChart.series}
            options={{
              ...chartOptionsBase,
              colors: ['#6750A4'],
              xaxis: { ...chartOptionsBase.xaxis, categories: homeworkChart.categories },
              yaxis: { ...chartOptionsBase.yaxis, min: 0, max: 100, title: { text: 'Оценка' } },
            }}
          />
        )}
      </Panel>

      {/* Ячейка 4: Посещаемость — проведённые занятия по датам */}
      <Panel padding="md">
        <SectionHeader title="Посещаемость" />
        {attendanceChart.categories.length === 0 ? (
          <div style={{ height: 260, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--md-sys-color-on-surface-variant)', fontSize: 14 }}>
            Нет проведённых занятий за период
          </div>
        ) : (
          <Chart
            type="line"
            height={260}
            series={attendanceChart.series}
            options={{
              ...chartOptionsBase,
              colors: ['#6750A4'],
              xaxis: { ...chartOptionsBase.xaxis, categories: attendanceChart.categories },
              yaxis: {
              ...chartOptionsBase.yaxis,
              title: { text: 'Занятий' },
              min: 0,
              tickAmount: 4,
              labels: {
                ...(chartOptionsBase.yaxis?.labels ?? {}),
                formatter: (val: number) => String(Math.round(val)),
              },
            },
            }}
          />
        )}
      </Panel>
      </DashboardLayout>
    </div>
  );
}
