'use client';

import type { Preloaded } from 'convex/react';
import { useState } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useAction, usePreloadedQuery } from 'convex/react';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
import { z } from 'zod';

import { api } from '@gib/backend/convex/_generated/api.js';
import { PASSWORD_MAX, PASSWORD_MIN, PASSWORD_REGEX } from '@gib/backend/types';
import {
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Input,
  Separator,
  SubmitButton,
} from '@gib/ui';

const formSchema = z
  .object({
    currentPassword: z.string().regex(PASSWORD_REGEX, {
      message: 'Incorrect current password. Does not meet requirements.',
    }),
    newPassword: z
      .string()
      .min(PASSWORD_MIN, {
        message: 'New password must be at least 8 characters.',
      })
      .max(PASSWORD_MAX, {
        message: 'New password must be less than 100 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(),
  })
  .refine((data) => data.currentPassword !== data.newPassword, {
    message: 'New password must be different from current password.',
    path: ['newPassword'],
  })
  .refine((data) => data.newPassword === data.confirmPassword, {
    message: 'Passwords do not match.',
    path: ['confirmPassword'],
  });

interface ResetFormProps {
  preloadedProvider: Preloaded<typeof api.auth.getUserProvider>;
}

export const ResetPasswordForm = ({ preloadedProvider }: ResetFormProps) => {
  const userProvider = usePreloadedQuery(preloadedProvider);
  const [loading, setLoading] = useState(false);

  const changePassword = useAction(api.auth.updateUserPassword);

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      currentPassword: '',
      newPassword: '',
      confirmPassword: '',
    },
  });

  const handleSubmit = async (values: z.infer<typeof formSchema>) => {
    setLoading(true);
    try {
      const result = await changePassword({
        currentPassword: values.currentPassword,
        newPassword: values.newPassword,
      });
      if (result.success) {
        form.reset();
        toast.success('Password updated successfully.');
      }
    } catch (error) {
      console.error('Error updating password:', error);
      toast.error('Error updating password.');
    } finally {
      setLoading(false);
    }
  };
  // Only show password reset for email/password auth users
  if (userProvider !== 'email') {
    return null;
  }

  return (
    <>
      <Separator />
      <CardHeader>
        <CardTitle>Change Password</CardTitle>
        <CardDescription>
          Update your password to keep your account secure
        </CardDescription>
      </CardHeader>
      <CardContent>
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(handleSubmit)}
            className='space-y-4'
          >
            <FormField
              control={form.control}
              name='currentPassword'
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Current Password</FormLabel>
                  <FormControl>
                    <Input
                      type='password'
                      {...field}
                      placeholder='Enter current password'
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name='newPassword'
              render={({ field }) => (
                <FormItem>
                  <FormLabel>New Password</FormLabel>
                  <FormControl>
                    <Input
                      type='password'
                      {...field}
                      placeholder='Enter new password'
                    />
                  </FormControl>
                  <FormDescription>
                    Must be at least 8 characters with uppercase, lowercase,
                    number, and symbol
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name='confirmPassword'
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Confirm New Password</FormLabel>
                  <FormControl>
                    <Input
                      type='password'
                      {...field}
                      placeholder='Confirm new password'
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <div className='flex justify-end pt-2'>
              <SubmitButton disabled={loading} pendingText='Updating...'>
                Update Password
              </SubmitButton>
            </div>
          </form>
        </Form>
      </CardContent>
    </>
  );
};
