import en from './locales/en';
import { LogUtility } from '../../utils/log';
import ChangeManager from '../change-manager/change-manager';
import { UPDATE_TRANSLATION } from '../change-manager/subject/static-subject/static-subject-title';
/**
 * Vega translation controller to control the internal text translation
 */
class InternalTranslationController {
  constructor() {
    this.resources = { en };
    this._currentLanguage = 'en';
  }
  /**
   * Get current language
   *
   * @returns {string} current language
   */
  get currentLanguage() {
    return this._currentLanguage;
  }
  /**
   * Initializes the translation controller with provided resources and language.
   *
   * @param {VegaTranslationConfig} config - The configuration object containing resources and initial language.
   */
  init({ resources, language }) {
    if (resources && Object.keys(resources).length > 0) {
      this.resources = resources;
    }
    else {
      LogUtility.warn(`Resources are empty. Falling back to default language "en".`);
      this.resources = { en };
    }
    if (language && language in this.resources) {
      this._currentLanguage = language;
    }
    else {
      LogUtility.warn(`Language "${language}" not found in resources. Falling back to default language "en".`);
      this._currentLanguage = 'en';
    }
    ChangeManager.notify(UPDATE_TRANSLATION, {});
  }
  /**
   * Changes the current language if it exists in the resources.
   *
   * @param {string} language - The language code to change to.
   */
  changeLanguage(language) {
    if (this.resources[language]) {
      this._currentLanguage = language;
      ChangeManager.notify(UPDATE_TRANSLATION, {});
    }
    else {
      LogUtility.warn(`Language "${language}" not found in resources.`);
    }
  }
  /**
   * Retrieves the translated string for the given key based on the current language.
   *
   * @param {string} key - The key for the translation.
   * @param {unknown[]} args - A list of values to replace in the translation string.
   * @returns {string} The translated string or the key itself if not found.
   */
  t(key, ...args) {
    const translation = this.resources[this._currentLanguage][key] || en[key] || key;
    return args.reduce((result, arg, index) => result.replace(new RegExp(`\\{${index}\\}`, 'g'), String(arg)), translation);
  }
  /**
   * Registers a component to the `connectedComponents` map, associating it with the component's tag name.
   * If the tag already exists, it adds the component to the existing set of components.
   *
   * @param {HTMLStencilElement} host - The component instance to register.
   */
  registerComponent(host) {
    const connectedComponents = InternalTranslationController.connectedComponents.get(host.tagName);
    if (connectedComponents) {
      connectedComponents.add(host);
    }
    else {
      InternalTranslationController.connectedComponents.set(host.tagName, new Set([host]));
    }
  }
  /**
   * Unregister a component from the `connectedComponents` map.
   *
   * @param {HTMLStencilElement} host - The component instance to unregister.
   */
  unRegisterComponent(host) {
    const connectedComponents = InternalTranslationController.connectedComponents.get(host.tagName);
    if (connectedComponents) {
      connectedComponents.delete(host);
    }
  }
  /**
   * Retrieves the map of connected components, where each entry associates a tag name with a set of components.
   *
   * @returns {Map<string, Set<HTMLElement>>} A map of connected components.
   */
  getConnectedComponents() {
    return InternalTranslationController.connectedComponents;
  }
  /**
   * Retrieves the preserved translated message segments.
   *
   * @param {string} key - The key for the translation.
   * @param {RegExp} preservePattern - the preserved regulation pattern to apply.
   * @param {unknown[]} args - A list of values to replace in the translation string.
   * @returns {PreservedTranslationOutput[]} An array of translated segments
   */
  tWithPreservedBlocks(key, preservePattern = /(\[[^\]]*\])/g, ...args) {
    // Use existing t method to handle translation and interpolation
    const interpolatedText = this.t(key, ...args);
    // Split by preserved blocks according to the pattern
    const segments = interpolatedText.split(preservePattern);
    // Convert to output format, marking preserved blocks
    return segments.map((segment) => {
      // Check if this segment matches the preserve pattern (by default: surrounded by square brackets)
      const isPreserved = preservePattern.test(segment);
      // For square brackets pattern, remove the brackets from content
      const content = isPreserved ? segment.substring(1, segment.length - 1) : segment;
      return {
        content,
        isPreserved,
      };
    });
  }
}
InternalTranslationController.connectedComponents = new Map();
export const VegaInternalTranslation = new InternalTranslationController();
