'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var reactIntl = require('react-intl');
require('../common/theme.js');
require('../common/direction.js');
require('@transferwise/neptune-tokens');
require('../common/propsValues/control.js');
var size = require('../common/propsValues/size.js');
require('../common/propsValues/typography.js');
require('../common/propsValues/width.js');
require('../common/propsValues/type.js');
require('../common/propsValues/dateMode.js');
require('../common/propsValues/monthFormat.js');
require('../common/propsValues/position.js');
require('../common/propsValues/layouts.js');
require('../common/propsValues/status.js');
require('../common/propsValues/sentiment.js');
require('../common/propsValues/profileType.js');
require('../common/propsValues/variant.js');
require('../common/propsValues/scroll.js');
require('../common/propsValues/markdownNodeType.js');
require('../common/fileType.js');
require('@transferwise/formatting');
require('@transferwise/icons');
require('clsx');
require('../common/closeButton/CloseButton.messages.js');
var jsxRuntime = require('react/jsx-runtime');
var contexts = require('../inputs/contexts.js');
var InputGroup = require('../inputs/InputGroup.js');
var SelectInput = require('../inputs/SelectInput/SelectInput.js');
require('../dateLookup/dateTrigger/DateTrigger.messages.js');
require('@headlessui/react');
var SelectInputOptionContent = require('../inputs/SelectInput/OptionContent/SelectInputOptionContent.js');
require('merge-props');
require('../header/Header.js');
require('virtua');
var Input = require('../inputs/Input.js');
require('../inputs/SelectInput/SelectInput.messages.js');
var PhoneNumberInput_messages = require('./PhoneNumberInput.messages.js');
var countries = require('./data/countries.js');
var index = require('./utils/setDefaultPrefix/index.js');
var isValidPhoneNumber = require('./utils/isValidPhoneNumber/isValidPhoneNumber.js');
var index$1 = require('./utils/explodeNumberModel/index.js');
var index$2 = require('./utils/findCountryByPrefix/index.js');
var cleanNumber = require('./utils/cleanNumber/cleanNumber.js');
var sortArrayByProperty = require('./utils/sortArrayByProperty/sortArrayByProperty.js');
var groupCountriesByPrefix = require('./utils/groupCountriesByPrefix/groupCountriesByPrefix.js');
var excludeCountries = require('./utils/excludeCountries/excludeCountries.js');

