import React, { useCallback, useEffect, useRef, useState } from 'react'
import dayjs from 'dayjs'
import { Link as ConnectedLink } from 'react-router-dom'
import { getNavigationsValue } from '@brojs/cli'
import {
  Box,
  CardHeader,
  CardBody,
  CardFooter,
  ButtonGroup,
  Stack,
  StackDivider,
  Button,
  Card,
  Heading,
  Tooltip,
  Spinner,
  Container,
  VStack,
  Link,
  Input,
  CloseButton,
  FormControl,
  FormLabel,
  FormHelperText,
  Center,
  FormErrorMessage,
  useToast,
} from '@chakra-ui/react'
import { useForm, Controller } from 'react-hook-form'

import { ErrorSpan } from './style'

import { useAppSelector } from '../__data__/store'
import { api } from '../__data__/api/api'
import { isTeacher } from '../utils/user'
import { AddIcon, ArrowDownIcon, ArrowUpIcon, LinkIcon } from '@chakra-ui/icons'
import { Course } from '../__data__/model'

interface NewCourseForm {
  startDt: string
  name: string
}

const CoursesList = () => {
  const toast = useToast()
  const user = useAppSelector((s) => s.user)
  const { data, isLoading } = api.useCoursesListQuery()
  const [createUpdateCourse, crucQuery] = api.useCreateUpdateCourseMutation()
  const [showForm, setShowForm] = useState(false)
  const [courseDetailsOpenedId, setCourseDetailsOpenedId] = useState<
    string | null
  >(null)
  const toastRef = useRef(null)

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors },
    getValues,
  } = useForm<NewCourseForm>({
    defaultValues: {
      startDt: '',
      name: '',
    },
  })

  const onSubmit = ({ startDt, name }) => {
    toastRef.current = toast({
      title: 'Отправляем',
      status: 'loading',
      duration: 9000,
    })
    createUpdateCourse({ name, startDt })
  }

  useEffect(() => {
    if (crucQuery.isSuccess) {
      const values = getValues()
      if (toastRef.current) {
        toast.update(toastRef.current, {
          title: 'Курс создан.',
          description: `Курс ${values.name} успешно создан`,
          status: 'success',
          duration: 9000,
          isClosable: true,
        })
      }
      reset()
    }
  }, [crucQuery.isSuccess])

  if (isLoading) {
    return (
      <Container maxW="container.xl">
        <Center h="300px">
          <Spinner
            thickness="4px"
            speed="0.65s"
            emptyColor="gray.200"
            color="blue.500"
            size="xl"
          />
        </Center>
      </Container>
    )
  }

  return (
    <Container maxW="container.xl">
      {isTeacher(user) && (
        <Box mt="15" mb="15">
          {showForm ? (
            <Card align="left">
              <CardHeader display="flex">
                <Heading as="h2" mt="0">
                  Создание курса
                </Heading>
                <CloseButton ml="auto" onClick={() => setShowForm(false)} />
              </CardHeader>
              <CardBody>
                <form onSubmit={handleSubmit(onSubmit)}>
                  <VStack spacing={10} align="left">
                    <Controller
                      control={control}
                      name="startDt"
                      rules={{ required: 'Обязательное поле' }}
                      render={({ field }) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(errors.startDt)}
                        >
                          <FormLabel>Дата начала</FormLabel>
                          <Input
                            {...field}
                            required={false}
                            placeholder="Select Date and Time"
                            size="md"
                            type="date"
                          />
                          {errors.startDt ? (
                            <FormErrorMessage>
                              {errors.startDt?.message}
                            </FormErrorMessage>
                          ) : (
                            <FormHelperText>
                              Укажите дату начала курса
                            </FormHelperText>
                          )}
                        </FormControl>
                      )}
                    />
                    <Controller
                      control={control}
                      name="name"
                      rules={{
                        required: 'Обязательное поле',
                      }}
                      render={({ field }) => (
                        <FormControl
                          isRequired
                          isInvalid={Boolean(errors.name)}
                        >
                          <FormLabel>Название новой лекции:</FormLabel>
                          <Input
                            {...field}
                            required={false}
                            placeholder="КФУ-24-2"
                            size="md"
                          />
                          {errors.name && (
                            <FormErrorMessage>
                              {errors.name.message}
                            </FormErrorMessage>
                          )}
                        </FormControl>
                      )}
                    />

                    <Box mt={10}>
                      <Button
                        size="lg"
                        type="submit"
                        leftIcon={<AddIcon />}
                        colorScheme="blue"
                      >
                        Создать
                      </Button>
                    </Box>
                  </VStack>

                  {crucQuery?.error && (
                    <ErrorSpan>{(crucQuery?.error as any).error}</ErrorSpan>
                  )}
                </form>
              </CardBody>
            </Card>
          ) : (
            <Box p="2" m="2">
              <Button
                leftIcon={<AddIcon />}
                colorScheme="green"
                onClick={() => setShowForm(true)}
              >
                Добавить
              </Button>
            </Box>
          )}
        </Box>
      )}
      <VStack as="ul" align="stretch">
        {data?.body?.map((c) => (
          <CourseCard
            isOpened={courseDetailsOpenedId === c._id}
            key={c._id}
            course={c}
            openDetails={() =>
              courseDetailsOpenedId === c._id
                ? setCourseDetailsOpenedId(null)
                : setCourseDetailsOpenedId(c._id)
            }
          />
        ))}
      </VStack>
    </Container>
  )
}

