
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import listPlugin from '@fullcalendar/list';
import timelinePlugin from '@fullcalendar/timeline';
import ruLocale from '@fullcalendar/core/locales/ru';

import { useState, useRef, useEffect, useCallback, useMemo } from 'react';

import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
import Alert from '@mui/material/Alert';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import Switch from '@mui/material/Switch';
import Rating from '@mui/material/Rating';
import Divider from '@mui/material/Divider';
import TextField from '@mui/material/TextField';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import DialogTitle from '@mui/material/DialogTitle';
import FormControl from '@mui/material/FormControl';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import CircularProgress from '@mui/material/CircularProgress';
import FormControlLabel from '@mui/material/FormControlLabel';

import { paths } from 'src/routes/paths';
import { useRouter } from 'src/routes/hooks';
import { useAuthContext } from 'src/auth/hooks';
import { useBoolean } from 'src/hooks/use-boolean';
import { useGetEvents, updateEvent, createEvent, deleteEvent } from 'src/actions/calendar';
import { createLiveKitRoom } from 'src/utils/livekit-api';
import { completeLesson, uploadLessonFile } from 'src/utils/dashboard-api';
import { createHomework } from 'src/utils/homework-api';

import { Iconify } from 'src/components/iconify';
import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs';
import { useSettingsContext } from 'src/components/settings';

import { CalendarForm } from '../calendar-form';
import { StyledCalendar } from '../styles';
import { CalendarToolbar } from '../calendar-toolbar';
import { useCalendar } from '../hooks/use-calendar';

// ----------------------------------------------------------------------

const MAX_HW_FILES = 10;
const MAX_HW_FILE_MB = 10;

function defaultDeadline() {
  const d = new Date();
  d.setDate(d.getDate() + 10);
  return d.toISOString().slice(0, 10);
}

