"use client";

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

import StepHeading from "@/components/pages/participant/sign-up/common/step-heading";
import SecondaryHeading from "@/components/pages/participant/sign-up/common/secondary-heading";
import Button from "@/components/common/button";
import TermsAndConditions from "@/components/pages/participant/sign-up/common/terms-conditions";
import { Option, Options } from "@/types/options/options-data-types";
import { UserInformationData } from "@/types/signup/user-signup-types";
import { AUTOCOMPLETE_VALUES } from "@/constants/signup-auto-complete-mapping";
import CompanyContactsFooter from "@/components/pages/participant/sign-up/common/company-contacts-footer";
import TextInput from "@/components/common/text-input";
import { mapEthnicityCategory } from "@/utils/mapEthnicityData";
import Select from "@/components/common/select";
import { INTERNAL_PAGES } from "@/constants/pages-mapping/internal-pages-mapping";
import FormError from "@/components/common/form-error";
import { validateUserInformation } from "@/services/participant/signup/signup-user-information-actions";
import Alert from "@/components/common/alert";

type UserInformationProps = {
  userFirstName?: string;
  genderOptions: Options;
  ethnicityOptions: Options;
  countryOptions: Options;
  devicesOptions: Options;
};

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

  return (
    <Button
      fullWidth
      aria-disabled={pending}
      btnLabel={pending ? "Validating your data..." : "Continue to next step"}
      customVariant="black"
      endContent={pending ? null : <FaChevronRight />}
      isDisabled={pending}
      isLoading={pending}
      type="submit"
    />
  );
}

function UserInformation({
  userFirstName,
  genderOptions,
  ethnicityOptions,
  countryOptions,
  devicesOptions,
}: UserInformationProps) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const queryString = searchParams.toString();

  const subtitle = userFirstName
    ? `Nearly there, ${userFirstName}! Just a few more questions about you.`
    : "Start your journey with People for Research.";

  const { control } = useForm<UserInformationData>({
    mode: "all",
    defaultValues: {
      ethnicOriginId: 0,
      genderId: 0,
      countryId: 0,
      postCode: "",
      devices: [],
    },
  });

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

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

  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={3}
        subtitle={subtitle}
        title="Finish account set up"
      />
      <div className="flex flex-col flex-grow">
        <div className="mt-4 space-y-0 ms-6 xl:ms-16">
          <SecondaryHeading title="About you" />
          <p className="font-noto text-xs text-others-shadowGray">
            This will help us invite you to the most suitable opportunities and
            customise your experience.
          </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="ethnicOriginId"
            render={({ fieldState, field }) => {
              const sections = ethnicityOptions.map((option: Option) => ({
                title: mapEthnicityCategory(option.title),
                category: mapEthnicityCategory(option.title),
              }));

              const uniqueSections = sections.filter(
                (section, index, self) =>
                  index ===
                  self.findIndex((s) => s.category === section.category),
              );

              return (
                <Select
                  control={control}
                  data={ethnicityOptions}
                  description="The race/ethnicity option that best represents you."
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Ethnicity"
                  mapCategory={mapEthnicityCategory}
                  name={field.name}
                  placeholder="Select your ethnicity"
                  sections={uniqueSections}
                  selectionMode="single"
                />
              );
            }}
          />
          {state.errors?.ethnicOriginId && (
            <FormError text={state.errors.ethnicOriginId} />
          )}
          <Controller
            control={control}
            name="genderId"
            render={({ field, fieldState }) => {
              return (
                <Select
                  control={control}
                  data={genderOptions}
                  description="The gender option that best represents you."
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Your gender"
                  name={field.name}
                  placeholder="Select your gender"
                />
              );
            }}
          />
          {state.errors?.genderId && <FormError text={state.errors.genderId} />}
          <Controller
            control={control}
            name="countryId"
            render={({ fieldState, field }) => {
              return (
                <Select
                  control={control}
                  data={countryOptions}
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Country"
                  name={field.name}
                  placeholder="Select your country"
                />
              );
            }}
          />
          {state.errors?.countryId && (
            <FormError text={state.errors.countryId} />
          )}
          <Controller
            control={control}
            name="postCode"
            render={({ fieldState, field }) => {
              return (
                <TextInput
                  isClearable
                  autoComplete={AUTOCOMPLETE_VALUES.POSTAL_CODE}
                  control={control}
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Postcode/Zip code"
                  name={field.name}
                  placeholder="e.g. SW1A 1AA"
                />
              );
            }}
          />
          {state.errors?.postCode && <FormError text={state.errors.postCode} />}
          <Controller
            control={control}
            name="devices"
            render={({ fieldState, field }) => {
              return (
                <Select
                  control={control}
                  data={devicesOptions}
                  description="Select all the devices you own."
                  fieldProps={field}
                  fieldState={fieldState}
                  label="Devices owned"
                  name={field.name}
                  placeholder="Select one or more devices you own"
                  selectionMode="multiple"
                />
              );
            }}
          />
          {state.errors?.devices && <FormError text={state.errors.devices} />}
          {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 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 UserInformation;