const ALLOWED_PHONE_CHARS = /^$|^[\d-\s]+$/;
const defaultSelectProps = {};
const defaultDisabledCountries = [];
const PhoneNumberInput = ({
  id,
  'aria-labelledby': ariaLabelledByProp,
  required,
  disabled,
  initialValue,
  onChange,
  onFocus,
  onBlur,
  countryCode,
  searchPlaceholder = 'Prefix',
  size: size$1 = size.Size.MEDIUM,
  placeholder,
  selectProps = defaultSelectProps,
  disabledCountries = defaultDisabledCountries
}) => {
  const countryCodeSelectRef = React.useRef(null);
  const phoneNumberInputRef = React.useRef(null);
  const inputAttributes = contexts.useInputAttributes({
    nonLabelable: true
  });
  const {
    paddingInlineStart
  } = InputGroup.useInputPaddings();
  const hasInputGroupAddonStart = paddingInlineStart != null;
  const fieldLabelRef = contexts.useFieldLabelRef();
  const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
  const {
    locale,
    formatMessage
  } = reactIntl.useIntl();
  const [randomId] = React.useState(() => Math.random().toString(36).slice(2, 8));
  const createId = (customID, backup) => {
    if (customID) {
      return customID + (backup ? `-${backup}` : '');
    }
    return `${backup}-${randomId}`;
  };
  // Link the first non-disabled input to the the Field label, if present
  const ids = {
    countryCode: {
      label: createId(id, 'country-code-label'),
      select: createId(id, 'country-code-select')
    },
    phoneNumber: {
      label: createId(id, 'phone-number-label'),
      input: createId(id, id ? '' : 'phone-number-input')
    }
  };
  const [internalValue, setInternalValue] = React.useState(() => {
    const cleanValue = initialValue ? cleanNumber.cleanNumber(initialValue) : null;
    if (!cleanValue || !isValidPhoneNumber.isValidPhoneNumber(cleanValue, 1)) {
      return {
        prefix: index.setDefaultPrefix(locale, countryCode),
        suffix: ''
      };
    }
    return index$1.explodeNumberModel(cleanValue);
  });
  const broadcastedValueRef = React.useRef(internalValue);
  const [suffixDirty, setSuffixDirty] = React.useState(false);
  React.useEffect(() => {
    if (!suffixDirty && internalValue.suffix) {
      // eslint-disable-next-line react-hooks/set-state-in-effect -- Tracking when suffix becomes dirty
      setSuffixDirty(true);
    }
  }, [internalValue.suffix, suffixDirty]);
  const countriesByPrefix = React.useMemo(() => groupCountriesByPrefix.groupCountriesByPrefix(sortArrayByProperty.sortArrayByProperty(excludeCountries.excludeCountries(countries.default, disabledCountries), 'iso3')), [disabledCountries]);
  const onSuffixChange = event => {
    const suffix = event.target.value;
    if (ALLOWED_PHONE_CHARS.test(suffix)) {
      setInternalValue(prev => ({
        ...prev,
        suffix
      }));
    }
  };
  const onPaste = event => {
    if (!event.nativeEvent.clipboardData) {
      return;
    }
    const pastedValue = (event.nativeEvent.clipboardData.getData('text/plain') || '').replace(/(\s|-)+/g, '');
    const pastedNumber = index$1.explodeNumberModel(pastedValue);
    if (pastedNumber.prefix != null && countriesByPrefix.has(pastedNumber.prefix) && ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)) {
      setInternalValue(pastedNumber);
    }
  };
  React.useEffect(() => {
    const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;
    const broadcastedPhoneNumber = `${broadcastedValueRef.current.prefix ?? ''}${broadcastedValueRef.current.suffix}`;
    if (internalPhoneNumber === broadcastedPhoneNumber) {
      return;
    }
    const newValue = isValidPhoneNumber.isValidPhoneNumber(internalPhoneNumber) ? cleanNumber.cleanNumber(internalPhoneNumber) : null;
    onChange(newValue, internalValue.prefix ?? '');
    broadcastedValueRef.current = internalValue;
  }, [onChange, internalValue]);
  React.useEffect(() => {
    const labelRef = fieldLabelRef?.current;
    if (labelRef) {
      const handleLabelClick = () => {
        if (!selectProps.disabled) {
          countryCodeSelectRef.current?.click();
        } else {
          phoneNumberInputRef.current?.focus();
        }
      };
      labelRef.addEventListener('click', handleLabelClick);
      return () => {
        labelRef?.removeEventListener('click', handleLabelClick);
      };
    }
  }, [fieldLabelRef, selectProps.disabled]);
  return /*#__PURE__*/jsxRuntime.jsxs("fieldset", {
    ...inputAttributes,
    "aria-labelledby": ariaLabelledBy,
    className: "tw-telephone",
    children: [/*#__PURE__*/jsxRuntime.jsx("label", {
      className: "sr-only",
      id: ids.countryCode.label,
      htmlFor: ids.countryCode.select,
      children: formatMessage(PhoneNumberInput_messages.default.countryCodeLabel)
    }), /*#__PURE__*/jsxRuntime.jsx("div", {
      className: `tw-telephone__country-select${hasInputGroupAddonStart ? ' tw-telephone__country-select--with-input-group-addon-start' : ''}`,
      children: /*#__PURE__*/jsxRuntime.jsx(SelectInput.SelectInput, {
        triggerRef: countryCodeSelectRef,
        placeholder: formatMessage(PhoneNumberInput_messages.default.selectInputPlaceholder),
        items: [...countriesByPrefix].map(([prefix, countries]) => ({
          type: 'option',
          value: prefix,
          filterMatchers: [prefix, ...countries.map(country => country.name), ...countries.map(country => country.iso3)]
        })),
        value: internalValue.prefix,
        renderValue: (prefix, withinTrigger) => /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContent.SelectInputOptionContent, {
          title: prefix,
          note: withinTrigger ? undefined : countriesByPrefix.get(prefix)?.map(country => country.iso3).join(', ')
        }),
        filterable: true,
        filterPlaceholder: searchPlaceholder,
        disabled: disabled,
        size: size$1,
        id: ids.countryCode.select,
        UNSAFE_triggerButtonProps: {
          id: ids.countryCode.select,
          'aria-labelledby': ids.countryCode.label,
          'aria-describedby': undefined,
          'aria-invalid': undefined
        },
        onChange: prefix => {
          const country = prefix != null ? index$2.findCountryByPrefix(prefix) : null;
          setInternalValue(prev => ({
            ...prev,
            prefix,
            format: country?.phoneFormat
          }));
        },
        onClose: () => {
          if (suffixDirty) {
            onBlur?.();
          }
        },
        ...selectProps
      })
    }), /*#__PURE__*/jsxRuntime.jsx("label", {
      className: "sr-only",
      id: ids.phoneNumber.label,
      htmlFor: ids.phoneNumber.input,
      children: formatMessage(PhoneNumberInput_messages.default.phoneNumberLabel)
    }), /*#__PURE__*/jsxRuntime.jsx("div", {
      className: "tw-telephone__number-input",
      children: /*#__PURE__*/jsxRuntime.jsx("div", {
        className: `input-group input-group-${size$1} ${disabled ? 'disabled' : ''}`,
        children: /*#__PURE__*/jsxRuntime.jsx(Input.Input, {
          ref: phoneNumberInputRef,
          id: ids.phoneNumber.input,
          autoComplete: "tel-national",
          name: "phoneNumber",
          inputMode: "numeric",
          value: internalValue.suffix,
          disabled: disabled,
          required: required,
          placeholder: placeholder,
          "aria-labelledby": ids.phoneNumber.label,
          onChange: onSuffixChange,
          onPaste: onPaste,
          onFocus: onFocus,
          onBlur: () => onBlur?.()
        })
      })
    })]
  });
};

exports.default = PhoneNumberInput;
//# sourceMappingURL=PhoneNumberInput.js.map
