"use client";

import React from "react";
import styles from "./RegisterForm.module.css";
import { Form, Formik, FormikHelpers, yupToFormErrors } from "formik";
import { RegisterFormValues, registerSchema } from "@/schemas";
import { useRouter } from "next/navigation";
import { fileAsBase64 } from "@/forms";
import Input from "@/components/Input";
import PrettyForm from "@/components/PrettyForm";
import HugeSubmit from "@/components/HugeSubmit";
import AvatarChanger from "@/components/AvatarChanger";
import { ValidAuthProvider } from "@/auth/AuthProvider";

type RegisterResponse = {
  ok: boolean;
  error?: string;
};

export default function RegisterForm({
  initialDisplayName,
  initialEmail,
  initialAvatarBase64,
  avatarSource
}: {
  initialDisplayName?: string;
  initialEmail?: string;
  initialAvatarBase64?: string;
  avatarSource: ValidAuthProvider | null;
}) {
  const [globalError, setGlobalError] = React.useState<string | null>(null);
  const router = useRouter();

  const initialValues: RegisterFormValues = {
    username: "",
    displayName: initialDisplayName ?? "",
    email: initialEmail ?? "",
    password: "",
    confirmPassword: "",
    avatar: initialAvatarBase64
  };

  async function handleFormSubmit(
    { avatar, username, displayName, email, password }: RegisterFormValues,
    { setFieldError, setSubmitting }: FormikHelpers<RegisterFormValues>
  ) {
    setSubmitting(true);

    const resp = await fetch(`/api/register`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        username,
        displayName,
        email,
        password,
        avatar: avatar != null ? avatar.split(",")[1] : undefined
      })
    });

    try {
      const res: RegisterResponse = await resp.json();

      if (res.ok) {
        router.replace("/me");
      } else {
        if (res.error !== null) {
          switch (res.error) {
            case "avatarBig":
              setFieldError(
                "avatar",
                "avatar was too big, but only the server caught you what the fuck are you doing!!"
              );
              break;

            case "usernameTaken":
              setFieldError("username", "Username is already taken.");
              break;
          }
        }
      }
    } catch (err) {
      console.error(err);
      setGlobalError("you done fucked up kiddo");
    }

    setSubmitting(false);
  }

  return (
    <PrettyForm globalError={globalError}>
      <Formik
        initialValues={initialValues}
        onSubmit={handleFormSubmit}
        validationSchema={registerSchema}
        enableReinitialize
      >
        {({ isSubmitting }) => (
          <Form>
            <Input
              hint="The username you'll use to log into NotNet services. By standard, this should be lowercase, and usually your first name."
              type="text"
              name="username"
              label="Username"
              placeholder="julian"
            />
            <Input
              hint="Your display name - this can be what you go by online, for example."
              type="text"
              name="displayName"
              label="Display name"
              placeholder="NotNite"
            />
            <Input
              hint="Your email address. An inbox will be created on @n2.pm that forwards to this email."
              type="email"
              name="email"
              label="Email"
              placeholder="hi@notnite.com"
            />
            <Input
              hint="Your password. To secure NotNet services, make this a strong and long password."
              type="password"
              name="password"
              label="Password"
              placeholder="deeznuts47"
              minLength={12}
              autoComplete="new-password"
            />
            <Input
              type="password"
              name="confirmPassword"
              label="Confirm password"
              placeholder="deeznuts47"
              minLength={12}
            />
            <Input
              hint={
                (avatarSource != null
                  ? `We found your avatar from ${avatarSource}, but you can change it if you'd like.`
                  : "") +
                " This will automatically be used as your avatar with supported services - maximum 2 MB. "
              }
              type="file"
              name="avatar"
              label="Avatar"
              accept="image/png, image/jpeg"
              customRender={(fieldProps) => (
                <AvatarChanger
                  currentAvatarBlob={fieldProps.field.value}
                  onChange={(newBlob) =>
                    fieldProps.form.setFieldValue("avatar", newBlob)
                  }
                />
              )}
            />
            <div className={styles.buttonContainer}>
              <HugeSubmit value="Join NotNet!" disabled={isSubmitting} />
            </div>

            <a
              className={styles.bail}
              onClick={async () => {
                await fetch("/api/unlink", { method: "POST" });
                document.cookie =
                  "ticket=; expires=" + new Date().toUTCString() + "; path=/";
                window.location.href = "/";
              }}
            >
              {`Didn't mean to sign up?`}
            </a>
          </Form>
        )}
      </Formik>
    </PrettyForm>
  );
}
