export class MaskFormatter {
  constructor(mask) {
    this.mask = mask;
    this.maskChars = {
      '#': (char) => /\d/.test(char),
      'U': (char) => /[a-zA-Z]/.test(char),
      'L': (char) => /[a-zA-Z]/.test(char),
      'A': (char) => /[a-zA-Z0-9]/.test(char),
      '?': (char) => /[a-zA-Z]/.test(char),
      '*': () => true
    };
  }
  /**
   * Formata a string de acordo com a máscara
   * @param value String a ser formatada
   * @returns String formatada
   */
  format(value) {
    if (!value || !this.mask)
      return value;
    const cleanedValue = this.removeIncompatibleChars(value);
    let formattedValue = '';
    let valueIndex = 0;
    let maskIndex = 0;
    while (maskIndex < this.mask.length && valueIndex < cleanedValue.length) {
      const maskChar = this.mask[maskIndex];
      const inputChar = cleanedValue[valueIndex];
      if (maskChar === "'") {
        maskIndex++;
        if (maskIndex < this.mask.length) {
          formattedValue += this.mask[maskIndex];
          maskIndex++;
        }
        continue;
      }
      if (this.maskChars[maskChar]) {
        if (this.maskChars[maskChar](inputChar)) {
          if (maskChar === 'U') {
            formattedValue += inputChar.toUpperCase();
          }
          else if (maskChar === 'L') {
            formattedValue += inputChar.toLowerCase();
          }
          else {
            formattedValue += inputChar;
          }
          valueIndex++;
        }
        else {
          valueIndex++;
          continue;
        }
      }
      else {
        formattedValue += maskChar;
        if (inputChar === maskChar) {
          valueIndex++;
        }
      }
      maskIndex++;
    }
    return formattedValue;
  }
  /**
   * Remove caracteres que não são compatíveis com nenhuma posição da máscara
   */
  removeIncompatibleChars(value) {
    let cleanValue = '';
    for (let i = 0; i < value.length; i++) {
      const char = value[i];
      let isValidChar = false;
      for (const maskRule in this.maskChars) {
        if (this.maskChars[maskRule](char)) {
          isValidChar = true;
          break;
        }
      }
      if (!isValidChar) {
        for (let j = 0; j < this.mask.length; j++) {
          if (this.mask[j] === char && !this.maskChars[this.mask[j]]) {
            isValidChar = true;
            break;
          }
        }
      }
      if (isValidChar) {
        cleanValue += char;
      }
    }
    return cleanValue;
  }
  /**
   * Remove a máscara de uma string formatada
   * @param formattedValue String formatada
   * @returns String sem máscara
   */
  removeMask(formattedValue) {
    if (!formattedValue || !this.mask)
      return formattedValue;
    let cleanValue = '';
    let valueIndex = 0;
    let maskIndex = 0;
    while (valueIndex < formattedValue.length && maskIndex < this.mask.length) {
      const maskChar = this.mask[maskIndex];
      const inputChar = formattedValue[valueIndex];
      if (maskChar === "'") {
        maskIndex++;
        if (maskIndex < this.mask.length) {
          if (inputChar === this.mask[maskIndex]) {
            valueIndex++;
          }
          maskIndex++;
        }
        continue;
      }
      if (this.maskChars[maskChar]) {
        if (this.maskChars[maskChar](inputChar)) {
          cleanValue += inputChar;
        }
        valueIndex++;
      }
      else {
        if (inputChar === maskChar) {
          valueIndex++;
        }
      }
      maskIndex++;
    }
    while (valueIndex < formattedValue.length) {
      const remainingChar = formattedValue[valueIndex];
      if (/[a-zA-Z0-9]/.test(remainingChar)) {
        cleanValue += remainingChar;
      }
      valueIndex++;
    }
    return cleanValue;
  }
  /**
   * Retorna a máscara configurada
   */
  getMask() {
    return this.mask;
  }
  /**
   * Gera um placeholder baseado na máscara
   * @returns String com placeholder gerado
   */
  generatePlaceholder() {
    if (!this.mask)
      return '';
    let placeholder = '';
    let maskIndex = 0;
    while (maskIndex < this.mask.length) {
      const maskChar = this.mask[maskIndex];
      if (maskChar === "'") {
        maskIndex++;
        if (maskIndex < this.mask.length) {
          placeholder += this.mask[maskIndex];
          maskIndex++;
        }
        continue;
      }
      if (this.maskChars[maskChar]) {
        switch (maskChar) {
          case '#':
            placeholder += '0';
            break;
          case 'U':
          case 'L':
          case '?':
            placeholder += 'A';
            break;
          case 'A':
            placeholder += 'A';
            break;
          case '~':
            placeholder += '0';
            break;
          case '*':
            placeholder += '_';
            break;
          default:
            placeholder += '_';
            break;
        }
      }
      else {
        placeholder += maskChar;
      }
      maskIndex++;
    }
    return placeholder;
  }
}