const CourseCard = ({
  course,
  isOpened,
  openDetails,
}: {
  course: Course
  isOpened: boolean
  openDetails: () => void
}) => {
  const [getLessonList, lessonList] = api.useLazyLessonListQuery()
  useEffect(() => {
    if (isOpened) {
      getLessonList(course._id, true)
    }
  }, [isOpened])
  const user = useAppSelector((s) => s.user)

  return (
    <Card key={course._id} align="left">
      <CardHeader>
        <Heading as="h2" mt="0">
          {course.name}
        </Heading>
      </CardHeader>
      {isOpened && (
        <CardBody mt="16px">
          <Stack divider={<StackDivider />} spacing="8px">
            <Box as="span" textAlign="left">
              {`Дата начала курса - ${dayjs(course.startDt).format('DD MMMM YYYYг.')}`}
            </Box>
            <Box as="span" textAlign="left">
              Количество занятий - {course.lessons.length}
            </Box>
            {lessonList.isFetching ? (
              <Spinner />
            ) : (
              <>
                <Heading as="h3" mt={4} mb={3} size="lg">
                  Список занятий:
                </Heading>
                <Stack>
                  {lessonList.data?.body?.map((lesson) => (
                    <Link
                      as={ConnectedLink}
                      key={lesson._id}
                      to={
                        isTeacher(user)
                          ? `${getNavigationsValue('journal.main')}/lesson/${course._id}/${lesson._id}`
                          : ''
                      }
                    >
                      {lesson.name}
                    </Link>
                  ))}
                </Stack>
              </>
            )}
          </Stack>
        </CardBody>
      )}
      <CardFooter>
        <ButtonGroup spacing="4" mt="16px">
          <Tooltip label="На страницу с лекциями" fontSize="12px" top="16px">
            <Button
              leftIcon={<LinkIcon />}
              as={ConnectedLink}
              colorScheme="blue"
              to={`${getNavigationsValue('journal.main')}/lessons-list/${course._id}`}
            >
              Открыть
            </Button>
          </Tooltip>
          <Tooltip label="Детали" fontSize="12px" top="16px">
            <Button
              colorScheme="blue"
              variant="outline"
              leftIcon={isOpened ? <ArrowUpIcon /> : <ArrowDownIcon />}
              loadingText="Загрузка"
              isLoading={lessonList.isFetching}
              onClick={openDetails}
            >
              Просмотреть детали
            </Button>
          </Tooltip>
        </ButtonGroup>
      </CardFooter>
    </Card>
  )
}

export default CoursesList
