"use client";

import { FaCheck } from "react-icons/fa6";
import { Controller, useForm } from "react-hook-form";
import { useCallback, useEffect } from "react";
import { useFormState, useFormStatus } from "react-dom";

import {
  ContactInformationProfileSchema,
  ManualEmailUpdateSchema,
} from "@/types/profile/profile-update-schema";
import Button from "@/components/common/button";
import Breadcrumbs from "@/components/common/breadcrumbs";
import TextInput from "@/components/common/text-input";
import { manualEmailUpdate } from "@/services/participant/profile/manual-email-update-actions";
import FormError from "@/components/common/form-error";
import Alert from "@/components/common/alert";
import { deleteSession } from "@/lib/user-session";

type ManualEmailUpdateProps = {
  userData: ContactInformationProfileSchema;
  phoneNumber: string;
  userEmail: string;
  userFirstName: string;
  userId: number;
};

function SubmitButton() {
  const { pending } = useFormStatus();

  return (
    <Button
      fullWidth
      aria-disabled={pending}
      btnLabel={pending ? "Updating..." : "Update my email address"}
      customVariant="black"
      endContent={pending ? null : <FaCheck />}
      isDisabled={pending}
      isLoading={pending}
      type="submit"
    />
  );
}

function ManualEmailUpdate({
  userData,
  userFirstName,
  userEmail,
  userId,
}: ManualEmailUpdateProps) {
  const { control, getValues } = useForm<ManualEmailUpdateSchema>({
    defaultValues: {
      currentEmail: "",
      newEmail: "",
    },
    mode: "all",
  });

  const [state, formAction] = useFormState(
    manualEmailUpdate.bind(null, userId, userData),
    {
      success: false,
      error: "",
    }
  );

  const handleLogout = useCallback(() => {
    const newEmail = getValues("newEmail");
    deleteSession(true, newEmail);
  }, [getValues]);

  useEffect(() => {
    if (state.success) {
      // note: this logout is required because we need to update the user session that exists in cookies.
      // these cookies are httpOnly, which means it won’t be accessible via JavaScript on the client side.
      // we need to login the user again to keep everything in sync (e.g. navbar depends on it).
      handleLogout();
    }
  }, [handleLogout, state.success]);

  return (
    <div className="mb-24">
      <div className="block lg:hidden m-4">
        <Breadcrumbs />
      </div>
      <div className="bg-white p-8 rounded-md m-4 sm:m-20 lg:m-auto mt-4 lg:w-1/2 lg:h-1/2 lg:mt-12">
        <div className="mt-4 space-y-4 text-black">
          <h1 className="font-inter text-xl font-extrabold tracking-tight">
            Update my email address
          </h1>
          <p className="font-noto text-base">
            {userFirstName}, you can update your email address here. Please note
            that the new email address will be used for all future communication
            and login attempts. Your current email address is:{" "}
            <kbd className="px-2 py-1 text-sm text-gray-900 bg-gray-100 border border-gray-300 rounded-md">
              {userEmail}
            </kbd>
            .
          </p>
          <p>
            In order to change your email address, please state below your
            current email address, along with the new email address.
          </p>
          <form action={formAction} className="flex flex-col gap-4">
            <Controller
              control={control}
              name="currentEmail"
              render={({ fieldState, field }) => {
                return (
                  <TextInput
                    blockCopyPaste
                    isClearable
                    control={control}
                    fieldProps={field}
                    fieldState={fieldState}
                    label="Current email address"
                    name={field.name}
                    placeholder="Your current email address"
                  />
                );
              }}
            />
            {state.errors?.currentEmail && (
              <FormError text={state.errors.currentEmail} />
            )}
            <Controller
              control={control}
              name="newEmail"
              render={({ fieldState, field }) => {
                return (
                  <TextInput
                    blockCopyPaste
                    isClearable
                    control={control}
                    fieldProps={field}
                    fieldState={fieldState}
                    label="New email address"
                    name={field.name}
                    placeholder="The new email address"
                  />
                );
              }}
            />
            <p>
              After you update your email address, you will be logged out
              automatically and you need to log in again.
            </p>
            {state.errors?.newEmail && (
              <FormError text={state.errors.newEmail} />
            )}
            {state.error && (
              <Alert
                showSupportEmail
                message={state.error}
                title={`Error (${state.errorCode})`}
                variant="error"
              />
            )}
            {state.errors && (
              <Alert
                message="Some fields have missing or incorrect information. Please review the highlighted fields and correct any errors."
                title="Error"
                variant="alert"
              />
            )}
            <SubmitButton />
          </form>
        </div>
      </div>
    </div>
  );
}

export default ManualEmailUpdate;
