import React, { useEffect, useState, useRef, useCallback } from 'react'
import { getFeatures } from '@brojs/cli'
import { useForm, Controller } from 'react-hook-form'
import {
  Box,
  Card,
  CardBody,
  CardHeader,
  Heading,
  Button,
  CloseButton,
  VStack,
  FormControl,
  FormLabel,
  FormHelperText,
  FormErrorMessage,
  Input,
  Flex,
  Icon,
  Text,
  Badge,
  useColorModeValue,
  HStack,
  Divider,
  SimpleGrid,
  Skeleton,
  SkeletonText,
  useStyleConfig,
  Select,
  Wrap,
  WrapItem,
  IconButton,
  Center,
  InputGroup,
  InputRightElement,
  List,
  ListItem
} from '@chakra-ui/react'
import { AddIcon, CheckIcon, WarningIcon, RepeatIcon, ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'
import { useTranslation } from 'react-i18next'
import { FaRobot } from 'react-icons/fa'
import dayjs from 'dayjs'
import { formatDate } from '../../../utils/dayjs-config'

import { dateToCalendarFormat } from '../../../utils/time'
import { Lesson } from '../../../__data__/model'
import { ErrorSpan } from '../style'
import { api } from '../../../__data__/api/api'
import { useParams } from 'react-router-dom'

const courceNameSuggestion = getFeatures('journal')['courceNameSuggestion']

interface NewLessonForm {
  name: string
  date: string
  time: string
}

interface LessonFormProps {
  lesson?: Partial<Lesson> | any // Разрешаем передавать как Lesson, так и AI-сгенерированный урок
  isLoading: boolean
  onCancel: () => void
  onSubmit: (lesson: Lesson) => void
  error?: string
  title: string
  nameButton: string
  aiSuggestions?: any[] // Список предложений от ИИ 
  isLoadingAiSuggestions?: boolean // Индикатор загрузки предложений
  onSelectAiSuggestion?: (suggestion: any) => void // Обработчик выбора предложения
  selectedAiSuggestion?: any // Выбранное предложение
  onRetryAiGeneration?: () => void // Функция для повторного запуска генерации
  existingLessons?: Array<{ date: string; name: string }> // Добавляем новый проп
}

export const LessonForm = ({
  lesson,
  isLoading,
  onCancel,
  onSubmit,
  error,
  title,
  nameButton,
  aiSuggestions = [],
  isLoadingAiSuggestions = false,
  onSelectAiSuggestion = () => {},
  selectedAiSuggestion,
  onRetryAiGeneration = () => {},
  existingLessons
}: LessonFormProps) => {
  const { courseId } = useParams()
  const { t } = useTranslation()
  const isAiSuggested = lesson && !lesson._id && !lesson.id
  const aiHighlightColor = useColorModeValue('blue.100', 'blue.800')
  const suggestionBgColor = useColorModeValue('blue.50', 'blue.900')
  const suggestionHoverBgColor = useColorModeValue('blue.100', 'blue.800')
  const borderColor = useColorModeValue('blue.200', 'blue.700')
  const textSecondaryColor = useColorModeValue('gray.600', 'gray.400')
  const [suggestions, setSuggestions] = useState<string[]>([])
  const [showSuggestions, setShowSuggestions] = useState(false)
  const [inputValue, setInputValue] = useState('')
  const inputRef = useRef<HTMLInputElement>(null)
  const suggestionsContainerRef = useRef<HTMLDivElement>(null)
  const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null)
  
  const [generateLessonName, {
    data: generateLessonNameData,
    isLoading: isLoadingGenerateLessonName,
    error: errorGenerateLessonName,
    isSuccess: isSuccessGenerateLessonName
  }] = api.useGenerateLessonNameMutation()
  
  // Функция debounce для запросов
  const debouncedGenerateName = useCallback((value: string) => {
    if (debounceTimeoutRef.current) {
      clearTimeout(debounceTimeoutRef.current)
    }
    
    debounceTimeoutRef.current = setTimeout(() => {
      if (value.length > 2) {
        generateLessonName({ courseId: courseId, name: value })
      } else {
        setSuggestions([])
      }
    }, Number(courceNameSuggestion.value) || 300)
  }, [courseId, generateLessonName])

  useEffect(() => {
    if (isSuccessGenerateLessonName) {
      setSuggestions(generateLessonNameData.body.map(suggestion => suggestion.name))
    }
  }, [isSuccessGenerateLessonName])
  
  // Эффект для корректного позиционирования списка подсказок
  useEffect(() => {
    const positionSuggestions = () => {
      if (inputRef.current && suggestionsContainerRef.current && showSuggestions) {
        const inputRect = inputRef.current.getBoundingClientRect()
        suggestionsContainerRef.current.style.top = `${inputRect.bottom + window.scrollY}px`
        suggestionsContainerRef.current.style.left = `${inputRect.left + window.scrollX}px`
        suggestionsContainerRef.current.style.width = `${inputRect.width}px`
      }
    }
    
    positionSuggestions()
    
    // Обновляем позицию при скролле или изменении размера окна
    window.addEventListener('scroll', positionSuggestions)
    window.addEventListener('resize', positionSuggestions)
    
    return () => {
      window.removeEventListener('scroll', positionSuggestions)
      window.removeEventListener('resize', positionSuggestions)
    }
  }, [showSuggestions, suggestions.length])
  
  // Эффект для очистки timeout при размонтировании компонента
  useEffect(() => {
    return () => {
      if (debounceTimeoutRef.current) {
        clearTimeout(debounceTimeoutRef.current)
      }
    }
  }, [])
  
  const getNearestTimeSlot = () => {
    const now = new Date();
    const minutes = now.getMinutes();
    
    if (minutes < 30) {
      // Округляем до начала текущего часа
      now.setMinutes(0, 0, 0);
    } else {
      // Округляем до начала следующего часа
      now.setHours(now.getHours() + 1);
      now.setMinutes(0, 0, 0);
    }
    
    return dateToCalendarFormat(now.toISOString());
  };

  const {
    control,
    handleSubmit,
    reset,
    setValue,
    formState: { errors },
  } = useForm<NewLessonForm>({
    defaultValues: (lesson && {
      ...lesson,
      date: dateToCalendarFormat(lesson.date),
    }) || {
      name: '',
      date: getNearestTimeSlot(),
    },
  })

  // Рендерим скелетон для предложений ИИ
  const renderSkeletons = () => {
    return (
      <VStack spacing={3} align="stretch" mt={4}>
        <Skeleton height="20px" width="70%" />
        <SimpleGrid columns={{ base: 1, md: 2 }} spacing={3}>
          {[1, 2, 3, 4, 5, 6].map(idx => (
            <Skeleton key={idx} height="60px" borderRadius="md" />
          ))}
        </SimpleGrid>
      </VStack>
    )
  }

  // Применяем выбранное предложение к форме
  const handleSelectSuggestion = (suggestion) => {
    setValue('name', suggestion.name)
    setValue('date', dateToCalendarFormat(suggestion.date))
    onSelectAiSuggestion(suggestion)
  }

  // Добавляем новые вспомогательные функции
  const generateTimeSlots = () => {
    const slots = [];
    for (let hour = 8; hour <= 21; hour++) {
      slots.push(`${hour.toString().padStart(2, '0')}:00`);
      slots.push(`${hour.toString().padStart(2, '0')}:30`);
    }
    return slots;
  };

  const timeGroups = {
    [`${t('journal.pl.days.morning')} (8-12)`]: generateTimeSlots().filter(slot => {
      const hour = parseInt(slot.split(':')[0]);
      return hour >= 8 && hour < 12;
    }),
    [`${t('journal.pl.days.day')} (12-17)`]: generateTimeSlots().filter(slot => {
      const hour = parseInt(slot.split(':')[0]);
      return hour >= 12 && hour < 17;
    }),
    [`${t('journal.pl.days.evening')} (17-21)`]: generateTimeSlots().filter(slot => {
      const hour = parseInt(slot.split(':')[0]);
      return hour >= 17 && hour <= 21;
    })
  };

  // Добавляем функцию для получения дня недели
  const getDayOfWeek = (date: Date) => {
    const days = [
      t('journal.pl.days.sunday'),
      t('journal.pl.days.monday'),
      t('journal.pl.days.tuesday'),
      t('journal.pl.days.wednesday'),
      t('journal.pl.days.thursday'),
      t('journal.pl.days.friday'),
      t('journal.pl.days.saturday')
    ];
    return days[date.getDay()];
  };

  // Добавляем вспомогательные функции для календаря
  const getDaysInMonth = (year: number, month: number) => {
    return new Date(year, month + 1, 0).getDate();
  };

  const getFirstDayOfMonth = (year: number, month: number) => {
    return new Date(year, month, 1).getDay();
  };

  const isWeekend = (dayOfWeek: number) => {
    return dayOfWeek === 0 || dayOfWeek === 6; // Воскресенье или суббота
  };

  const isSameDay = (date1: Date, date2: Date) => {
    return date1.getFullYear() === date2.getFullYear() &&
           date1.getMonth() === date2.getMonth() &&
           date1.getDate() === date2.getDate();
  };
  // Компонент календаря
  interface CalendarProps {
    selectedDate: Date;
    onSelectDate: (date: Date) => void;
    existingLessons?: string[];
  }

  const Calendar: React.FC<CalendarProps> = ({ selectedDate, onSelectDate, existingLessons = [] }) => {
    const { t } = useTranslation();
    const [viewDate, setViewDate] = useState(new Date());
    
    // Используем короткие названия дней недели из локализации
    const weekDays = [
      t('journal.pl.days.shortMonday'),
      t('journal.pl.days.shortTuesday'),
      t('journal.pl.days.shortWednesday'),
      t('journal.pl.days.shortThursday'),
      t('journal.pl.days.shortFriday'),
      t('journal.pl.days.shortSaturday'),
      t('journal.pl.days.shortSunday'),
    ];

    // Используем локализованные названия месяцев
    const monthNames = [
      t('journal.pl.months.january'),
      t('journal.pl.months.february'),
      t('journal.pl.months.march'),
      t('journal.pl.months.april'),
      t('journal.pl.months.may'),
      t('journal.pl.months.june'),
      t('journal.pl.months.july'),
      t('journal.pl.months.august'),
      t('journal.pl.months.september'),
      t('journal.pl.months.october'),
      t('journal.pl.months.november'),
      t('journal.pl.months.december'),
    ];

    const daysInMonth = getDaysInMonth(viewDate.getFullYear(), viewDate.getMonth());
    let firstDay = getFirstDayOfMonth(viewDate.getFullYear(), viewDate.getMonth());
    firstDay = firstDay === 0 ? 6 : firstDay - 1; // Корректируем для начала недели с понедельника

    const days = Array.from({ length: 42 }, (_, i) => {
      const dayNumber = i - firstDay + 1;
      if (dayNumber > 0 && dayNumber <= daysInMonth) {
        const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), dayNumber);
        return {
          date,
          dayOfMonth: dayNumber,
          isCurrentMonth: true,
          isWeekend: isWeekend(date.getDay()),
          isToday: isSameDay(date, new Date()),
          isSelected: isSameDay(date, selectedDate)
        };
      }
      return null;
    });

    // Добавим функцию проверки наличия лекции в определенный день
    const hasLessonOnDate = (date: Date) => {
      return existingLessons.some(lessonDate => 
        isSameDay(new Date(lessonDate), date)
      );
    };

    return (
      <Box>
        <Text fontSize="sm" mb={2}>{t('journal.pl.lesson.form.selectDate')}</Text>
        <HStack justify="space-between" mb={2}>
          <IconButton
            aria-label="Previous month"
            icon={<ChevronLeftIcon />}
            size="sm"
            onClick={() => {
              const newDate = new Date(viewDate);
              newDate.setMonth(newDate.getMonth() - 1);
              setViewDate(newDate);
            }}
          />
          <HStack>
            <Select
              size="sm"
              value={viewDate.getMonth()}
              onChange={(e) => {
                const newDate = new Date(viewDate);
                newDate.setMonth(parseInt(e.target.value));
                setViewDate(newDate);
              }}
            >
              {monthNames.map((month, i) => (
                <option key={i} value={i}>{month}</option>
              ))}
            </Select>
            <Select
              size="sm"
              value={viewDate.getFullYear()}
              onChange={(e) => {
                const newDate = new Date(viewDate);
                newDate.setFullYear(parseInt(e.target.value));
                setViewDate(newDate);
              }}
            >
              {Array.from({ length: 5 }, (_, i) => {
                const year = new Date().getFullYear() + i;
                return <option key={year} value={year}>{year}</option>;
              })}
            </Select>
          </HStack>
          <IconButton
            aria-label="Next month"
            icon={<ChevronRightIcon />}
            size="sm"
            onClick={() => {
              const newDate = new Date(viewDate);
              newDate.setMonth(newDate.getMonth() + 1);
              setViewDate(newDate);
            }}
          />
        </HStack>

        <SimpleGrid columns={7} spacing={1}>
          {weekDays.map(day => (
            <Center key={day} py={1}>
              <Text fontSize="xs" color="gray.500">
                {day}
              </Text>
            </Center>
          ))}
          {days.map((day, i) => {
            const hasLesson = day?.isCurrentMonth && hasLessonOnDate(day.date);
            
            return (
              <Button
                key={i}
                size="sm"
                variant={day?.isSelected ? "solid" : "ghost"}
                colorScheme={day?.isSelected ? "blue" : day?.isWeekend ? "red" : "gray"}
                opacity={day?.isCurrentMonth ? 1 : 0}
                onClick={() => day?.date && onSelectDate(day.date)}
                h="32px"
                disabled={!day?.isCurrentMonth}
                position="relative"
                _after={hasLesson ? {
                  content: '""',
                  position: "absolute",
                  bottom: "2px",
                  left: "50%",
                  transform: "translateX(-50%)",
                  width: "4px",
                  height: "4px",
                  borderRadius: "full",
                  bg: day?.isSelected ? "white" : "blue.500",
                  _dark: {
                    bg: day?.isSelected ? "white" : "blue.300"
                  }
                } : undefined}
                title={hasLesson ? t('journal.pl.lesson.existingLessonHint') : undefined}
              >
                <Text
                  fontSize="xs"
                  fontWeight={day?.isToday ? "bold" : "normal"}
                  textDecoration={day?.isToday ? "underline" : "none"}
                >
                  {day?.dayOfMonth}
                </Text>
              </Button>
            );
          })}
        </SimpleGrid>
      </Box>
    );
  };

  return (
    <Card align="left" bg={isAiSuggested ? aiHighlightColor : undefined}>
      <CardHeader display="flex">
        <Flex align="center">
          <Heading as="h2" mt="0">
            {title}
          </Heading>
          {isAiSuggested && (
            <Badge colorScheme="blue" ml={2} display="flex" alignItems="center">
              <Icon as={FaRobot} mr={1} />
              <Text>{t('journal.pl.lesson.aiGenerated')}</Text>
            </Badge>
          )}
        </Flex>
        <CloseButton
          ml="auto"
          onClick={() => {
            reset()
            onCancel()
          }}
        />
      </CardHeader>
      <CardBody>
        <form onSubmit={handleSubmit(onSubmit)}>
          <VStack spacing="10" align="left">
            <Controller
              control={control}
              name="date"
              rules={{ required: t('journal.pl.common.required') }}
              render={({ field }) => {
                const [currentDate = '', currentTime = '00:00:00'] = field.value.split('T');
                const currentTimeShort = currentTime.split(':').slice(0, 2).join(':');
                const selectedDate = new Date(currentDate);
                
                // Получаем существующие лекции из пропсов компонента
                const existingLessons2 = existingLessons?.map(lesson => lesson.date) || [];
                
                return (
                  <FormControl>
                    <FormLabel>{t('journal.pl.lesson.form.date')}</FormLabel>
                    <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
                      {/* Календарь */}
                      <Box>
                        <Calendar
                          selectedDate={selectedDate}
                          existingLessons={existingLessons2}
                          onSelectDate={(date) => {
                            const formattedDate = dateToCalendarFormat(date.toISOString()).split('T')[0];
                            field.onChange(`${formattedDate}T${currentTimeShort}:00`);
                          }}
                        />
                      </Box>

                      {/* Временные слоты */}
                      <Box>
                        <Text fontSize="sm" mb={2}>{t('journal.pl.lesson.form.selectTime')}:</Text>
                        <SimpleGrid columns={1} spacing={4}>
                          {Object.entries(timeGroups).map(([groupName, slots]) => (
                            <Box key={groupName}>
                              <Text fontSize="xs" color="gray.500" mb={1}>
                                {groupName}
                              </Text>
                              <Wrap spacing={1}>
                                {slots.map(slot => {
                                  const isSelected = currentTimeShort === slot;
                                  return (
                                    <WrapItem key={slot}>
                                      <Button
                                        size="xs"
                                        variant={isSelected ? "solid" : "outline"}
                                        colorScheme="blue"
                                        onClick={() => {
                                          field.onChange(`${currentDate}T${slot}:00`);
                                        }}
                                        h="24px"
                                        minW="54px"
                                      >
                                        {slot}
                                      </Button>
                                    </WrapItem>
                                  );
                                })}
                              </Wrap>
                            </Box>
                          ))}
                        </SimpleGrid>
                      </Box>
                    </SimpleGrid>
                  </FormControl>
                );
              }}
            />

            <Controller
              control={control}
              name="name"
              rules={{ required: t('journal.pl.common.required') }}
              render={({ field }) => (
                <FormControl isRequired isInvalid={Boolean(errors.name)}>
                  <FormLabel>{t('journal.pl.lesson.form.title')}</FormLabel>
                  <Box position="relative">
                    <InputGroup>
                      <Input
                        {...field}
                        ref={inputRef}
                        required={false}
                        placeholder={t('journal.pl.lesson.form.namePlaceholder')}
                        size="md"
                        onChange={(e) => {
                          const value = e.target.value
                          setInputValue(value)
                          field.onChange(value)
                          if (value.length > 2 && courceNameSuggestion) {
                            setShowSuggestions(true)
                            debouncedGenerateName(value)
                          } else {
                            setSuggestions([])
                          }
                        }}
                        onFocus={() => setShowSuggestions(true)}
                        onBlur={() => setTimeout(() => setShowSuggestions(false), 200)}
                      />
                    </InputGroup>
                  </Box>
                  {errors.name && (
                    <FormErrorMessage>{errors.name.message}</FormErrorMessage>
                  )}
                </FormControl>
              )}
            />
            <Box mt="10">
              <Button
                size="lg"
                type="submit"
                leftIcon={isAiSuggested ? <Icon as={FaRobot} /> : <AddIcon />}
                colorScheme={isAiSuggested ? "blue" : "blue"}
                isLoading={isLoading}
              >
                {nameButton}
              </Button>
            </Box>
          </VStack>

          {error && <ErrorSpan>{error}</ErrorSpan>}
        </form>

        {/* Блок с предложениями ИИ */}
        {((Array.isArray(aiSuggestions) && aiSuggestions.length > 0) || isLoadingAiSuggestions || typeof aiSuggestions === 'string') && (
          <>
            <Divider my={6} />
            
            <Flex align="center" mb={4}>
              <Icon as={FaRobot} color="blue.500" mr={2} />
              <Heading size="sm" color="blue.500">
                {t('journal.pl.lesson.aiSuggested')}
              </Heading>
              {!isLoadingAiSuggestions && Array.isArray(aiSuggestions) && (
                <Badge colorScheme="blue" ml={2}>
                  {aiSuggestions.length} {t('journal.pl.common.lesson').toLowerCase()}
                </Badge>
              )}
            </Flex>
            
            {isLoadingAiSuggestions ? (
              renderSkeletons()
            ) : typeof aiSuggestions === 'string' ? (
              <Box 
                p={4} 
                bg={useColorModeValue('red.50', 'red.900')} 
                color={useColorModeValue('red.600', 'red.200')}
                borderRadius="md"
                borderLeft="3px solid"
                borderLeftColor="red.500"
              >
                <Flex align="center" mb={2}>
                  <Icon as={WarningIcon} color="red.500" mr={2} />
                  <Text fontWeight="bold">{t('journal.pl.lesson.aiGenerationError')}</Text>
                </Flex>
                <Text fontSize="sm" mb={3}>{t('journal.pl.lesson.tryAgainLater')}</Text>
                <Button 
                  size="sm" 
                  colorScheme="red" 
                  variant="outline"
                  leftIcon={<RepeatIcon />}
                  onClick={onRetryAiGeneration}
                  isLoading={isLoadingAiSuggestions}
                >
                  {t('journal.pl.lesson.retryGeneration')}
                </Button>
              </Box>
            ) : (
              <>
                <Text fontSize="sm" color={textSecondaryColor} mb={4}>
                  {t('journal.pl.lesson.aiSuggestedDescription')}
                </Text>
                
                <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
                  {aiSuggestions.map((suggestion, index) => {
                    const isSelected = selectedAiSuggestion && 
                      selectedAiSuggestion.name === suggestion.name && 
                      selectedAiSuggestion.date === suggestion.date;
                      
                    return (
                      <Box 
                        key={`ai-suggestion-${index}`}
                        bg={isSelected ? suggestionHoverBgColor : suggestionBgColor}
                        p={3}
                        borderRadius="md"
                        borderLeft="3px solid"
                        borderLeftColor={isSelected ? "green.400" : borderColor}
                        cursor="pointer"
                        onClick={() => handleSelectSuggestion(suggestion)}
                        transition="all 0.2s"
                        _hover={{ 
                          bg: suggestionHoverBgColor,
                          transform: 'translateY(-2px)',
                          boxShadow: 'sm'
                        }}
                      >
                        <Flex justify="space-between" align="center" mb={1}>
                          <HStack>
                            <Icon as={FaRobot} color="blue.500" boxSize="3" />
                            <Text fontWeight="bold">{suggestion.name}</Text>
                          </HStack>
                          {isSelected && <CheckIcon color="green.400" />}
                        </Flex>
                        <Text fontSize="sm" color={textSecondaryColor}>
                          {formatDate(suggestion.date, 'DD.MM.YYYY HH:mm')}
                        </Text>
                      </Box>
                    );
                  })}
                </SimpleGrid>
              </>
            )}
          </>
        )}
      </CardBody>

      {/* Выпадающий список подсказок (размещаем вне стандартного потока документа) */}
      {suggestions.length > 0 && showSuggestions && (
        <Box
          position="fixed"
          ref={suggestionsContainerRef}
          bg={useColorModeValue('white', 'gray.800')}
          borderRadius="md"
          boxShadow="md"
          zIndex={9999}
          maxH="200px"
          overflowY="auto"
        >
          <List>
            {suggestions.map((suggestion, index) => (
              <ListItem
                key={index}
                p={2}
                cursor="pointer"
                _hover={{ bg: useColorModeValue('gray.100', 'gray.700') }}
                onClick={() => {
                  setValue('name', suggestion)
                  setInputValue(suggestion)
                  setSuggestions([])
                  setShowSuggestions(false)
                }}
              >
                {suggestion}
              </ListItem>
            ))}
          </List>
        </Box>
      )}
    </Card>
  )
}
