'use client'

import { getAreas } from '@/api/areas'
import { getAudiences } from '@/api/audiences'
import { getCategories } from '@/api/categories'
import { editCourseId, getCourseId } from '@/api/courses'
import { createModules, getModules, ModulesProps } from '@/api/modules'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import InputFile from '@/components/input-file'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { Button } from '@/components/ui/button'
import { Calendar } from '@/components/ui/calendar'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
} from '@/components/ui/form'
import { Label } from '@/components/ui/label'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { Separator } from '@/components/ui/separator'
import { cn } from '@/lib/utils'
import { zodResolver } from '@hookform/resolvers/zod'
import { Box, Chip, MenuItem, TextField } from '@mui/material'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { AxiosError } from 'axios'
import { format, parseISO } from 'date-fns'
import { toZonedTime } from 'date-fns-tz'
import { CalendarIcon, Trash2 } from 'lucide-react'
import { useParams, useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { z } from 'zod'

const FormSchema = z.object({
  name: z.string().trim().min(3, { message: 'Título obrigatório' }),
  description: z.string().trim().min(3, { message: 'Descrição obrigatória' }),
  desktopBanner: z.any(),
  mobileBanner: z.any(),
  startDate: z.date().optional(),
  endDate: z.date().optional(),
  professors: z.string().array(),
  workload: z.string().trim().min(1, { message: 'Horas do curso necessário' }),
  areaId: z.string().trim().min(1, { message: 'Selecione a área' }),
  audienceId: z.string(),
  categoryId: z.string(),
  moduleIds: z.string().array(),
})

export default function Curso() {
  const params = useParams<{ id: string }>()

  const [checkedStart, setCheckedStart] = useState<boolean>(false)
  const [checkedEnd, setCheckedEnd] = useState<boolean>(false)
  const [dateStart, setDateStart] = useState<Date>()
  const [dateEnd, setDateEnd] = useState<Date>()
  const [inputValue, setInputValue] = useState<string>('')
  const [desktopBanner, setDesktopBanner] = useState<File | null>(null)
  const [mobileBanner, setMobileBanner] = useState<File | null>(null)

  const router = useRouter()
  const queryClient = useQueryClient()

  const { register, handleSubmit } = useForm<ModulesProps>()
  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      professors: [],
      moduleIds: [],
      desktopBanner: '',
      mobileBanner: '',
    },
  })

  const { data: course, isLoading } = useQuery({
    queryKey: ['course', params.id],
    queryFn: () => getCourseId(params.id),
    enabled: !!params.id,
  })

  const formatDate = (dateString: string) => {
    const date = parseISO(dateString)
    const utcDate = toZonedTime(date, 'UTC')
    return utcDate
  }

  useEffect(() => {
    if (course && course.data.startDate) {
      setCheckedStart(true)

      onCheckedStart(!!course.data.startDate)
    }
    if (course && course.data.endDate) {
      setCheckedEnd(true)

      onCheckedEnd(!!course.data.endDate)
    }
  }, [course])

  useEffect(() => {
    if (!course?.data) return

    const { modules, professors, category, audience, startDate, endDate } =
      course.data

    if (modules) {
      const existingModuleIds = modules.map((mod) => mod.module.id)
      form.setValue('moduleIds', existingModuleIds)
    }
    if (professors) {
      const existingTeachers = professors.map((teacher) => teacher)
      form.setValue('professors', existingTeachers)
    }
    if (category) {
      form.setValue('categoryId', category.id)
    }
    if (audience) {
      form.setValue('audienceId', audience.id)
    }

    if (startDate) {
      const date = formatDate(startDate)
      form.setValue('startDate', date)
      setDateStart(date)
    }
    if (endDate) {
      const date = formatDate(endDate)
      form.setValue('endDate', date)
      setDateEnd(date)
    }
  }, [course, form])

  const values = form.watch()

  const { data: areas } = useQuery({
    queryKey: ['areas'],
    queryFn: getAreas,
  })

  const { data: modules } = useQuery({
    queryKey: ['modules'],
    queryFn: getModules,
  })

  const { data: audiences, isLoading: audiencesLoading } = useQuery({
    queryKey: ['audiences'],
    queryFn: getAudiences,
  })

  const { data: categories, isLoading: categoriesLoading } = useQuery({
    queryKey: ['categories'],
    queryFn: getCategories,
  })

  const mutationEdit = useMutation({
    mutationFn: editCourseId,
    onSuccess: () => {
      toast.success('Curso editada com sucesso!')
      queryClient.invalidateQueries({ queryKey: ['courses'] })
      router.push('/admin')
    },
    onError: (error) => {
      if (error instanceof AxiosError) {
        const { message } = error.response?.data
        toast.error(`${message}`)
      }
    },
  })

  function onCheckedStart(checkedStart: boolean) {
    setCheckedStart(checkedStart)
  }

  function onCheckedEnd(checkedEnd: boolean) {
    setCheckedEnd(checkedEnd)
  }

  const handleKeyDown = (event: React.KeyboardEvent) => {
    if (event.key === 'Enter' && inputValue.trim()) {
      event.preventDefault()
      form.setValue('professors', [...values.professors, inputValue.trim()])
      setInputValue('')
    }
  }

  const handleDeleteTeacher = (professorToDelete: string) => {
    form.setValue(
      'professors',
      values.professors.filter((str) => str !== professorToDelete),
    )
  }

  const mutation = useMutation({
    mutationFn: createModules,
    onSuccess: () => {
      toast.success('Módulo criado com sucesso!')
      queryClient.invalidateQueries({ queryKey: ['modules'] })
    },
  })

  const selectedModuleIds = form.watch('moduleIds') || []

  async function addNewModuler(data: ModulesProps) {
    const response = await mutation.mutateAsync(data)
    const responseModuleId = response.data.id

    form.setValue('moduleIds', [...selectedModuleIds, responseModuleId])
  }

  const selectedModules = modules?.data.filter((module) =>
    selectedModuleIds.includes(module.id),
  )

  const handleSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedId = event.target.value

    if (selectedId && !selectedModuleIds.includes(selectedId)) {
      form.setValue('moduleIds', [...selectedModuleIds, selectedId])
    }
  }

  const handleDeleteModule = (idToRemove: string) => {
    const updatedIds = selectedModuleIds.filter((id) => id !== idToRemove)

    form.setValue('moduleIds', updatedIds)
  }

  async function onSubmit(data: z.infer<typeof FormSchema>) {
    if (!dateStart) {
      form.setError('startDate', {
        type: 'manual',
        message: 'Data de início obrigatória!',
      })
      return
    }
    if (!dateEnd) {
      form.setError('endDate', {
        type: 'manual',
        message: 'Data de fim obrigatória!',
      })
      return
    }

    const urlCapaDesktop = await handleUpload(desktopBanner)
    const urlCapaMobile = await handleUpload(mobileBanner)

    const body = {
      ...data,
      id: params.id,
      startDate: dateStart ? format(dateStart, 'yyyy-MM-dd') : '',
      endDate: dateEnd ? format(dateEnd, 'yyyy-MM-dd') : '',
      desktopBanner: urlCapaDesktop,
      mobileBanner: urlCapaMobile,
      workload: Number(data.workload),
    }
    mutationEdit.mutate(body)
  }

  const handleUpload = async (file: File | null) => {
    if (!file) return

    const formData = new FormData()
    formData.append('file', file)

    const res = await fetch('/api/upload', {
      method: 'POST',
      body: formData,
    })

    const data = await res.json()
    return data.url
  }

  console.log('error: ', form.formState.errors)

  if (isLoading) {
    return <p>Carregando...</p>
  }

  return (
    <section className="container py-10">
      <BreadcrumbComponent page="Curso" />
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)}>
          <div className="flex items-center gap-6">
            <h1 className="text-3xl font-bold">Criar curso</h1>
            <Button type="submit" variant="secondary" className="uppercase">
              Salvar e publicar
            </Button>
          </div>
          <div className="flex w-full mt-10">
            <div className="flex-1 flex flex-col border-r border-gray-50 pr-6 space-y-4">
              <h6 className="text-xl text-purple-100">
                Informações sobre o curso
              </h6>

              <TextField
                label="Nome do curso"
                variant="standard"
                type="text"
                {...form.register('name')}
                defaultValue={course?.data.name}
                sx={StyledInputs(
                  form.formState.errors.name
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              />

              <TextField
                type="text"
                variant="standard"
                label="Área"
                select
                defaultValue={course?.data.area.id || ''}
                {...form.register('areaId')}
                sx={StyledInputs(
                  form.formState.errors.areaId
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              >
                <MenuItem value="" className="hidden">
                  Selecione a área
                </MenuItem>
                {areas?.data.map((option) => (
                  <MenuItem key={option.id} value={option.id}>
                    {option.name}
                  </MenuItem>
                ))}
              </TextField>

              <TextField
                label="Descrição do Curso"
                variant="standard"
                type="text"
                defaultValue={course?.data.description}
                multiline
                rows={4}
                {...form.register('description')}
                sx={StyledInputs(
                  form.formState.errors.description
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              />

              <Controller
                control={form.control}
                name="professors"
                render={({ field }) => (
                  <Box
                    sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}
                  >
                    <TextField
                      label="Digite os nomes dos professores e pressione Enter"
                      value={inputValue}
                      onChange={(e) => setInputValue(e.target.value)}
                      onKeyDown={handleKeyDown}
                      variant="standard"
                      sx={StyledInputs({ color: '#26AAA7' })}
                    />
                    <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
                      {field.value.map((str, index) => (
                        <Chip
                          key={index}
                          label={str}
                          onDelete={() => handleDeleteTeacher(str)}
                          variant="outlined"
                          color="secondary"
                          sx={{ color: 'white' }}
                        />
                      ))}
                    </Box>
                  </Box>
                )}
              />

              <div className="flex justify-between flex-wrap gap-6 py-6">
                <div className="flex flex-col flex-1 mt-6">
                  <h6
                    className={cn(
                      'text-xl text-purple-100',
                      form.formState.errors.desktopBanner && 'text-red-600',
                    )}
                  >
                    Capa do curso desktop
                  </h6>
                  <span className="mt-4">
                    Dimensões recomendadas: 348 x 464
                  </span>
                  <span>Formatos aceitos: .png, .jpg</span>

                  <InputFile
                    id="desktopBanner"
                    label={
                      !desktopBanner ? 'Atualizar capa' : desktopBanner.name
                    }
                    onChange={(e) =>
                      setDesktopBanner(e.target.files?.[0] || null)
                    }
                  />
                </div>
                <div className="flex flex-col flex-1 mt-6">
                  <h6
                    className={cn(
                      'text-xl text-purple-100',
                      form.formState.errors.mobileBanner && 'text-red-600',
                    )}
                  >
                    Capa do curso mobile
                  </h6>
                  <span className="mt-4">
                    Dimensões recomendadas: 348 x 464
                  </span>
                  <span>Formatos aceitos: .png, .jpg</span>
                  <InputFile
                    id="mobileBanner"
                    label={!mobileBanner ? 'Atualizar capa' : mobileBanner.name}
                    onChange={(e) =>
                      setMobileBanner(e.target.files?.[0] || null)
                    }
                  />
                </div>
              </div>

              <Separator className="!mt-10 !mb-4" />
              <h6 className="text-xl text-purple-100 mb-4">Horas</h6>
              <TextField
                label="Total de horas do curso"
                variant="standard"
                defaultValue={course?.data.workload}
                type="number"
                {...form.register('workload')}
                sx={StyledInputs(
                  form.formState.errors.workload
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              />

              <Separator className="!mt-10 !mb-4" />
              <h6 className="text-xl text-purple-100 mb-4">Datas</h6>
              <div className="flex flex-col space-y-6">
                <div className="flex justify-between items-center">
                  <div className="flex items-center gap-2">
                    <Checkbox
                      id="start"
                      onCheckedChange={onCheckedStart}
                      checked={checkedStart}
                    />
                    <label
                      htmlFor="start"
                      className={cn(
                        'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
                        form.formState.errors.startDate && 'text-red-600',
                      )}
                    >
                      Definir data de início
                    </label>
                  </div>
                  {checkedStart && (
                    <div className="flex flex-col">
                      <Label>Data de início</Label>
                      <Popover>
                        <PopoverTrigger asChild>
                          <Button
                            variant={'ghost'}
                            type="button"
                            className={cn(
                              'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
                              !dateStart && 'text-muted-foreground',
                            )}
                          >
                            {dateStart ? (
                              format(dateStart, 'dd/MM/yyyy')
                            ) : (
                              <span className="text-gray-600">MM/DD/YYYY</span>
                            )}
                            <CalendarIcon className="ml-auto h-4 w-4 text-green-400" />
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent className="w-auto p-0">
                          <Calendar
                            mode="single"
                            selected={dateStart}
                            onSelect={(date) => {
                              if (date) {
                                setDateStart(date)
                                form.setValue('startDate', date)
                              }
                            }}
                            initialFocus
                          />
                        </PopoverContent>
                      </Popover>
                    </div>
                  )}
                </div>
                <div className="flex justify-between items-center">
                  <div className="flex items-center gap-2">
                    <Checkbox
                      id="end"
                      onCheckedChange={onCheckedEnd}
                      checked={checkedEnd}
                    />
                    <label
                      htmlFor="closure"
                      className={cn(
                        'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
                        form.formState.errors.endDate && 'text-red-600',
                      )}
                    >
                      Definir data de encerramento
                    </label>
                  </div>
                  {checkedEnd && (
                    <div className="flex flex-col">
                      <Label>Data de encerramento</Label>
                      <Popover>
                        <PopoverTrigger asChild>
                          <Button
                            variant={'ghost'}
                            type="button"
                            className={cn(
                              'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
                              !dateEnd && 'text-muted-foreground',
                            )}
                          >
                            {dateEnd ? (
                              format(dateEnd, 'dd/MM/yyyy')
                            ) : (
                              <span className="text-gray-600">MM/DD/YYYY</span>
                            )}
                            <CalendarIcon className="ml-auto h-4 w-4 text-green-400" />
                          </Button>
                        </PopoverTrigger>
                        <PopoverContent className="w-auto p-0">
                          <Calendar
                            mode="single"
                            selected={dateEnd}
                            onSelect={(date) => {
                              if (date) {
                                setDateEnd(date)
                                form.setValue('endDate', date)
                              }
                            }}
                            initialFocus
                          />
                        </PopoverContent>
                      </Popover>
                    </div>
                  )}
                </div>
              </div>

              <Separator className="!mt-10 !mb-4" />

              <h6 className="text-xl text-purple-100 mb-4">Módulos</h6>

              <TextField
                type="text"
                variant="standard"
                label="Selecione os módulos do curso"
                select
                defaultValue={''}
                value=""
                onChange={handleSelect}
                // {...form.register('moduleIds')}
                sx={StyledInputs(
                  form.formState.errors.moduleIds
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              >
                <MenuItem value="" className="hidden">
                  Selecione os módulos
                </MenuItem>
                {modules?.data.map((option) => (
                  <MenuItem key={option.id} value={option.id}>
                    {option.name}
                  </MenuItem>
                ))}
                {!modules?.data.length && <p>Não há módulo criado!</p>}
              </TextField>

              {selectedModules?.map((item) => (
                <div
                  key={item.id}
                  className="w-full flex justify-between bg-green-800/30 py-2 px-4 rounded-sm"
                >
                  <p>{item.name}</p>
                  <Trash2
                    className="cursor-pointer text-red-400 hover:text-red-100"
                    onClick={() => handleDeleteModule(item.id)}
                  />
                </div>
              ))}

              <div className="flex flex-col p-4 gap-6 border border-gray-100">
                <TextField
                  label="Título"
                  variant="standard"
                  type="text"
                  sx={StyledInputs({ color: '#26AAA7' })}
                  {...register('name')}
                />

                <TextField
                  label="Descrição"
                  variant="standard"
                  type="text"
                  multiline
                  rows={4}
                  sx={StyledInputs({ color: '#26AAA7' })}
                  {...register('description')}
                />
              </div>

              <Button
                variant="third"
                type="button"
                className="uppercase w-52 flex items-center gap-2 !mt-8"
                onClick={handleSubmit(addNewModuler)}
              >
                <span>Criar novo Módulo</span>
              </Button>
            </div>

            <div className="w-[380px] pl-6 flex flex-col gap-4">
              <h6 className="text-xl text-purple-100 mb-4">
                Qual o público alvo?
              </h6>
              {audiencesLoading && <LoadingSpinIcon className="ml-10" />}
              <div className="flex items-center gap-2 ml-4">
                <FormField
                  control={form.control}
                  name="audienceId"
                  render={({ field }) => (
                    <FormControl>
                      <RadioGroup
                        value={field.value}
                        onValueChange={field.onChange}
                        className="flex flex-col space-y-4"
                      >
                        {audiences?.data.map((audience) => (
                          <FormItem
                            className="flex items-center space-x-3 space-y-0"
                            key={audience.id}
                          >
                            <FormControl>
                              <RadioGroupItem value={audience.id} />
                            </FormControl>
                            <FormLabel className="font-normal">
                              {audience.name}
                            </FormLabel>
                          </FormItem>
                        ))}
                      </RadioGroup>
                    </FormControl>
                  )}
                />
              </div>
              <h6 className="text-xl text-purple-100 my-4">
                Qual o tipo de curso?
              </h6>
              {categoriesLoading && <LoadingSpinIcon className="ml-10" />}
              <div className="flex items-center gap-2 ml-4">
                <FormField
                  control={form.control}
                  name="categoryId"
                  render={({ field }) => (
                    <FormControl>
                      <RadioGroup
                        value={field.value}
                        onValueChange={field.onChange}
                        className="flex flex-col space-y-4"
                      >
                        {categories?.data.map((category) => (
                          <FormItem
                            className="flex items-center space-x-3 space-y-0"
                            key={category.id}
                          >
                            <FormControl>
                              <RadioGroupItem value={category.id} />
                            </FormControl>
                            <FormLabel className="font-normal">
                              {category.name}
                            </FormLabel>
                          </FormItem>
                        ))}
                      </RadioGroup>
                    </FormControl>
                  )}
                />
              </div>
            </div>
          </div>
        </form>
      </Form>
    </section>
  )
}
