import _defineProperty from "@babel/runtime/helpers/defineProperty";
// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
import React, { PureComponent, isValidElement, cloneElement, createContext, useContext } from 'react';
import PropTypes from 'prop-types';

const applyParams = (message, params = {}) => {
  const result = [];
  let hasElements = false;
  let m;

  while (m = message.match(/%%(\w+)%%/)) {
    const {
      index = 0
    } = m;

    if (index > 0) {
      result.push(message.substr(0, index));
    }

    const param = params[m[1]];

    if (param === undefined) {
      result.push(m[0]);
    } else if (typeof param === 'object' && /*#__PURE__*/isValidElement(param)) {
      result.push( /*#__PURE__*/cloneElement(param, {
        key: m[1]
      }));
      hasElements = true;
    } else {
      result.push(param);
    }

    message = message.substr(index + m[0].length);
  }

  if (message !== '') {
    result.push(message);
  }

  return hasElements ? result : result.join('');
};

const getMessage = (fullKey, messages) => {
  const [key, ...rest] = fullKey.split('.');
  const message = messages[key];

  if (typeof message === 'object' && rest.length) {
    return getMessage(rest.join('.'), message);
  }

  return messages[fullKey];
};

const createTranslate = messages => // eslint-disable-next-line default-param-last
(key, params = {}, fallback) => {
  if (typeof key !== 'string') {
    return '';
  }

  let message = getMessage(key, messages);

  if (typeof message !== 'string') {
    message = typeof fallback === 'string' ? fallback : `[${key}]`;
  }

  return applyParams(message, params);
};

const LocaleContext = /*#__PURE__*/createContext(undefined);
export const useTranslate = namespace => {
  const context = useContext(LocaleContext);
  return (key, params, fallback) => {
    if (context) {
      const {
        locale: {
          lmsg
        }
      } = context;
      return lmsg(namespace ? `${namespace}.${key}` : key, params, fallback);
    }

    return typeof fallback === 'string' ? applyParams(fallback, params) : `[${key}]`;
  };
};

/**
 * LocaleProvider provides a uniform localization support for built-in text of components.
 * @since 0.0.42
 */
class LocaleProvider extends PureComponent {
  getChildContext() {
    const {
      messages
    } = this.props;
    return {
      locale: {
        lmsg: createTranslate(messages)
      }
    };
  }

  render() {
    const {
      children
    } = this.props;
    return /*#__PURE__*/React.createElement(LocaleContext.Provider, {
      value: this.getChildContext()
    }, children);
  }

}

_defineProperty(LocaleProvider, "childContextTypes", {
  locale: PropTypes.object
});

export default LocaleProvider;