'use client'
import Image from 'next/image'
import { useForm } from 'react-hook-form'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from '@/components/ui/select'
import {
  Form,
  FormField,
  FormControl,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import GenderInput from '@/components/features/genderInput'
import { zodResolver } from '@hookform/resolvers/zod'
import * as z from 'zod'
import { Gender } from '@/types/user'
import { useEffect, useState } from 'react'
import dayjs from 'dayjs'
import { useCheckNickname, useCompleteUser, useCurrentUser } from '@/hooks/auth'
import { useRouter, useSearchParams } from 'next/navigation'

const currentYear = dayjs().year()
const years = Array.from({ length: currentYear - 1950 + 1 }, (_, i) => `${1950 + i}`)
const months = Array.from({ length: 12 }, (_, i) => `${i + 1}`.padStart(2, '0'))
const monthTexts = Array.from({ length: 12 }, (_, i) => dayjs().month(i).format('MMM'))

function getDaysInMonth(year: string, month: string) {
  return Array.from({ length: dayjs(`${year}-${month}`).daysInMonth() }, (_, i) =>
    `${i + 1}`.padStart(2, '0')
  )
}

function calculateAge(year: string, month: string, day: string) {
  const birthDate = dayjs(`${year}-${month}-${day}`)
  const today = dayjs()
  return today.diff(birthDate, 'year')
}

const schema = z
  .object({
    nickname: z
      .string()
      .trim()
      .min(1, 'Please Enter nickname')
      .min(2, 'Nickname must be between 2 and 20 characters'),
    gender: z.enum(Gender, { message: 'Please select your gender' }),
    year: z.string().min(1, 'Please select your birthday'),
    month: z.string().min(1, 'Please select your birthday'),
    day: z.string().min(1, 'Please select your birthday'),
  })
  .refine(
    (data) => {
      const age = calculateAge(data.year, data.month, data.day)
      return age >= 18
    },
    {
      message: 'Character age must be at least 18 years old',
      path: ['year'],
    }
  )

type FormValues = z.infer<typeof schema>

export default function FieldsPage() {
  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      nickname: '',
      gender: undefined,
      year: '2000',
      month: '01',
      day: '01',
    },
    mode: 'all',
  })
  const { mutateAsync } = useCompleteUser()
  const { data: user, refetch } = useCurrentUser()
  const router = useRouter()
  const searchParams = useSearchParams()
  const redirect = searchParams.get('redirect')
  const [loading, setLoading] = useState(false)

  const { mutateAsync: checkNickname } = useCheckNickname({
    onError: (error) => {
      form.setError('nickname', {
        message: error.errorMsg,
      })
    },
  })

  const selectedYear = form.watch('year')
  const selectedMonth = form.watch('month')
  const days = selectedYear && selectedMonth ? getDaysInMonth(selectedYear, selectedMonth) : []

  useEffect(() => {
    if (!user?.cpUserInfo) {
      router.push('/')
    }
  }, [user?.cpUserInfo])

  useEffect(() => {
    const currentDay = form.getValues('day')
    const maxDay = days[days.length - 1]
    if (parseInt(currentDay) > parseInt(maxDay)) {
      form.setValue('day', maxDay)
    }
  }, [selectedYear, selectedMonth, days, form])

  async function onSubmit(data: FormValues) {
    if (!user?.userId) {
      return
    }
    setLoading(true)
    try {
      const isExist = await checkNickname({
        nickname: data.nickname.trim(),
      })
      if (isExist) {
        form.setError('nickname', {
          message: 'This nickname is already taken',
        })
        return
      }
      await mutateAsync({
        nickname: data.nickname.trim(),
        sex: data.gender,
        birthday: `${data.year}-${data.month}-${data.day}`,
        userId: user?.userId,
      })
      await refetch()
      if (redirect) {
        router.push(decodeURIComponent(redirect))
      } else {
        router.push('/')
      }
    } catch (error) {
      console.error(error)
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="flex flex-col items-center">
      <div className="relative mx-auto mt-[20vh] h-[88px] w-[221px]">
        <Image
          src="/images/login/logo.svg"
          alt="Anime character"
          width={221}
          height={88}
          className="object-cover"
          priority
        />
      </div>
      <div className="mt-20 w-[752px]">
        <div className="bg-surface-element-normal mt-6 rounded-lg p-6">
          <h2 className="txt-title-l py-4 text-center">Personal Information</h2>
          <Form {...form}>
            <form className="flex flex-col gap-6" onSubmit={form.handleSubmit(onSubmit)}>
              <FormField
                control={form.control}
                name="nickname"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="txt-label-m">Nickname</FormLabel>
                    <FormControl>
                      <Input
                        {...field}
                        placeholder="Enter nickname"
                        autoComplete="off"
                        maxLength={20}
                        showCount
                        error={!!form.formState.errors.nickname}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="gender"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel className="txt-label-m">Gender</FormLabel>
                    <FormControl>
                      <GenderInput value={field.value} onChange={field.onChange} />
                    </FormControl>
                    <div className="txt-body-s text-txt-secondary-normal mt-1">
                      Please note: gender cannot be changed after setting
                    </div>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <div>
                <Label className="txt-label-m mb-3 block">Birthday</Label>
                <div className="flex gap-2">
                  <FormField
                    control={form.control}
                    name="year"
                    render={({ field }) => (
                      <FormItem className="flex-1">
                        <Select onValueChange={field.onChange} value={field.value}>
                          <SelectTrigger className="w-full" error={!!form.formState.errors.year}>
                            <SelectValue placeholder="Year" />
                          </SelectTrigger>
                          <SelectContent>
                            {years.map((y) => (
                              <SelectItem key={y} value={y}>
                                {y}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="month"
                    render={({ field }) => (
                      <FormItem className="flex-1">
                        <Select onValueChange={field.onChange} value={field.value}>
                          <SelectTrigger className="w-full" error={!!form.formState.errors.year}>
                            <SelectValue placeholder="Month" />
                          </SelectTrigger>
                          <SelectContent>
                            {months.map((m, index) => (
                              <SelectItem key={m} value={m}>
                                {monthTexts[index]}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="day"
                    render={({ field }) => (
                      <FormItem className="flex-1">
                        <Select onValueChange={field.onChange} value={field.value}>
                          <SelectTrigger
                            className="w-full"
                            error={!!form.formState.errors.year || !!form.formState.errors.day}
                          >
                            <SelectValue placeholder="Day" />
                          </SelectTrigger>
                          <SelectContent>
                            {days.map((d) => (
                              <SelectItem key={d} value={d}>
                                {d}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </FormItem>
                    )}
                  />
                </div>
                <FormMessage>
                  {form.formState.errors.year?.message ||
                    form.formState.errors.month?.message ||
                    form.formState.errors.day?.message}
                </FormMessage>
              </div>

              <div className="flex justify-between">
                <div />
                <Button type="submit" loading={loading}>
                  Submit
                </Button>
              </div>
            </form>
          </Form>
        </div>
      </div>
    </div>
  )
}
