'use client';

import { zodResolver } from '@hookform/resolvers/zod';
import cookies from 'js-cookie';
import { Loader2 } from 'lucide-react';
import { usePathname, useRouter } from 'next/navigation';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import * as z from 'zod';

import AppLink from '@/components/ui/AppLink';
import { Button } from '@/components/ui/Button';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from '@/components/ui/Form';
import { Input } from '@/components/ui/Input';

const AuthFormSchema = z.object({
  pseudo: z.string().nonempty({ message: "Nom d'utilisateur requis" }),
  email: z.string().optional(),
  passwd: z.string().nonempty({ message: 'Mot de passe requis' }),
  firstname: z.string().optional(),
  lastname: z.string().optional(),
  // Remove this soon cause not supported anymore
  description: z.string().optional(),
  sgroup: z.string().optional(),
  avatar: z.string().optional()
});

export default function UserAuthForm() {
  const form = useForm<z.infer<typeof AuthFormSchema>>({
    resolver: zodResolver(AuthFormSchema),
    defaultValues: {
      pseudo: '',
      email: '',
      passwd: '',
      firstname: '',
      lastname: '',
      // Remove this soon cause not supported anymore
      description: '',
      sgroup: '',
      avatar: ''
    }
  });

  const [isLoading, setIsLoading] = useState(false);

  const router = useRouter();
  const pathname = usePathname()!;

  const isSignIn = pathname.includes('sign-in');

  async function onSubmit(data: z.infer<typeof AuthFormSchema>) {
    setIsLoading(true);

    const res = await fetch(
      `${process.env.NEXT_PUBLIC_API_URL}/${isSignIn ? 'login' : 'register'}`,
      {
        method: 'POST',
        body: JSON.stringify(data)
      }
    );

    if (!res) {
      form.setError('passwd', {
        type: 'manual',
        message: "Une erreur s'est produite."
      });
      setIsLoading(false);
      return;
    }

    if (!isSignIn) {
      if (res.status === 400) {
        const { username_valid, email_valid } = await res.json();
        if (!username_valid) {
          form.setError('pseudo', {
            message: "Nom d'utilisateur indisponible"
          });
          setIsLoading(false);
          return;
        }
        if (!email_valid) {
          form.setError('email', {
            message: 'Adresse e-mail indisponible'
          });
          setIsLoading(false);
          return;
        }
      }
    }

    if (res.status === 200) {
      const token = res.headers.get('Authorization')?.split(' ')[1];
      if (token) {
        cookies.set('token', token, {
          sameSite: 'strict',
          secure: process.env.NODE_ENV === 'production'
        });
        router.refresh();
      }
    } else {
      form.setError('passwd', {
        message: "Nom d'utilisateur ou mot de passe incorrect"
      });
      setIsLoading(false);
      return;
    }
  }

  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(onSubmit)}
        className="flex w-52 flex-col justify-center space-y-4 sm:w-72"
      >
        {!isSignIn && (
          <>
            <FormField
              control={form.control}
              name="email"
              render={({ field }) => (
                <FormItem>
                  <FormLabel htmlFor="email">Email</FormLabel>
                  <FormControl>
                    <Input type="email" placeholder="philipzcwbarlow@peerat.dev" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="firstname"
              render={({ field }) => (
                <FormItem>
                  <FormLabel htmlFor="firstname">Prénom</FormLabel>
                  <FormControl>
                    <Input placeholder="Philip" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="lastname"
              render={({ field }) => (
                <FormItem>
                  <FormLabel htmlFor="lastname">Nom</FormLabel>
                  <FormControl>
                    <Input placeholder="Barlow" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
          </>
        )}
        <FormField
          control={form.control}
          name="pseudo"
          render={({ field }) => (
            <FormItem>
              <FormLabel htmlFor="pseudo">Nom d&apos;utilisateur</FormLabel>
              <FormControl>
                <Input placeholder="Barlow" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="passwd"
          render={({ field }) => (
            <FormItem>
              <FormLabel htmlFor="passwd">Mot de passe</FormLabel>
              <FormControl>
                <Input type="password" placeholder="********" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button disabled={isLoading} variant="brand">
          {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
          {isSignIn ? 'Se connecter' : "S'inscrire"}
        </Button>
        <p className="flex flex-col items-center text-sm text-muted">
          {isSignIn ? "Vous n'avez pas de compte?" : 'Vous possédez un compte?'}{' '}
          <AppLink className="text-brand underline" href={isSignIn ? '/sign-up' : '/sign-in'}>
            {isSignIn ? "S'inscrire maintenant" : 'Se connecter'}
          </AppLink>
        </p>
      </form>
    </Form>
  );
}
