'use client';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import Link from 'next/link';
import { useAuthActions } from '@convex-dev/auth/react';
import { useRouter } from 'next/navigation';
import { ConvexError } from 'convex/values';
import { useState } from 'react';
import {
  Card,
  CardContent,
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Input,
  SubmitButton,
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from '@/components/ui';
import { toast } from 'sonner';
import { PASSWORD_MIN, PASSWORD_MAX, PASSWORD_REGEX } from '@/lib/types';

const signInFormSchema = z.object({
  email: z.email({
    message: 'Please enter a valid email address.',
  }),
  password: z.string().regex(PASSWORD_REGEX, {
    message: 'Incorrect password. Does not meet requirements.',
  }),
});

const signUpFormSchema = z
  .object({
    name: z.string().min(2, {
      message: 'Name must be at least 2 characters.',
    }),
    email: z.string().email({
      message: 'Please enter a valid email address.',
    }),
    password: z
      .string()
      .min(PASSWORD_MIN, {
        message: `Password must be at least ${PASSWORD_MIN} characters.`,
      })
      .max(PASSWORD_MAX, {
        message: `Password must be no more than ${PASSWORD_MAX} characters.`,
      })
      .regex(/^\S+$/, {
        message: 'Password must not contain whitespace.',
      })
      .regex(/[0-9]/, {
        message: 'Password must contain at least one digit.',
      })
      .regex(/[a-z]/, {
        message: 'Password must contain at least one lowercase letter.',
      })
      .regex(/[A-Z]/, {
        message: 'Password must contain at least one uppercase letter.',
      })
      .regex(/[\p{P}\p{S}]/u, {
        message: 'Password must contain at least one symbol.',
      }),
    confirmPassword: z.string().min(PASSWORD_MIN, {
      message: `Password must be at least ${PASSWORD_MIN} characters.`,
    }),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: 'Passwords do not match!',
    path: ['confirmPassword'],
  });

const SignIn = () => {
  const { signIn } = useAuthActions();
  const [flow, setFlow] = useState<'signIn' | 'signUp'>('signIn');
  const [loading, setLoading] = useState(false);
  const router = useRouter();

  const signInForm = useForm<z.infer<typeof signInFormSchema>>({
    resolver: zodResolver(signInFormSchema),
    defaultValues: { email: '', password: '' },
  });

  const signUpForm = useForm<z.infer<typeof signUpFormSchema>>({
    resolver: zodResolver(signUpFormSchema),
    defaultValues: {
      name: '',
      email: '',
      password: '',
      confirmPassword: '',
    },
  });

  const handleSignIn = async (values: z.infer<typeof signInFormSchema>) => {
    const formData = new FormData();
    formData.append('email', values.email);
    formData.append('password', values.password);
    formData.append('flow', flow);
    setLoading(true);
    try {
      await signIn('password', formData);
      signInForm.reset();
      router.push('/');
    } catch (error) {
      console.error('Error signing in:', error);
      toast.error('Error signing in.');
    } finally {
      setLoading(false);
    }
  };

  const handleSignUp = async (values: z.infer<typeof signUpFormSchema>) => {
    const formData = new FormData();
    formData.append('email', values.email);
    formData.append('password', values.password);
    formData.append('flow', flow);
    formData.append('name', values.name);
    setLoading(true);
    try {
      if (values.confirmPassword !== values.password)
        throw new ConvexError('Passwords do not match.');
      await signIn('password', formData);
      signUpForm.reset();
      router.push('/');
    } catch (error) {
      console.error('Error signing up:', error);
      toast.error('Error signing up.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className='flex flex-col items-center'>
      <Card className='p-4 bg-card/25 min-h-[720px] w-md'>
        <Tabs
          defaultValue={flow}
          onValueChange={(value) => setFlow(value as 'signIn' | 'signUp')}
          className='items-center'
        >
          <TabsList className='py-6'>
            <TabsTrigger
              value='signIn'
              className='p-6 text-2xl font-bold cursor-pointer'
            >
              Sign In
            </TabsTrigger>
            <TabsTrigger
              value='signUp'
              className='p-6 text-2xl font-bold cursor-pointer'
            >
              Sign Up
            </TabsTrigger>
          </TabsList>
          <TabsContent value='signIn'>
            <Card className='min-w-xs sm:min-w-sm bg-card/50'>
              <CardContent>
                <Form {...signInForm}>
                  <form
                    onSubmit={signInForm.handleSubmit(handleSignIn)}
                    className='flex flex-col space-y-8'
                  >
                    <FormField
                      control={signInForm.control}
                      name='email'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className='text-xl'>Email</FormLabel>
                          <FormControl>
                            <Input
                              type='email'
                              placeholder='you@example.com'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={signInForm.control}
                      name='password'
                      render={({ field }) => (
                        <FormItem>
                          <div className='flex justify-between'>
                            <FormLabel className='text-xl'>Password</FormLabel>
                            <Link href='/forgot-password'>
                              Forgot Password?
                            </Link>
                          </div>
                          <FormControl>
                            <Input
                              type='password'
                              placeholder='Your password'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <SubmitButton
                      disabled={loading}
                      pendingText='Signing in...'
                      className='text-lg font-semibold w-2/3 mx-auto'
                    >
                      Sign In
                    </SubmitButton>
                  </form>
                </Form>
              </CardContent>
            </Card>
          </TabsContent>
          <TabsContent value='signUp'>
            <Card className='min-w-xs sm:min-w-sm bg-card/50'>
              <CardContent>
                <Form {...signUpForm}>
                  <form
                    onSubmit={signUpForm.handleSubmit(handleSignUp)}
                    className='flex flex-col space-y-8'
                  >
                    <FormField
                      control={signUpForm.control}
                      name='name'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className='text-xl'>Name</FormLabel>
                          <FormControl>
                            <Input
                              type='text'
                              placeholder='Full Name'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={signUpForm.control}
                      name='email'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className='text-xl'>Email</FormLabel>
                          <FormControl>
                            <Input
                              type='email'
                              placeholder='you@example.com'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={signUpForm.control}
                      name='password'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className='text-xl'>Password</FormLabel>
                          <FormControl>
                            <Input
                              type='password'
                              placeholder='Your password'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={signUpForm.control}
                      name='confirmPassword'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel className='text-xl'>
                            Confirm Passsword
                          </FormLabel>
                          <FormControl>
                            <Input
                              type='password'
                              placeholder='Confirm your password'
                              {...field}
                            />
                          </FormControl>
                          <div className='flex flex-col w-full items-center'>
                            <FormMessage className='w-5/6 text-center' />
                          </div>
                        </FormItem>
                      )}
                    />
                    <SubmitButton
                      disabled={loading}
                      pendingText='Signing Up...'
                      className='text-lg font-semibold w-2/3 mx-auto'
                    >
                      Sign Up
                    </SubmitButton>
                  </form>
                </Form>
              </CardContent>
            </Card>
          </TabsContent>
        </Tabs>
      </Card>
    </div>
  );
};
export default SignIn;
