/* eslint-disable react/prop-types */
import { InputAdornment } from '@mui/material';
import omit from 'lodash/omit';
import { useEffect, useRef, useCallback } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { defaultCountries, usePhoneInput } from 'react-international-phone';
import type { CountryIso2 } from 'react-international-phone';

import { useMount } from 'ahooks';
import FormInput from '../../components/input';
import { isValidCountry } from '../../libs/util';
import CountrySelect from '../../components/country-select';
import { getPhoneUtil } from '../../libs/phone-validator';

export default function PhoneInput({ ...props }) {
  const countryFieldName = props.countryFieldName || 'billing_address.country';
  const { control, getValues, setValue, trigger } = useFormContext();
  const values = getValues();

  const isUpdatingRef = useRef(false);

  const safeUpdate = useCallback((callback: () => void) => {
    if (isUpdatingRef.current) return;

    try {
      isUpdatingRef.current = true;
      callback();
    } finally {
      requestAnimationFrame(() => {
        isUpdatingRef.current = false;
      });
    }
  }, []);

  const { phone, handlePhoneValueChange, inputRef, country, setCountry } = usePhoneInput({
    defaultCountry: isValidCountry(values[countryFieldName]) ? values[countryFieldName] : 'us',
    value: values[props.name] || '',
    countries: defaultCountries,
    onChange: (data) => {
      safeUpdate(() => {
        setValue(props.name, data.phone);
        setValue(countryFieldName, data.country);
      });
    },
  });

  const userCountry = useWatch({ control, name: countryFieldName });
  useEffect(() => {
    if (!userCountry || userCountry === country) return;

    safeUpdate(() => {
      setCountry(userCountry);
    });
  }, [userCountry, country, setCountry, safeUpdate]);

  useMount(() => {
    getPhoneUtil().catch((err) => {
      console.error('Failed to preload phone validator:', err);
    });
  });

  const onCountryChange = useCallback(
    (v: CountryIso2) => {
      safeUpdate(() => {
        setCountry(v);
      });
    },
    [setCountry, safeUpdate]
  );

  const handleBlur = useCallback(() => {
    trigger(props.name);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.name]);

  return (
    // @ts-ignore
    <FormInput
      value={phone}
      onChange={handlePhoneValueChange}
      type="tel"
      inputRef={inputRef}
      onBlur={handleBlur}
      InputProps={{
        startAdornment: (
          <InputAdornment position="start" style={{ marginRight: '2px', marginLeft: '-8px' }}>
            <CountrySelect
              value={country}
              onChange={onCountryChange}
              name={countryFieldName}
              sx={{
                '&.MuiOutlinedInput-notchedOutline': {
                  borderColor: 'transparent !important',
                },
              }}
              showDialCode
            />
          </InputAdornment>
        ),
      }}
      {...omit(props, ['countryFieldName'])}
    />
  );
}
