import { zodResolver } from "@hookform/resolvers/zod";
import { SubmitHandler, useForm } from "react-hook-form";
import z from "zod";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "../ui/form";
import { Input } from "../ui/input";

const oneEmoji = z
  .string()
  .refine((val) => val.length === 0 || [...val].length === 1, {
    error: "Please enter a single emoji",
  });

const gridDimension = (dir: "row" | "column") =>
  z.coerce.number<number>().min(2, { error: `Minimum 2 ${dir}s` });

type FormData = z.infer<typeof formSchema>;
const formSchema = z.object({
  width: gridDimension("column"),
  height: gridDimension("row"),
  variants: z.array(oneEmoji).min(2).max(4),
});

interface Props {
  defaultValues: FormData;
  onSubmit: SubmitHandler<FormData>;
  buttons?: () => React.ReactNode;
}

export function PreferencesForm({ defaultValues, onSubmit, buttons }: Props) {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues,
  });

  return (
    <Form {...form}>
      <form
        id="preferences-form"
        onSubmit={form.handleSubmit((formData) => {
          formData.variants = formData.variants.filter(Boolean);
          return onSubmit(formData);
        })}
      >
        <div className="grid gap-4 grid-cols-4">
          <FormField
            control={form.control}
            name="width"
            render={({ field }) => (
              <FormItem className="col-span-2">
                <FormLabel>Columns</FormLabel>
                <FormControl>
                  <Input
                    type="number"
                    onFocus={(e) => e.target.select()}
                    {...field}
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="height"
            render={({ field }) => (
              <FormItem className="col-span-2">
                <FormLabel>Rows</FormLabel>
                <FormControl>
                  <Input
                    type="number"
                    onFocus={(e) => e.target.select()}
                    {...field}
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="variants.0"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Left</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    onFocus={(e) => e.target.select()}
                    className="text-center text-2xl"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="variants.1"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Top</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    onFocus={(e) => e.target.select()}
                    className="text-center text-2xl"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="variants.2"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Right</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    onFocus={(e) => e.target.select()}
                    className="text-center text-2xl"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="variants.3"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Bottom</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    onFocus={(e) => e.target.select()}
                    className="text-center text-2xl"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
          <div className="col-span-4">{buttons?.()}</div>
        </div>
      </form>
    </Form>
  );
}
