'use client'

import { getAreas } from '@/api/areas'
import { getAudiences } from '@/api/audiences'
import { getCategories } from '@/api/categories'
import { createCourses } 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 } from 'date-fns'
import { CalendarIcon, Trash2 } from 'lucide-react'
import { useRouter } from 'next/navigation'
import { 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.string().nullable(),
  mobileBanner: z.string().nullable(),
  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 [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: {
      areaId: '',
      professors: [],
      moduleIds: [],
      desktopBanner: null,
      mobileBanner: null,
    },
  })
  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,
  })

  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 handleDelete = (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)
  }

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

  async function onSubmit(data: z.infer<typeof FormSchema>) {
    if (!desktopBanner) {
      form.setError('desktopBanner', {
        type: 'manual',
        message: 'Foto desktop obrigatória!',
      })
      return
    }
    if (!mobileBanner) {
      form.setError('mobileBanner', {
        type: 'manual',
        message: 'Foto mobile obrigatória!',
      })
      return
    }
    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,
      startDate: dateStart ? format(dateStart, 'yyyy-MM-dd') : '',
      endDate: dateEnd ? format(dateEnd, 'yyyy-MM-dd') : '',
      desktopBanner: urlCapaDesktop,
      mobileBanner: urlCapaMobile,
      workload: Number(data.workload),
    }

    mutationCreateCourse.mutateAsync(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
  }

  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')}
                sx={StyledInputs(
                  form.formState.errors.name
                    ? { color: '#dc2626' }
                    : { color: '#26AAA7' },
                )}
              />

              <TextField
                type="text"
                variant="standard"
                label="Área"
                select
                defaultValue={''}
                {...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"
                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={() => handleDelete(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 ? 'Adicionar 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 ? 'Adicionar 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"
                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} />
                    <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={setDateStart}
                            initialFocus
                            {...form.register('startDate')}
                          />
                        </PopoverContent>
                      </Popover>
                    </div>
                  )}
                </div>
                <div className="flex justify-between items-center">
                  <div className="flex items-center gap-2">
                    <Checkbox id="end" onCheckedChange={onCheckedEnd} />
                    <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={setDateEnd}
                            initialFocus
                            {...form.register('endDate')}
                          />
                        </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
                        onValueChange={field.onChange}
                        defaultValue={field.value}
                        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
                        onValueChange={field.onChange}
                        defaultValue={field.value}
                        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>
  )
}