// Controlled: lessonId + open + onClose props.
// Uncontrolled: reads lessonId from sessionStorage on mount.
function CompleteLessonDialog({ lessonId: propLessonId, open: propOpen, onClose: propOnClose }) {
  const isControlled = propLessonId != null;

  const [ssLessonId, setSsLessonId] = useState(null);
  const [ssOpen, setSsOpen] = useState(false);

  const [mentorGrade, setMentorGrade] = useState(0);
  const [schoolGrade, setSchoolGrade] = useState(0);
  const [notes, setNotes] = useState('');
  const [hasHw, setHasHw] = useState(false);
  const [hwTitle, setHwTitle] = useState('Домашнее задание');
  const [hwText, setHwText] = useState('');
  const [hwFiles, setHwFiles] = useState([]);
  const [hwDeadline, setHwDeadline] = useState(defaultDeadline);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const fileInputRef = useRef(null);

  // Uncontrolled: check sessionStorage once on mount
  useEffect(() => {
    if (isControlled) return;
    try {
      const id = sessionStorage.getItem('complete_lesson_id');
      if (id) {
        setSsLessonId(parseInt(id, 10));
        setSsOpen(true);
        sessionStorage.removeItem('complete_lesson_id');
      }
    } catch { /* ignore */ }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Reset form when a new lesson is opened
  useEffect(() => {
    const willOpen = isControlled ? propOpen : ssOpen;
    if (willOpen) {
      setMentorGrade(0);
      setSchoolGrade(0);
      setNotes('');
      setHasHw(false);
      setHwTitle('Домашнее задание');
      setHwText('');
      setHwFiles([]);
      setHwDeadline(defaultDeadline());
      setError(null);
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isControlled ? propOpen : ssOpen, isControlled ? propLessonId : ssLessonId]);

  const lessonId = isControlled ? propLessonId : ssLessonId;
  const open = isControlled ? (propOpen ?? false) : ssOpen;

  const handleClose = () => {
    if (loading) return;
    if (isControlled) propOnClose?.();
    else setSsOpen(false);
  };

  const handleFileChange = (e) => {
    const { files: list } = e.target;
    if (!list?.length) return;
    const toAdd = Array.from(list).filter((f) => f.size <= MAX_HW_FILE_MB * 1024 * 1024);
    setHwFiles((prev) => [...prev, ...toAdd].slice(0, MAX_HW_FILES));
    e.target.value = '';
  };

  const handleSubmit = async () => {
    if (!lessonId) return;
    setLoading(true);
    setError(null);
    try {
      const mg = mentorGrade > 0 ? mentorGrade : undefined;
      const sg = schoolGrade > 0 ? schoolGrade : undefined;
      const n = notes.trim() || '';

      let fileIds = [];
      if (hasHw && hwFiles.length > 0) {
        // eslint-disable-next-line no-restricted-syntax
        for (const file of hwFiles) {
          // eslint-disable-next-line no-await-in-loop
          const created = await uploadLessonFile(lessonId, file);
          const fid = typeof created.id === 'number' ? created.id : parseInt(String(created.id), 10);
          if (!Number.isNaN(fid)) fileIds.push(fid);
        }
      }

      const hwT = hasHw ? hwText.trim() || undefined : undefined;
      await completeLesson(String(lessonId), n, mg, sg, hwT, hasHw && fileIds.length > 0, fileIds.length > 0 ? fileIds : undefined);

      if (hasHw && (hwText.trim() || hwFiles.length > 0)) {
        await createHomework({
          title: hwTitle.trim() || 'Домашнее задание',
          description: hwText.trim(),
          lesson_id: lessonId,
          due_date: hwDeadline,
          status: 'published',
        });
      }

      handleClose();
    } catch (e) {
      setError(e?.response?.data?.detail || e?.message || 'Не удалось сохранить данные урока');
    } finally {
      setLoading(false);
    }
  };

  if (!open) return null;

  return (
    <Dialog
      open={open}
      onClose={(_, reason) => { if (reason !== 'backdropClick') handleClose(); }}
      maxWidth="sm"
      fullWidth
      disableEscapeKeyDown
    >
      <DialogTitle sx={{ pb: 1 }}>
        <Typography variant="h6">Завершение урока</Typography>
        <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
          Заполните информацию о прошедшем занятии
        </Typography>
      </DialogTitle>

      <DialogContent dividers sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
        {error && <Alert severity="error">{error}</Alert>}

        {/* Grades */}
        <Box>
          <Typography variant="subtitle2" sx={{ mb: 1.5 }}>Оценка за занятие</Typography>
          <Stack direction="row" spacing={4}>
            <FormControl>
              <Typography variant="caption" color="text.secondary" sx={{ mb: 0.5 }}>Успеваемость (1–5)</Typography>
              <Rating
                value={mentorGrade}
                max={5}
                onChange={(_, v) => setMentorGrade(v ?? 0)}
                disabled={loading}
              />
            </FormControl>
            <FormControl>
              <Typography variant="caption" color="text.secondary" sx={{ mb: 0.5 }}>Школьная оценка (1–5)</Typography>
              <Rating
                value={schoolGrade}
                max={5}
                onChange={(_, v) => setSchoolGrade(v ?? 0)}
                disabled={loading}
              />
            </FormControl>
          </Stack>
        </Box>

        <Divider />

        {/* Comment */}
        <TextField
          label="Комментарий к уроку"
          placeholder="Что прошли, успехи, рекомендации…"
          value={notes}
          onChange={(e) => setNotes(e.target.value)}
          multiline
          rows={3}
          disabled={loading}
          fullWidth
        />

        <Divider />

        {/* Homework toggle */}
        <Box>
          <FormControlLabel
            control={
              <Switch
                checked={hasHw}
                onChange={(e) => setHasHw(e.target.checked)}
                disabled={loading}
              />
            }
            label="Выдать домашнее задание"
          />
        </Box>

        {/* Homework form */}
        {hasHw && (
          <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
            <TextField
              label="Название ДЗ"
              value={hwTitle}
              onChange={(e) => setHwTitle(e.target.value)}
              disabled={loading}
              fullWidth
              size="small"
            />
            <TextField
              label="Описание задания"
              placeholder="Опишите задание…"
              value={hwText}
              onChange={(e) => setHwText(e.target.value)}
              multiline
              rows={3}
              disabled={loading}
              fullWidth
            />
            <TextField
              label="Дедлайн"
              type="date"
              value={hwDeadline}
              onChange={(e) => setHwDeadline(e.target.value)}
              disabled={loading}
              fullWidth
              size="small"
              InputLabelProps={{ shrink: true }}
              inputProps={{ min: new Date().toISOString().slice(0, 10) }}
            />
            {/* File upload */}
            <Box>
              <input
                ref={fileInputRef}
                type="file"
                multiple
                onChange={handleFileChange}
                disabled={loading}
                style={{ display: 'none' }}
              />
              <Button
                size="small"
                variant="outlined"
                startIcon={<Iconify icon="solar:paperclip-bold" width={16} />}
                onClick={() => fileInputRef.current?.click()}
                disabled={loading || hwFiles.length >= MAX_HW_FILES}
              >
                Прикрепить файлы
              </Button>
              {hwFiles.length > 0 && (
                <Stack spacing={0.5} sx={{ mt: 1 }}>
                  {hwFiles.map((f, i) => (
                    <Stack
                      key={`${f.name}-${i}-${f.size}`}
                      direction="row"
                      alignItems="center"
                      spacing={1}
                      sx={{ p: 0.75, borderRadius: 1, bgcolor: 'action.hover' }}
                    >
                      <Iconify icon="solar:document-bold" width={16} color="text.secondary" />
                      <Typography variant="caption" noWrap sx={{ flex: 1 }}>{f.name}</Typography>
                      <Button
                        size="small"
                        color="error"
                        disabled={loading}
                        onClick={() => setHwFiles((p) => p.filter((_, j) => j !== i))}
                        sx={{ minWidth: 0, p: 0.5 }}
                      >
                        <Iconify icon="solar:trash-bin-trash-bold" width={14} />
                      </Button>
                    </Stack>
                  ))}
                </Stack>
              )}
            </Box>
          </Box>
        )}
      </DialogContent>

      <DialogActions sx={{ px: 3, py: 2 }}>
        <Button onClick={handleClose} disabled={loading} color="inherit">
          Пропустить
        </Button>
        <Button
          onClick={handleSubmit}
          disabled={loading}
          variant="contained"
          startIcon={loading ? <CircularProgress size={16} color="inherit" /> : <Iconify icon="solar:check-circle-bold" width={18} />}
        >
          {loading ? 'Сохранение…' : 'Сохранить'}
        </Button>
      </DialogActions>
    </Dialog>
  );
}

// ----------------------------------------------------------------------

function isValidTimezone(tz) {
  if (!tz) return false;
  try { Intl.DateTimeFormat(undefined, { timeZone: tz }); return true; } catch { return false; }
}

function fTime(str, timezone) {
  if (!str) return '';
  const opts = { hour: '2-digit', minute: '2-digit', ...(isValidTimezone(timezone) ? { timeZone: timezone } : {}) };
  return new Date(str).toLocaleTimeString('ru-RU', opts);
}

function UpcomingLessonsBar({ events, isMentor, timezone }) {
  const router = useRouter();
  const [joiningId, setJoiningId] = useState(null);

  const now = new Date();
  const todayKey = now.toDateString();

  // Занятия сегодня, ещё не завершённые (не завершено и не отменено), сортируем по времени
  const todayUpcoming = useMemo(() => {
    return events
      .filter((ev) => {
        const st = new Date(ev.start);
        const status = String(ev.extendedProps?.status || '').toLowerCase();
        return st.toDateString() === todayKey && status !== 'completed' && status !== 'cancelled';
      })
      .sort((a, b) => new Date(a.start) - new Date(b.start))
      .slice(0, 3);
  }, [events, todayKey]);

  if (todayUpcoming.length === 0) return null;

  const handleJoin = async (ev) => {
    setJoiningId(ev.id);
    try {
      const room = await createLiveKitRoom(ev.id);
      const token = room.access_token || room.token;
      router.push(`${paths.dashboard.prejoin}?token=${encodeURIComponent(token)}&lesson_id=${ev.id}`);
    } catch (e) {
      console.error(e);
    } finally {
      setJoiningId(null);
    }
  };

  return (
    <Box sx={{ mb: 3 }}>
      <Typography variant="subtitle2" sx={{ mb: 1.5, color: 'text.secondary' }}>
        Сегодня · {todayUpcoming.length} {todayUpcoming.length === 1 ? 'занятие' : 'занятий'}
      </Typography>
      <Box sx={{ display: 'grid', gap: 2, gridTemplateColumns: { xs: '1fr', sm: 'repeat(2,1fr)', md: 'repeat(3,1fr)' } }}>
        {todayUpcoming.map((ev) => {
          const ep = ev.extendedProps || {};
          const startTime = new Date(ev.start);
          const diffMin = (startTime - now) / 60000;
          const canJoin = diffMin < 11 && diffMin > -90;
          const isJoining = joiningId === ev.id;

          // Групповое занятие — показываем название группы, индивидуальное — имя ученика/ментора
          const personName = ep.group_name
            ? ep.group_name
            : isMentor
              ? (ep.student || ep.client_name || '')
              : (ep.mentor_name || ep.mentor || '');
          const subject = ep.subject_name || ep.subject || ev.title || 'Занятие';
          const initial = (personName[0] || subject[0] || 'З').toUpperCase();

          return (
            <Card
              key={ev.id}
              onClick={() => !canJoin && router.push(paths.dashboard.lesson(ev.id))}
              sx={{
                p: 2,
                display: 'flex',
                alignItems: 'center',
                gap: 1.5,
                border: '1px solid',
                borderColor: canJoin ? 'primary.main' : 'divider',
                boxShadow: canJoin ? (t) => `0 0 0 2px ${t.vars.palette.primary.main}22` : 0,
                transition: 'all 0.2s',
                cursor: canJoin ? 'default' : 'pointer',
                '&:hover': !canJoin ? { bgcolor: 'action.hover' } : {},
              }}
            >
              <Avatar sx={{ bgcolor: 'primary.main', width: 44, height: 44, flexShrink: 0 }}>
                {initial}
              </Avatar>
              <Box sx={{ flex: 1, minWidth: 0 }}>
                <Typography variant="subtitle2" noWrap>{subject}</Typography>
                {personName && (
                  <Typography variant="caption" color="text.secondary" noWrap display="block">{personName}</Typography>
                )}
                <Chip
                  label={fTime(ev.start, timezone)}
                  size="small"
                  color={canJoin ? 'primary' : 'default'}
                  variant={canJoin ? 'filled' : 'outlined'}
                  icon={<Iconify icon="solar:clock-circle-bold" width={12} />}
                  sx={{ mt: 0.5, height: 20, fontSize: 11 }}
                />
              </Box>
              {canJoin && (
                <Button
                  size="small"
                  variant="contained"
                  color="primary"
                  disabled={isJoining}
                  onClick={(e) => { e.stopPropagation(); handleJoin(ev); }}
                  startIcon={isJoining
                    ? <CircularProgress size={14} color="inherit" />
                    : <Iconify icon="solar:videocamera-record-bold" width={16} />}
                  sx={{ flexShrink: 0, whiteSpace: 'nowrap' }}
                >
                  {isJoining ? '...' : 'Войти'}
                </Button>
              )}
            </Card>
          );
        })}
      </Box>
    </Box>
  );
}

// ----------------------------------------------------------------------

// Statuses that should open the detail page instead of the edit form
const NON_PLANNED_STATUSES = ['completed', 'in_progress', 'ongoing', 'cancelled'];

export function CalendarView() {
  const settings = useSettingsContext();
  const router = useRouter();
  const { user } = useAuthContext();
  const isMentor = user?.role === 'mentor';

  const [completeLessonId, setCompleteLessonId] = useState(null);
  const [completeLessonOpen, setCompleteLessonOpen] = useState(false);

  const handleOpenCompleteLesson = useCallback((lessonId) => {
    setCompleteLessonId(lessonId);
    setCompleteLessonOpen(true);
  }, []);

  const { calendarRef, view, date, onDatePrev, onDateNext, onDateToday, onChangeView,
    onSelectRange, onClickEvent, onResizeEvent, onDropEvent, onInitialView,
    openForm, onOpenForm, onCloseForm, selectEventId, selectedRange } = useCalendar();

  // Intercept event click:
  // - completed/cancelled/ongoing → detail page
  // - past lessons (end_time already passed) → detail page regardless of status
  // - future planned → mentor gets edit form, student gets detail page
  const handleEventClick = useCallback((arg) => {
    const eventId = arg.event.id;
    if (!eventId || eventId === 'undefined' || eventId === 'null') return;

    const ep = arg.event.extendedProps || {};
    const status = String(ep.status || '').toLowerCase();

    // Use raw API timestamps from extendedProps (more reliable than FullCalendar Date objects)
    const rawEnd = ep.end_time || ep.end;
    const rawStart = ep.start_time || ep.start;
    const refTime = rawEnd || rawStart;
    const isPast = refTime ? new Date(refTime).getTime() < Date.now() : false;

    if (NON_PLANNED_STATUSES.includes(status) || isPast) {
      router.push(paths.dashboard.lesson(eventId));
    } else if (isMentor) {
      onClickEvent(arg);
    } else {
      // student/parent — open detail page for upcoming lessons too
      router.push(paths.dashboard.lesson(eventId));
    }
  }, [router, isMentor, onClickEvent]);

  const { events, eventsLoading } = useGetEvents(date);

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

  const handleCreateEvent = useCallback(
    (eventData) => createEvent(eventData, date),
    [date]
  );

  const handleUpdateEvent = useCallback(
    (eventData) => updateEvent(eventData, date),
    [date]
  );

  const handleDeleteEvent = useCallback(
    (eventId, deleteAllFuture) => deleteEvent(eventId, deleteAllFuture, date),
    [date]
  );

  return (
    <>
      <Container maxWidth={settings.themeStretch ? false : 'xl'}>
        <Stack
          direction="row"
          alignItems="center"
          justifyContent="space-between"
          sx={{ mb: { xs: 3, md: 5 } }}
        >
          <Stack spacing={1}>
            <Typography variant="h4">Расписание</Typography>
            <CustomBreadcrumbs
              links={[
                { name: 'Дашборд', href: paths.dashboard.root },
                { name: 'Расписание' },
              ]}
            />
          </Stack>

          {isMentor && (
            <Button
              variant="contained"
              startIcon={<Iconify icon="mingcute:add-line" />}
              onClick={() => onOpenForm()}
            >
              Новое занятие
            </Button>
          )}
        </Stack>

        <UpcomingLessonsBar events={events} isMentor={isMentor} timezone={user?.timezone} />

        <Card sx={{ position: 'relative' }}>
          <StyledCalendar>
            <CalendarToolbar
              date={date}
              view={view}
              loading={eventsLoading}
              onNextDate={onDateNext}
              onPrevDate={onDatePrev}
              onToday={onDateToday}
              onChangeView={onChangeView}
            />

            <FullCalendar
              weekends
              editable={isMentor}
              droppable={isMentor}
              selectable={isMentor}
              rerenderEvents
              events={events}
              ref={calendarRef}
              initialDate={date}
              initialView={view}
              dayMaxEventRows={5}
              eventDisplay="block"
              headerToolbar={false}
              allDayMaintainDuration
              eventResizableFromStart
              displayEventTime={false}
              select={isMentor ? onSelectRange : undefined}
              eventClick={handleEventClick}
              eventDrop={isMentor ? onDropEvent : undefined}
              eventResize={isMentor ? onResizeEvent : undefined}
              eventOrder={(a, b) => {
                const done = (e) => {
                  const s = String(e.extendedProps?.status || '').toLowerCase();
                  return s === 'completed' || s === 'cancelled' ? 1 : 0;
                };
                return done(a) - done(b);
              }}
              plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin, timelinePlugin]}
              locale={ruLocale}
              timeZone={isValidTimezone(user?.timezone) ? user.timezone : 'local'}
              slotLabelFormat={{ hour: '2-digit', minute: '2-digit', hour12: false }}
              eventTimeFormat={{ hour: '2-digit', minute: '2-digit', hour12: false }}
            />
          </StyledCalendar>
        </Card>
      </Container>

      {isMentor && (
        <CalendarForm
          currentEvent={events.find((event) => event.id === selectEventId)}
          range={selectedRange}
          open={openForm}
          onClose={onCloseForm}
          onCreateEvent={handleCreateEvent}
          onUpdateEvent={handleUpdateEvent}
          onDeleteEvent={handleDeleteEvent}
          onCompleteLesson={(lessonId) => { onCloseForm(); handleOpenCompleteLesson(lessonId); }}
        />
      )}

      {/* Auto-open after video call redirect (reads sessionStorage) */}
      {isMentor && <CompleteLessonDialog />}

      {/* Controlled: opened from CalendarForm */}
      {isMentor && (
        <CompleteLessonDialog
          lessonId={completeLessonId}
          open={completeLessonOpen}
          onClose={() => setCompleteLessonOpen(false)}
        />
      )}
    </>
  );
}
