import { useTranslation } from "react-i18next";
import React, { Fragment } from "react";
import { usePlacesWidget } from "react-google-autocomplete";
import FormInputField from "../FormInput";
import isRegionRequired from "./isRegionRequired";
import { mergeRefs } from "../../utils/mergeRefs";
import adaptGooglePlacestoForm from "./adaptGooglePlacesToForm";
import PostalCode from "./PostalCode";
import CountryProvince from "./CountryProvince";

const BaseAddressInputs = ({
  register,
  errors: { firstName, lastName, address1, address2, country, postalCode, city, province },
  watch,
  trigger,
  setValue,
  googleAutocompleteApiKey,
  defaultCountry,
  countryNotice,
  countryList,
  hideName,
  address1PlaceHolderText,
  requireEmeaProvince = false,
}) => {
  const [selectedCountry, currentFirstName, currentLastName, currentAddress1, currentAddress2, currentCity] = watch([
    "country",
    "firstName",
    "lastName",
    "address1",
    "address2",
    "city",
  ]);

  const { t } = useTranslation("components-form");
  const { ref: address1Ref, ...registeredAddress1 } = register("address1", {
    required: t("Please enter your address."),
  });
  const { ref: placesRef } = usePlacesWidget({
    apiKey: googleAutocompleteApiKey,
    onPlaceSelected: place => {
      const adaptedAddress = adaptGooglePlacestoForm(place?.address_components, requireEmeaProvince);
      Object.keys(adaptedAddress).forEach(item => {
        if (item !== "province") {
          setValue(item, adaptedAddress[item]);
        }
      });
      if (adaptedAddress?.province) {
        setValue("province", adaptedAddress?.province); // must be called after country value is set
      }
      trigger(["country", "province", "city", "postalCode"]);
    },
    options: {
      types: ["address"],
      componentRestrictions: { country: selectedCountry },
    },
  });

  const firstNameIsValid = firstName === undefined;
  const lastNameIsValid = lastName === undefined;
  const address1IsValid = address1 === undefined;
  const cityIsValid = city === undefined;
  // For Countries that have no regions configured in Magento, the Province/State field will NOT show.
  const showRegion = isRegionRequired(selectedCountry, requireEmeaProvince);

  return (
    <Fragment>
      {!hideName && (
        <FormInputField
          id="firstName"
          data-testid="firstName"
          type="text"
          name="firstName"
          label={t("First Name")}
          required
          valid={firstNameIsValid && currentFirstName}
          {...register("firstName", {
            required: t("Please enter your first name."),
          })}
          error={firstName}
        />
      )}
      {!hideName && (
        <FormInputField
          id="lastName"
          data-testid="lastName"
          type="text"
          name="lastName"
          label={t("Last Name")}
          required
          valid={lastNameIsValid && currentLastName}
          {...register("lastName", {
            required: t("Please enter your last name."),
          })}
          error={lastName}
        />
      )}
      <FormInputField
        ref={mergeRefs(address1Ref, placesRef)}
        required
        label={t("Address")}
        error={address1}
        type="text"
        valid={address1IsValid && currentAddress1}
        data-testid="address1"
        {...registeredAddress1}
        placeholder={address1PlaceHolderText}
      />
      <FormInputField
        {...register("address2", {})}
        label={t("Address 2")}
        error={address2}
        type="text"
        valid={currentAddress2}
        placeholder={showRegion ? t("Apt, suite, PO Box, etc. (optional)") : t("Apt, suite etc. (optional)")}
      />
      <FormInputField
        {...register("city", {
          required: t("Please enter your city."),
        })}
        label={t("City")}
        required
        type="text"
        error={city}
        data-testid="city"
        valid={cityIsValid && currentCity}
      />
      <CountryProvince
        register={register}
        errors={{ country, province }}
        watch={watch}
        countryList={countryList}
        countryNotice={countryNotice}
        defaultCountry={defaultCountry}
        setValue={setValue}
        requireEmeaProvince={requireEmeaProvince}
      />
      <PostalCode register={register} errors={{ postalCode }} watch={watch} setValue={setValue} />
    </Fragment>
  );
};
export default BaseAddressInputs;
