'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,
  CardDescription,
  CardHeader,
  CardTitle,
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Input,
  SubmitButton,
  Switch,
} 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' }),
  automaticLunch: z.boolean(),
});

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

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

  const updateUser = useMutation(api.auth.updateUser);

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

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

  const handleSubmit = async (values: z.infer<typeof formSchema>) => {
    const name = values.name.trim();
    const email = values.email.trim().toLowerCase();
    const lunchTime = values.lunchTime.trim();
    const automaticLunch = values.automaticLunch;
    const patch: Partial<{
      name: string;
      email: string;
      lunchTime: string;
      automaticLunch: boolean;
    }> = {};
    if (name !== (user?.name ?? '') && name !== undefined)
      patch.name = name;
    if (email !== (user?.email ?? '') && email !== undefined)
      patch.email = email;
    if (lunchTime !== (user?.lunchTime && '') && lunchTime !== undefined)
      patch.lunchTime = lunchTime;
    if (automaticLunch !== user?.automaticLunch && automaticLunch !== undefined)
      patch.automaticLunch = automaticLunch;
    if (Object.keys(patch).length === 0) return;
    setLoading(true);
    try {
      await updateUser(patch);
      form.reset(patch);
      toast.success('Profile updated successfully.');
    } catch (error) {
      console.error(error);
      toast.error('Error updating profile.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <CardHeader>
        <CardTitle className='text-2xl'>Account Information</CardTitle>
        <CardDescription>Update your account information here.</CardDescription>
      </CardHeader>
      <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}
                      disabled={user?.provider !== 'password'}
                    />
                  </FormControl>
                  <FormDescription>
                    Your email address associated with your account.
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <div className='flex flex-row justify-center space-x-10'>
              <FormField
                control={form.control}
                name='lunchTime'
                render={({ field }) => (
                  <FormItem className='sm:w-2/5'>
                    <div className='flex flex-row space-x-2 my-auto'>
                      <FormLabel>Lunch Time</FormLabel>
                      <FormControl>
                        <Input type='time' className='w-28' {...field} />
                      </FormControl>
                    </div>
                    <FormDescription>Your regular lunch time.</FormDescription>
                    <FormDescription className='dark:text-red-300/60 text-red-800/80'>
                      {!user?.lunchTime && 'Not currently set.'}
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name='automaticLunch'
                render={({ field }) => (
                  <FormItem className='w-2/5 mt-2'>
                    <div className='flex flex-row space-x-2 my-auto'>
                      <FormControl>
                        <Switch
                          className='border-solid border-primary'
                          checked={field.value}
                          onCheckedChange={field.onChange}
                        />
                      </FormControl>
                      <FormLabel>Automatic Lunch</FormLabel>
                    </div>
                    <FormDescription>
                      Automatically take your lunch at the time you specify.
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <div className='flex justify-center mt-5'>
              <SubmitButton
                className='lg:w-1/3 w-2/3 text-[1.0rem]'
                disabled={loading}
                pendingText='Saving...'
              >
                Save Changes
              </SubmitButton>
            </div>
          </form>
        </Form>
      </CardContent>
    </>
  );
};
