/**
 * character-count.js
 * Script to count characters on input field and at styling to it
 */

import ElementHelpers from '../helpers/element-helpers';

/**
 * Declare constants
 */
const attributeBase = 'data-rs-character-counter';

export class CharacterCounter {
  constructor(element) {
    this.element = element;
    this.counterOutput = ElementHelpers.getElementByAttribute(
      this.attributes.output,
      this.element.getAttribute(attributeBase)
    );
    this.maxLength = this.element.getAttribute(this.attributes.maxLength);
    this.labels = this.element.getAttribute(this.attributes.labels);
    this.setCounterOutput();
    this.addEventHandlers();
  }

  /**
   * Declare attribute constants
   */
  get attributes() {
    return {
      output: `${attributeBase}-output`,
      maxLength: `${attributeBase}-maxlength`,
      labels: `${attributeBase}-labels`
    };
  }

  /**
   * Declare classes
   */
  get classes() {
    return {
      textNegative: 'text--negative'
    };
  }

  /**
   * Add event handlers
   */
  addEventHandlers() {
    this.element.addEventListener('input', () => {
      this.setCounterOutput();
    });
  }

  /**
   * Set counter output
   */
  setCounterOutput() {
    const defaultLabels = {
      characters: 'characters',
      charactersLeft: '@characters characters left'
    };

    const labels = this.labels ? JSON.parse(this.labels) : defaultLabels;

    if (this.counterOutput) {
      let { characters, charactersLeft } = labels;

      const characterCount = this.maxLength - this.element.value.length;

      if (characterCount >= 0) {
        charactersLeft = charactersLeft.replace('@characters', characterCount);

        this.counterOutput.classList.remove(this.classes.textNegative);
        this.counterOutput.innerText = charactersLeft;
      } else {
        this.counterOutput.classList.add(this.classes.textNegative);
        this.counterOutput.innerText = `${characterCount} ${characters}`;
      }
    }
  }

  /**
   * Get selector
   */
  static getSelector() {
    return `[${attributeBase}]`;
  }
}
