import { useState, useEffect, useMemo } from 'react';
import { useIntl } from 'react-intl';
import { useInputAttributes } 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 { jsxs, jsx } from 'react/jsx-runtime';
import { Size } from '../common/propsValues/size.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 inputAttributes = useInputAttributes({
    nonLabelable: true
  });
  const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
  const {
    locale,
    formatMessage
  } = useIntl();
  const [internalValue, setInternalValue] = useState(() => {
    const cleanValue = initialValue ? cleanNumber(initialValue) : null;
    if (!cleanValue || !isValidPhoneNumber(cleanValue)) {
      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]);
  return /*#__PURE__*/jsxs("div", {
    role: "group",
    ...inputAttributes,
    "aria-labelledby": ariaLabelledBy,
    className: "tw-telephone",
    children: [/*#__PURE__*/jsx("div", {
      className: "tw-telephone__country-select",
      children: /*#__PURE__*/jsx(SelectInput, {
        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,
        onChange: prefix => {
          const country = prefix != null ? findCountryByPrefix(prefix) : null;
          setInternalValue(prev => ({
            ...prev,
            prefix,
            format: country?.phoneFormat
          }));
        },
        onClose: () => {
          if (suffixDirty) {
            onBlur?.();
          }
        },
        ...selectProps
      })
    }), /*#__PURE__*/jsx("div", {
      className: "tw-telephone__number-input",
      children: /*#__PURE__*/jsx("div", {
        className: `input-group input-group-${size}`,
        children: /*#__PURE__*/jsx("input", {
          id: id,
          autoComplete: "tel-national",
          name: "phoneNumber",
          inputMode: "numeric",
          value: internalValue.suffix,
          className: "form-control",
          disabled: disabled,
          required: required,
          placeholder: placeholder,
          onChange: onSuffixChange,
          onPaste: onPaste,
          onFocus: onFocus,
          onBlur: () => onBlur?.()
        })
      })
    })]
  });
};

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