'use client';
import { useMemo, useState } from 'react';
import { type Preloaded, usePreloadedQuery, useMutation } from 'convex/react';
import { api } from '~/convex/_generated/api';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import {
  CardContent,
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Input,
  SubmitButton,
} from '@/components/ui';
import { toast } from 'sonner';

const formSchema = z.object({
  name: z
    .string()
    .trim()
    .min(5, {
      message: 'Full name is required & must be at least 5 characters.',
    })
    .max(50, {
      message: 'Full name must be less than 50 characters.',
    }),
  email: z.email({
    message: 'Please enter a valid email address.',
  }),
  lunchTime: z
    .string()
    .trim()
    .min(3, { message: 'Must be a valid 24-hour time. Example: 13:00'}),
});

type UserInfoFormProps = {
  preloadedUser: Preloaded<typeof api.auth.getUser>;
};

export const UserInfoForm = ({ preloadedUser }: UserInfoFormProps) => {
  const user = usePreloadedQuery(preloadedUser);
  const [loading, setLoading] = useState(false);

  const updateUserName = useMutation(api.auth.updateUserName);
  const updateUserEmail = useMutation(api.auth.updateUserEmail);
  const updateUserLunchtime = useMutation(api.auth.updateUserLunchtime);

  const initialValues = useMemo<z.infer<typeof formSchema>>(
    () => ({
      name: user?.name ?? '',
      email: user?.email ?? '',
      lunchTime: user?.lunchTime ?? '',
    }), [user?.name, user?.email, user?.lunchTime]
  );

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    values: initialValues,
  });

  const handleSubmit = async (values: z.infer<typeof formSchema>) => {
    const ops: Promise<unknown>[] = [];
    const name = values.name.trim();
    const email = values.email.trim().toLowerCase();
    const lunchTime = values.lunchTime.trim();
    if (name !== (user?.name ?? '')) ops.push(updateUserName({ name }));
    if (email !== (user?.email ?? '')) ops.push(updateUserEmail({ email }));
    if (lunchTime !== (user?.lunchTime ?? ''))
      ops.push(updateUserLunchtime({ lunchTime }))
    if (ops.length === 0) return;
    setLoading(true);
    try {
      await Promise.all(ops);
      form.reset({ name, email, lunchTime });
      toast.success('Profile updated successfully.');
    } catch (error) {
      console.error(error);
      toast.error('Error updating profile.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <CardContent>
      <Form {...form}>
        <form onSubmit={form.handleSubmit(handleSubmit)} className='space-y-6'>
          <FormField
            control={form.control}
            name='name'
            render={({ field }) => (
              <FormItem>
                <FormLabel>Full Name</FormLabel>
                <FormControl>
                  <Input {...field} />
                </FormControl>
                <FormDescription>Your public display name.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <FormField
            control={form.control}
            name='email'
            render={({ field }) => (
              <FormItem>
                <FormLabel>Email</FormLabel>
                <FormControl>
                  <Input {...field} />
                </FormControl>
                <FormDescription>
                  Your email address associated with your account.
                </FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <FormField
            control={form.control}
            name='lunchTime'
            render={({ field }) => (
              <FormItem>
                <FormLabel>Regular Lunch Time</FormLabel>
                <FormControl>
                  <Input {...field} />
                </FormControl>
                <FormDescription>
                  Enter the time you take your lunch most often in 24 hour time.
                </FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />

          <div className='flex justify-center'>
            <SubmitButton disabled={loading} pendingText='Saving...'>
              Save Changes
            </SubmitButton>
          </div>
        </form>
      </Form>
    </CardContent>
  );
};
