import React, { useEffect, useRef, useMemo, useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import QRCode from 'qrcode'
import { sha256 } from 'js-sha256'
import { getConfigValue, getNavigationValue } from '@brojs/cli'
import { motion, AnimatePresence } from 'framer-motion'
import {
  Box,
  Container,
  VStack,
  Heading,
  Stack,
  useColorMode,
} from '@chakra-ui/react'
import { useTranslation } from 'react-i18next'

import { api } from '../__data__/api/api'
import { User } from '../__data__/model'
import { UserCard } from '../components/user-card'
import { formatDate } from '../utils/dayjs-config'
import { useSetBreadcrumbs } from '../components'

import {
  QRCanvas,
  StudentList,
} from './style'
import { useAppSelector } from '../__data__/store'
import { isTeacher } from '../utils/user'

export function getGravatarURL(email, user) {
  if (!email) return void 0
  const address = String(email).trim().toLowerCase()
  const hash = sha256(address)

  // Grab the actual image URL
  return `https://www.gravatar.com/avatar/${hash}?d=robohash`
}

const LessonDetail = () => {
  const { lessonId, courseId } = useParams()
  const canvRef = useRef(null)
  const user = useAppSelector((s) => s.user)
  const { t } = useTranslation()
  const { colorMode } = useColorMode()
  
  // Получаем данные о курсе и уроке
  const { data: courseData } = api.useGetCourseByIdQuery(courseId)
  const { data: lessonData } = api.useLessonByIdQuery(lessonId)
  
  // Устанавливаем хлебные крошки
  useSetBreadcrumbs([
    {
      title: t('journal.pl.breadcrumbs.home'),
      path: '/'
    },
    {
      title: courseData?.name || t('journal.pl.breadcrumbs.course'),
      path: `${getNavigationValue('journal.main')}/lessons-list/${courseId}`
    },
    {
      title: lessonData?.body?.name || t('journal.pl.breadcrumbs.lesson'),
      isCurrentPage: true
    }
  ])
  
  // Создаем ref для отслеживания ранее присутствовавших студентов
  const prevPresentStudentsRef = useRef(new Set<string>())
  
  // Добавляем состояние для отслеживания пульсации
  const [isPulsing, setIsPulsing] = useState(false)
  // Отслеживаем предыдущее количество студентов
  const prevStudentCountRef = useRef(0)
  
  const {
    isFetching,
    data: accessCode,
    isSuccess,
    refetch,
  } = api.useCreateAccessCodeQuery(
    { lessonId },
    {
      skip: !isTeacher(user),
      pollingInterval:
        Number(getConfigValue('journal.polling-interval')) || 3000,
      skipPollingIfUnfocused: true,
    },
  )
  const AllStudents = api.useCourseAllStudentsQuery(courseId)
  const [manualAdd, manualAddRqst] = api.useManualAddStudentMutation()
  const userUrl = useMemo(
    () => `${location.origin}/journal/u/${lessonId}/${accessCode?.body?._id}`,
    [accessCode, lessonId],
  )

  // Эффект для обнаружения и обновления новых присутствующих студентов
  useEffect(() => {
    if (accessCode?.body) {
      const currentPresent = new Set(accessCode.body.lesson.students.map(s => s.sub))
      
      // Проверяем, изменилось ли количество студентов
      const currentCount = accessCode.body.lesson.students.length;
      if (prevStudentCountRef.current !== currentCount && prevStudentCountRef.current > 0) {
        // Запускаем эффект пульсации
        setIsPulsing(true);
        // Сбрасываем эффект через 1.5 секунды
        setTimeout(() => {
          setIsPulsing(false);
        }, 1500);
      }
      
      // Обновляем предыдущее количество
      prevStudentCountRef.current = currentCount;
      
      // Очищаем флаги предыдущего состояния после задержки
      const timeoutId = setTimeout(() => {
        prevPresentStudentsRef.current = currentPresent
      }, 3000)
      
      return () => clearTimeout(timeoutId)
    }
  }, [accessCode])

  useEffect(() => {
    if (manualAddRqst.isSuccess) {
      refetch()
    }
  }, [manualAddRqst.isSuccess])

  useEffect(() => {
    if (!isFetching && isSuccess) {
      const generateQRCode = () => {
        if (!canvRef.current) return;
        
        // Получаем текущую ширину канваса, гарантируя квадратный QR-код
        const canvas = canvRef.current;
        const containerWidth = canvas.clientWidth;
        
        // Очищаем canvas перед новой генерацией
        const ctx = canvas.getContext('2d');
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // Устанавливаем одинаковые размеры для ширины и высоты (1:1)
        canvas.width = containerWidth;
        canvas.height = containerWidth;
        
        QRCode.toCanvas(
          canvas,
          userUrl,
          { 
            width: containerWidth,
            margin: 1 // Небольшой отступ для лучшей читаемости
          },
          function (error) {
            if (error) console.error(error)
            console.log('success!')
          },
        )
      }
      
      // Генерируем QR-код
      generateQRCode();
      
      // Перегенерируем при изменении размера окна
      const handleResize = () => {
        generateQRCode();
      };
      
      window.addEventListener('resize', handleResize);
      
      return () => {
        window.removeEventListener('resize', handleResize);
      };
    }
  }, [isFetching, isSuccess, userUrl])

  const studentsArr = useMemo(() => {
    let allStudents: (User & { present?: boolean; recentlyPresent?: boolean })[] = [
      ...(AllStudents.data?.body || []),
    ].map((st) => ({ ...st, present: false, recentlyPresent: false }))
    let presentStudents: (User & { present?: boolean })[] = [
      ...(accessCode?.body.lesson.students || []),
    ]

    // Находим новых студентов по сравнению с предыдущим состоянием
    const currentPresent = new Set(presentStudents.map(s => s.sub))
    const newlyPresent = [...currentPresent].filter(id => !prevPresentStudentsRef.current.has(id))

    while (presentStudents.length) {
      const student = presentStudents.pop()

      const present = allStudents.find((st) => st.sub === student.sub)

      if (present) {
        present.present = true
        present.recentlyPresent = newlyPresent.includes(student.sub)
      } else {
        allStudents.push({ 
          ...student, 
          present: true, 
          recentlyPresent: newlyPresent.includes(student.sub) 
        })
      }
    }

    return allStudents.sort((a, b) => (a.present ? -1 : 1))
  }, [accessCode?.body, AllStudents.data, prevPresentStudentsRef.current])

  // Функция для определения цвета на основе посещаемости
  const getAttendanceColor = (attendance: number, total: number) => {
    const percentage = total > 0 ? (attendance / total) * 100 : 0
    
    if (percentage > 80) return { bg: 'green.100', color: 'green.800', dark: { bg: 'green.800', color: 'green.100' } }
    if (percentage > 60) return { bg: 'teal.100', color: 'teal.800', dark: { bg: 'teal.800', color: 'teal.100' } }
    if (percentage > 40) return { bg: 'yellow.100', color: 'yellow.800', dark: { bg: 'yellow.800', color: 'yellow.100' } }
    if (percentage > 20) return { bg: 'orange.100', color: 'orange.800', dark: { bg: 'orange.800', color: 'orange.100' } }
    return { bg: 'red.100', color: 'red.800', dark: { bg: 'red.800', color: 'red.100' } }
  }

  return (
    <>
      <Container maxW="2280px">
        <VStack align="left">
          <Heading as="h3" mt="4" mb="3">
            {t('journal.pl.lesson.topicTitle')}
          </Heading>
          <Box as="span">{accessCode?.body?.lesson?.name}</Box>
          
        </VStack>
        <Stack spacing="8" direction={{ base: "column", md: "row" }} mt={6}>
          <Box 
            flexShrink={0} 
            alignSelf="flex-start" 
            p={4} 
            borderRadius="xl" 
            bg={colorMode === "light" ? "gray.50" : "gray.700"}
            boxShadow="md"
          ><Box pb={3}>
          {formatDate(accessCode?.body?.lesson?.date, t('journal.pl.lesson.dateFormat'))}{' '}
          {t('journal.pl.common.marked')} - 
          {AllStudents.isSuccess && (
            <Box 
              as="span" 
              px={2} 
              py={1} 
              ml={2}
              borderRadius="md"
              fontWeight="bold"
              bg={getAttendanceColor(
                accessCode?.body?.lesson?.students?.length || 0, 
                AllStudents?.data?.body?.length || 1
              ).bg}
              color={getAttendanceColor(
                accessCode?.body?.lesson?.students?.length || 0, 
                AllStudents?.data?.body?.length || 1
              ).color}
              _dark={{ 
                bg: getAttendanceColor(
                  accessCode?.body?.lesson?.students?.length || 0, 
                  AllStudents?.data?.body?.length || 1
                ).dark.bg, 
                color: getAttendanceColor(
                  accessCode?.body?.lesson?.students?.length || 0, 
                  AllStudents?.data?.body?.length || 1
                ).dark.color 
              }}
              position="relative"
              animation={isPulsing ? "pulse 1.5s ease-in-out" : "none"}
              sx={{
                '@keyframes pulse': {
                  '0%': { transform: 'scale(1)' },
                  '50%': { transform: 'scale(1.15)', boxShadow: '0 0 10px rgba(66, 153, 225, 0.7)' },
                  '100%': { transform: 'scale(1)' }
                }
              }}
            >
              {accessCode?.body?.lesson?.students?.length} / {AllStudents?.data?.body?.length}
            </Box>
          )}
          {!AllStudents.isSuccess && (
            <span> {accessCode?.body?.lesson?.students?.length}</span>
          )}{' '}
          {t('journal.pl.common.people')}
        </Box>
            <a href={userUrl}>
              <QRCanvas ref={canvRef} />
            </a>
          </Box>
          <Box 
            flex={1} 
            p={4} 
            borderRadius="xl" 
            bg={colorMode === "light" ? "gray.50" : "gray.700"}
            boxShadow="md"
          >
            <StudentList>
              {isTeacher(user) && (
                <AnimatePresence initial={false}>
                  {studentsArr.map((student) => (
                    <motion.li
                      key={student.sub}
                      layout
                      initial={{ opacity: 0, scale: 0.8 }}
                      animate={{ 
                        opacity: 1, 
                        scale: 1,
                        // Добавляем подсветку для недавно отметившихся студентов
                        boxShadow: student.recentlyPresent 
                          ? ['0 0 0 0 rgba(66, 153, 225, 0)', '0 0 20px 5px rgba(66, 153, 225, 0.7)', '0 0 0 0 rgba(66, 153, 225, 0)'] 
                          : '0 0 0 0 rgba(0, 0, 0, 0)'
                      }}
                      exit={{ opacity: 0, scale: 0.8 }}
                      transition={{ 
                        type: "spring", 
                        stiffness: 300, 
                        damping: 30,
                        layout: { duration: 0.4 },
                        boxShadow: {
                          repeat: student.recentlyPresent ? 3 : 0,
                          duration: 1.5
                        }
                      }}
                    >
                      <UserCard
                        wrapperAS="div"
                        student={student}
                        present={student.present}
                        recentlyPresent={student.recentlyPresent}
                        onAddUser={(user: User) => manualAdd({ lessonId, user })}
                      />
                    </motion.li>
                  ))}
                </AnimatePresence>
              )}
            </StudentList>
          </Box>
        </Stack>
      </Container>
    </>
  )
}

export default LessonDetail
