import { useRef, useState, useEffect, useMemo } from 'react';
import { useIntl } from 'react-intl';
import '../common/theme.mjs';
import '../common/direction.mjs';
import '../common/propsValues/control.mjs';
import '../common/propsValues/breakpoint.mjs';
import { Size } from '../common/propsValues/size.mjs';
import '../common/propsValues/typography.mjs';
import '../common/propsValues/width.mjs';
import '../common/propsValues/type.mjs';
import '../common/propsValues/dateMode.mjs';
import '../common/propsValues/monthFormat.mjs';
import '../common/propsValues/position.mjs';
import '../common/propsValues/layouts.mjs';
import '../common/propsValues/status.mjs';
import '../common/propsValues/sentiment.mjs';
import '../common/propsValues/profileType.mjs';
import '../common/propsValues/variant.mjs';
import '../common/propsValues/scroll.mjs';
import '../common/propsValues/markdownNodeType.mjs';
import '../common/fileType.mjs';
import '@transferwise/icons';
import 'clsx';
import '../common/closeButton/CloseButton.messages.mjs';
import { jsxs, jsx } from 'react/jsx-runtime';
import { useInputAttributes, useFieldLabelRef } from '../inputs/contexts.mjs';
import { SelectInput, SelectInputOptionContent } from '../inputs/SelectInput.mjs';
import messages from './PhoneNumberInput.messages.mjs';
import countries from './data/countries.mjs';
import { setDefaultPrefix } from './utils/setDefaultPrefix/index.mjs';
import { isValidPhoneNumber } from './utils/isValidPhoneNumber/isValidPhoneNumber.mjs';
import { explodeNumberModel } from './utils/explodeNumberModel/index.mjs';
import { findCountryByPrefix } from './utils/findCountryByPrefix/index.mjs';
import { cleanNumber } from './utils/cleanNumber/cleanNumber.mjs';
import { sortArrayByProperty } from './utils/sortArrayByProperty/sortArrayByProperty.mjs';
import { groupCountriesByPrefix } from './utils/groupCountriesByPrefix/groupCountriesByPrefix.mjs';
import { excludeCountries } from './utils/excludeCountries/excludeCountries.mjs';
import { Input } from '../inputs/Input.mjs';

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.MEDIUM,
  placeholder,
  selectProps = defaultSelectProps,
  disabledCountries = defaultDisabledCountries
}) => {
  const countryCodeSelectRef = useRef(null);
  const phoneNumberInputRef = useRef(null);
  const inputAttributes = useInputAttributes({
    nonLabelable: true
  });
  const fieldLabelRef = useFieldLabelRef();
  const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
  const {
    locale,
    formatMessage
  } = useIntl();
  const createId = (customID, backup) => {
    if (customID) {
      return customID + (backup ? `-${backup}` : '');
    }
    const random = Math.random().toString(36).slice(2, 8);
    return `${backup}-${random}`;
  };
  // 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] = useState(() => {
    const cleanValue = initialValue ? cleanNumber(initialValue) : null;
    if (!cleanValue || !isValidPhoneNumber(cleanValue, 1)) {
      return {
        prefix: setDefaultPrefix(locale, countryCode),
        suffix: ''
      };
    }
    return explodeNumberModel(cleanValue);
  });
  const [broadcastedValue, setBroadcastedValue] = useState(null);
  const [suffixDirty, setSuffixDirty] = useState(false);
  useEffect(() => {
    if (internalValue.suffix) {
      setSuffixDirty(true);
    }
  }, [internalValue.suffix]);
  const countriesByPrefix = useMemo(() => groupCountriesByPrefix(sortArrayByProperty(excludeCountries(countries, 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 = explodeNumberModel(pastedValue);
    if (pastedNumber.prefix != null && countriesByPrefix.has(pastedNumber.prefix) && ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)) {
      setInternalValue(pastedNumber);
    }
  };
  useEffect(() => {
    if (broadcastedValue === null) {
      setBroadcastedValue(internalValue);
      return;
    }
    const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;
    const broadcastedPhoneNumber = `${broadcastedValue.prefix ?? ''}${broadcastedValue.suffix}`;
    if (internalPhoneNumber === broadcastedPhoneNumber) {
      return;
    }
    const newValue = isValidPhoneNumber(internalPhoneNumber) ? cleanNumber(internalPhoneNumber) : null;
    onChange(newValue, internalValue.prefix ?? '');
    setBroadcastedValue(internalValue);
  }, [onChange, broadcastedValue, internalValue]);
  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__*/jsxs("fieldset", {
    ...inputAttributes,
    "aria-labelledby": ariaLabelledBy,
    className: "tw-telephone",
    children: [/*#__PURE__*/jsx("label", {
      className: "sr-only",
      id: ids.countryCode.label,
      htmlFor: ids.countryCode.select,
      children: formatMessage(messages.countryCodeLabel)
    }), /*#__PURE__*/jsx("div", {
      className: "tw-telephone__country-select",
      children: /*#__PURE__*/jsx(SelectInput, {
        triggerRef: countryCodeSelectRef,
        placeholder: formatMessage(messages.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__*/jsx(SelectInputOptionContent, {
          title: prefix,
          note: withinTrigger ? undefined : countriesByPrefix.get(prefix)?.map(country => country.iso3).join(', ')
        }),
        filterable: true,
        filterPlaceholder: searchPlaceholder,
        disabled: disabled,
        size: size,
        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 ? findCountryByPrefix(prefix) : null;
          setInternalValue(prev => ({
            ...prev,
            prefix,
            format: country?.phoneFormat
          }));
        },
        onClose: () => {
          if (suffixDirty) {
            onBlur?.();
          }
        },
        ...selectProps
      })
    }), /*#__PURE__*/jsx("label", {
      className: "sr-only",
      id: ids.phoneNumber.label,
      htmlFor: ids.phoneNumber.input,
      children: formatMessage(messages.phoneNumberLabel)
    }), /*#__PURE__*/jsx("div", {
      className: "tw-telephone__number-input",
      children: /*#__PURE__*/jsx("div", {
        className: `input-group input-group-${size} ${disabled ? 'disabled' : ''}`,
        children: /*#__PURE__*/jsx(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?.()
        })
      })
    })]
  });
};

export { PhoneNumberInput as default };
//# sourceMappingURL=PhoneNumberInput.mjs.map
