"use client";

import { Controller, useForm } from "react-hook-form";
import { useRouter, useSearchParams } from "next/navigation";
import { FaChevronRight, FaCircleCheck } from "react-icons/fa6";
import { useCallback, useEffect, useState, useRef, useMemo } from "react";
import { useFormState, useFormStatus } from "react-dom";

import SecondaryHeading from "@/components/pages/participant/sign-up/common/secondary-heading";
import StepHeading from "@/components/pages/participant/sign-up/common/step-heading";
import Button from "@/components/common/button";
import { Options } from "@/types/options/options-data-types";
import TermsAndConditions from "@/components/pages/participant/sign-up/common/terms-conditions";
import { IncomeOccupationData } from "@/types/signup/user-signup-types";
import CompanyContactsFooter from "@/components/pages/participant/sign-up/common/company-contacts-footer";
import Select from "@/components/common/select";
import CheckboxGroup from "@/components/common/checkbox-group";
import { validateIncomeOccupation } from "@/services/participant/signup/signup-income-occupation-actions";
import { INTERNAL_PAGES } from "@/constants/pages-mapping/internal-pages-mapping";
import FormError from "@/components/common/form-error";
import { registerUser } from "@/services/participant/signup/signup-register-user-actions";
import Alert from "@/components/common/alert";

type IncomeOccupationProps = {
  incomeRangeOptions: Options;
  employmentOptions: Options;
  userFirstName: string;
};

function SubmitButton({ isUserEmployed }: { isUserEmployed: boolean }) {
  const { pending } = useFormStatus();

  return (
    <Button
      fullWidth
      aria-disabled={pending}
      btnLabel={
        isUserEmployed ? "Continue to next step" : "Finish registration"
      }
      customVariant="black"
      endContent={isUserEmployed ? <FaChevronRight /> : <FaCircleCheck />}
      isDisabled={pending}
      isLoading={pending}
      type="submit"
    />
  );
}

function IncomeOccupation({
  incomeRangeOptions,
  employmentOptions,
  userFirstName,
}: IncomeOccupationProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const queryString = searchParams.toString();
  const userSource = searchParams.get("utm_source") || undefined;
  const [hasError, setHasError] = useState(false);
  const [hasRegistered, setHasRegistered] = useState(false);

  // 1 = employed, 2 = self-employed, 3 = student, 9 = zero-hours
  const employedTypes = useMemo(() => [1, 2, 3, 9], []);

  const { control, watch } = useForm<IncomeOccupationData>({
    mode: "all",
    defaultValues: {
      incomeBracketId: 0,
      employmentStatus: [],
    },
  });

  const employmentStatusIds = watch("employmentStatus");
  const isUserEmployed = employmentStatusIds.some((type) =>
    employedTypes.includes(type),
  );

  const isUserEmployedRef = useRef(false);

  useEffect(() => {
    isUserEmployedRef.current = employmentStatusIds.some((type) =>
      employedTypes.includes(type),
    );
  }, [employmentStatusIds, employedTypes]);

  const [state, formAction] = useFormState(validateIncomeOccupation, {
    success: false,
    error: "",
  });

  const handleRegisterUser = useCallback(async () => {
    const response = await registerUser(userSource);

    if (response.success) {
      setHasRegistered(true);
    } else {
      setHasRegistered(false);
      setHasError(true);
    }
  }, [userSource]);

  useEffect(() => {
    if (!state.success) return;

    if (isUserEmployedRef.current) {
      queryString
        ? router.push(
            `${INTERNAL_PAGES.participant.signup.employmentInformation}?${queryString}`,
          )
        : router.push(INTERNAL_PAGES.participant.signup.employmentInformation);
    } else {
      handleRegisterUser();
    }
  }, [state.success, handleRegisterUser, queryString, router]);

  useEffect(() => {
    if (hasRegistered) {
      queryString
        ? router.push(
            `${INTERNAL_PAGES.participant.signup.thanksForJoining}?${queryString}`,
          )
        : router.push(INTERNAL_PAGES.participant.signup.thanksForJoining);
    }
  }, [hasRegistered, queryString, router]);

  const showFinalError = hasError || state.error !== "";

  return (
    <main
      className="xl:w-7/12 relative bg-white xl:pt-0 pt-12 light pb-10"
      id="main-content"
    >
      <div className="absolute xl:hidden top-0 w-full h-2 bg-participant-bittersweet dark:bg-participant-cerulean" />
      <StepHeading
        currentStep={4}
        subtitle={`Nearly there, ${userFirstName}! Just a few more questions about you.`}
        title="Finish account set up"
        totalSteps={isUserEmployed ? 5 : 4}
      />
      <div className="flex flex-col flex-grow">
        <div className="mt-4 space-y-0 ms-6 xl:ms-16">
          <SecondaryHeading title="Income & occupation" />
          <p className="font-noto text-xs text-others-shadowGray">
            Please enter your current income range and occupation below.
          </p>
        </div>
        <form
          noValidate
          action={formAction}
          className="mt-6 sm:mt-8 flex flex-col gap-4 xl:mx-16 mx-6"
        >
          <Controller
            control={control}
            name="incomeBracketId"
            render={({ field, fieldState }) => {
              return (
                <Select
                  control={control}
                  data={incomeRangeOptions}
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Income range"
                  name={field.name}
                  placeholder="Select your income range"
                />
              );
            }}
          />
          {state.errors?.incomeBracketId && (
            <FormError text={state.errors.incomeBracketId} />
          )}
          <Controller
            control={control}
            name="employmentStatus"
            render={({ field, fieldState }) => {
              return (
                <CheckboxGroup
                  classNames={{ base: "light font-noto" }}
                  fieldProps={field}
                  fieldState={fieldState}
                  label="My current occupation"
                  name={field.name}
                  options={employmentOptions}
                  secondaryLabel="Please select all options that apply."
                />
              );
            }}
          />
          {state.errors?.employmentStatus && (
            <FormError text={state.errors.employmentStatus} />
          )}
          <SubmitButton isUserEmployed={isUserEmployed} />
          {showFinalError && (
            <Alert
              showSupportEmail
              message="An error has occurred while trying to create your account. Please try again. If the error persists, please contact us at "
              title="Error"
              variant="error"
            />
          )}
        </form>
      </div>
      <div className="mt-16 mb-10 mx-8 sm:mb-4 sm:mx-28 lg:mb-3 lg:mx-0 space-y-6">
        <TermsAndConditions />
        <CompanyContactsFooter />
      </div>
    </main>
  );
}

export default IncomeOccupation;
