import FormSelect from "../FormSelect";
import React, { useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import isRegionRequired from "./isRegionRequired";

/**
 * A hook to de-select the province if the country changes
 */
const useResetProvince = ({
  countryList,
  selectedCountry,
  selectedProvince,
  setValue,
  availableProvinceList,
  provinceName,
}) => {
  useEffect(() => {
    const selectedCountryInfo = countryList.find(({ id }) => id === selectedCountry);
    const shouldResetProvince =
      !selectedCountryInfo || !selectedCountryInfo?.available_regions?.find(({ code }) => code === selectedProvince);
    if (shouldResetProvince) {
      setValue(provinceName, undefined);
      setValue("regionId", undefined);
    }
  }, [selectedCountry, availableProvinceList, selectedProvince, countryList, setValue]);
};

const CountryProvince = ({
  register,
  errors,
  watch,
  countryList,
  defaultCountry,
  countryNotice,
  setValue,
  countryName = "country",
  provinceName = "province",
  requireEmeaProvince,
}) => {
  const { t } = useTranslation("components-form");
  const countryError = errors[countryName];
  const provinceError = errors[provinceName];
  const countryIsValid = countryError === undefined;
  const provinceIsValid = provinceError === undefined;
  const [selectedCountry, selectedProvince] = watch([countryName, provinceName]);

  useEffect(() => {
    if (!selectedCountry) {
      setValue(countryName, defaultCountry);
    }
  }, [defaultCountry, selectedCountry]);
  const availableProvinceList = useMemo(() => {
    if (!selectedCountry) {
      return [];
    }
    const availableProvinces = countryList.find(({ id }) => id === selectedCountry)?.available_regions;
    if (availableProvinces) {
      return availableProvinces;
    }
    return [];
  }, [selectedCountry, countryList]);
  const shouldShowProvince = !(selectedCountry && !availableProvinceList.length);
  const isProvinceRequired = isRegionRequired(selectedCountry, requireEmeaProvince);
  useResetProvince({
    countryList,
    selectedCountry,
    selectedProvince,
    setValue,
    availableProvinceList,
    provinceName,
  });
  useEffect(() => {
    if (selectedProvince && availableProvinceList.length > 0) {
      const region = availableProvinceList.find(region => region.code === selectedProvince);
      setValue("regionId", region?.id);
    }
  }, [selectedProvince, availableProvinceList]);
  return (
    <>
      <FormSelect
        id={countryName}
        {...register(countryName, {
          required: t("Please select your country."),
        })}
        label={t("Country")}
        error={countryError}
        required
        labelText={t("Country")}
        data-testid={countryName}
        disallowEmptyOption={true}
        valid={countryIsValid && selectedCountry}
        list={countryList.map(({ full_name_locale, id }) => ({ label: full_name_locale, value: id }))}
      />
      {countryNotice}
      {shouldShowProvince && (
        <>
          <FormSelect
            id={`${provinceName}-${selectedCountry}`}
            {...register(provinceName, {
              required: isProvinceRequired && t("Please enter your province or state."),
            })}
            label={t("Province / State")}
            error={provinceError}
            required={isProvinceRequired}
            valid={provinceIsValid && selectedProvince}
            list={availableProvinceList.map(({ code, name }) => ({ value: code, label: name }))}
          />
          <input {...register("regionId")} type="hidden" />
        </>
      )}
    </>
  );
};

export default CountryProvince;
