class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBuilder {
  constructor(elements) {
    super(elements);
    this.elements = elements;

    this.elements.positionalAttrSelection.addEventListener('change', (event) => {
      this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
      if (event.target.value !== 'empty-token') {
        this.toggleClass([event.target.value], 'hide', 'remove');
        this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
        this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
      }
      if (event.target.value === 'word' || event.target.value === 'lemma') {
        this.toggleClass(['input-field-options'], 'hide', 'remove');
      } else if (event.target.value === 'empty-token'){
        this.addTokenToQuery();
      } else {
        this.toggleClass(['input-field-options'], 'hide', 'add');
      }
    });

    // Options for positional attribute selection
    document.querySelectorAll('.positional-attr-options-action-button[data-options-action]').forEach(button => {
      button.addEventListener('click', () => {this.actionButtonInOptionSectionHandler(button.dataset.optionsAction);});
    });

    // Eventlistener for kind of token 
    this.elements.tokenSubmitButton.addEventListener('click', () => {this.addTokenToQuery();});
    this.elements.wordInput.addEventListener('input', () => {this.optionToggleHandler();});
    this.elements.lemmaInput.addEventListener('input', () => {this.optionToggleHandler();});
    this.elements.englishPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
    this.elements.germanPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
    this.elements.simplePosSelection.addEventListener('change', () => {this.optionToggleHandler();});
  }

  tokenInputCheck() {
    let input;

    if (!document.querySelector('[data-toggle-area="word"]').classList.contains('hide')) {
      input = this.elements.wordInput;
    } else if (!document.querySelector('[data-toggle-area="lemma"]').classList.contains('hide')){
      input = this.elements.lemmaInput;
    } else if (!document.querySelector('[data-toggle-area="english-pos"]').classList.contains('hide')){
      input = this.elements.englishPosSelection;
    } else if (!document.querySelector('[data-toggle-area="german-pos"]').classList.contains('hide')){
      input = this.elements.germanPosSelection;
    } else if (!document.querySelector('[data-toggle-area="simple-pos"]').classList.contains('hide')){
      input = this.elements.simplePosSelection;
    }

    return input;
  }

  optionToggleHandler() {
    let input;
    input = this.tokenInputCheck();

    if (input.value === '' || input.value === 'default') {
      this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
    } else {
      this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'remove');
    }
  }

  disableTokenSubmit() {
    this.elements.isTokenQueryInvalid = true;
    this.elements.tokenSubmitButton.classList.add('red');
    this.elements.noValueMessage.classList.remove('hide');
    setTimeout(() => {
      this.elements.tokenSubmitButton.classList.remove('red');
    }, 500);
    setTimeout(() => {
      this.elements.noValueMessage.classList.add('hide');
    }, 3000);
  }

  tokenChipFactory(prettyQueryText, tokenText) {
    tokenText = encodeURI(tokenText);
    let builderElement;
    let queryChipElement;
    builderElement = document.createElement('div');
    builderElement.innerHTML = `
    <div class='chip col s2 l2' style='margin-top:20px;' data-tokentext='${tokenText}'>
      ${prettyQueryText}
      <i class='material-icons close'>close</i>
    </div>`;
    queryChipElement = builderElement.firstElementChild;
    this.elements.tokenQuery.appendChild(queryChipElement);
  }

  addTokenToQuery() {
    let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
    let tokenQueryPrettyText = '';
    let tokenQueryCQLText = '';
    this.elements.isTokenQueryInvalid = false;

    this.elements.tokenQuery.childNodes.forEach(element => {
      tokenQueryPrettyText += ' ' + element.firstChild.data + ' ';
      tokenQueryCQLText += decodeURI(element.dataset.tokentext);
    });

    switch (this.elements.positionalAttrSelection.value) {
      case 'word':
        if (this.elements.wordInput.value === '') {
          this.disableTokenSubmit();
        } else {
          tokenQueryPrettyText += `word=${this.elements.wordInput.value}${c}`;
          tokenQueryCQLText += `word="${this.elements.wordInput.value}"${c}`;
          this.elements.wordInput.value = '';
        }
        break;
      case 'lemma':
        if (this.elements.lemmaInput.value === '') {
          this.disableTokenSubmit();
        } else {
          tokenQueryPrettyText += `lemma=${this.elements.lemmaInput.value}${c}`;
          tokenQueryCQLText += `lemma="${this.elements.lemmaInput.value}"${c}`;
          this.elements.lemmaInput.value = '';
        }
        break;
      case 'english-pos':
        if (this.elements.englishPosSelection.value === 'default') {
          this.disableTokenSubmit();
        } else {
          tokenQueryPrettyText += `pos=${this.elements.englishPosSelection.value}`;
          tokenQueryCQLText += `pos="${this.elements.englishPosSelection.value}"`;
          this.elements.englishPosSelection.value = '';
        }
        break;
      case 'german-pos':
        if (this.elements.germanPosSelection.value === 'default') {
          this.disableTokenSubmit();
        } else {
          tokenQueryPrettyText += `pos=${this.elements.germanPosSelection.value}`;
          tokenQueryCQLText += `pos="${this.elements.germanPosSelection.value}"`;
          this.elements.germanPosSelection.value = '';
        }
        break;
      case 'simple-pos':
        if (this.elements.simplePosSelection.value === 'default') {
          this.disableTokenSubmit();
        } else {
          tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
          tokenQueryCQLText += `simple_pos='${this.elements.simplePosSelection.value}'`;
          this.elements.simplePosSelection.value = '';
        }
        break;
      case 'empty-token':
        tokenQueryPrettyText += 'empty token';
      default:
        break;
    }

    // isTokenQueryInvalid looks if a valid value is passed. If the input fields/dropdowns are empty (isTokenQueryInvalid === true), no token is added.
    if (this.elements.isTokenQueryInvalid === false) {
      tokenQueryCQLText = '[' + tokenQueryCQLText + ']';
      this.queryChipFactory('token', tokenQueryPrettyText, tokenQueryCQLText);
      this.resetPositionalAttrModal();
      this.elements.positionalAttrModal.close();
    }
  }

  actionButtonInOptionSectionHandler(elem) {
    let input = this.tokenInputCheck();
    switch (elem) {
      case 'option-group':
        input.value  += '(option1|option2)';
        let firstIndex = input.value.indexOf('option1');
        let lastIndex = firstIndex + 'option1'.length;
        input.focus();
        input.setSelectionRange(firstIndex, lastIndex);
        break;
      case 'wildcard-char':
        input.value += '.';
        break;
      case 'and':
        this.conditionHandler('and', " & ");
        break;
      case 'or':
        this.conditionHandler('or', " | ");
        break;
      default:
        break;
    }
    this.optionToggleHandler();
  }

  characterIncidenceModifierHandler(elem) {
    // For word and lemma, the incidence modifiers are inserted in the input field. For the others, one or two chips are created which contain the respective value of the token and the incidence modifier.
    switch (this.elements.positionalAttrSelection.value) {
      case 'empty-token':
        this.tokenChipFactory(elem.innerText, elem.dataset.token);
        break;
      case 'english-pos':
        this.tokenChipFactory(`pos=${this.elements.englishPosSelection.value}`, `pos="${this.elements.englishPosSelection.value}"`);
        this.tokenChipFactory(elem.innerText, elem.dataset.token);
        break;
      case 'german-pos':
        this.tokenChipFactory(`pos=${this.elements.germanPosSelection.value}`, `pos="${this.elements.germanPosSelection.value}"`);
        this.tokenChipFactory(elem.innerText, elem.dataset.token);
        break;
      case 'simple-pos':
        this.tokenChipFactory(`simple_pos=${this.elements.simplePosSelection.value}`, `simple_pos="${this.elements.simplePosSelection.value}"`);
        this.tokenChipFactory(elem.innerText, elem.dataset.token);
        break;     
      default:
        let input = this.tokenInputCheck();
        input.value += elem.dataset.token;
        break;
    }

    if (this.elements.positionalAttrSelection.value !== "word" && this.elements.positionalAttrSelection.value !== "lemma") {
      this.toggleClass([this.elements.positionalAttrSelection.value], "hide", "add");
    }
  }

  characterNMSubmitHandler(modalId) {
    let modal = document.querySelector(`#${modalId}`);
    let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value;
    let input_m = modal.querySelector('.n-m-input[data-value-type="m"]') || undefined;
    input_m = input_m !== undefined ? ',' + input_m.value : '';
    let input = `${input_n}${input_m}`;

    let instance = M.Modal.getInstance(modal);
    instance.close();
    
    switch (this.elements.positionalAttrSelection.value) {
      case 'word':
        this.elements.wordInput.value += '{' + input + '}';
        break;
      case 'lemma':
        this.elements.lemmaInput.value += '{' + input + '}';
        break;
      default:
        break;
    }
  }

  conditionHandler(conditionText, conditionQueryContent) {
    let tokenQueryPrettyText;
    let tokenQueryCQLText;
    let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';

    switch (this.elements.positionalAttrSelection.value) {
      case 'word':
        tokenQueryPrettyText = `word=${this.elements.wordInput.value}${c}`;
        tokenQueryCQLText = `word="${this.elements.wordInput.value}"${c}`;
        this.elements.wordInput.value = '';
        break;
      case 'lemma':
        tokenQueryPrettyText = `lemma=${this.elements.lemmaInput.value}${c}`;
        tokenQueryCQLText = `lemma="${this.elements.lemmaInput.value}"${c}`;
        this.elements.lemmaInput.value = '';
        break;
      case 'english-pos':
        tokenQueryPrettyText = `pos=${this.elements.englishPosSelection.value}`;
        tokenQueryCQLText = `pos="${this.elements.englishPosSelection.value}"`;
        this.elements.englishPosSelection.value = '';
        break;
      case 'german-pos':
        tokenQueryPrettyText = `pos=${this.elements.germanPosSelection.value}`;
        tokenQueryCQLText = `pos="${this.elements.germanPosSelection.value}"`;
        this.elements.germanPosSelection.value = '';
        break;
      case 'simple-pos':
        tokenQueryPrettyText = `simple_pos=${this.elements.simplePosSelection.value}`;
        tokenQueryCQLText = `simple_pos="${this.elements.simplePosSelection.value}"`;
        this.elements.simplePosSelection.value = '';
        break;
      default:
        break;
    }

    // Deleting the options which do not make sense in the context of the condition like "word" AND "word". Also sets selection default.
    let selectionDefault = "word";
    let optionDeleteList = ['empty-token'];
    if (conditionText === 'and') {
      if (this.elements.positionalAttrSelection.value === 'word' || this.elements.positionalAttrSelection.value === 'lemma') {
        selectionDefault = "english-pos";
        optionDeleteList.push('word', 'lemma');
      } else if (this.elements.positionalAttrSelection.value === 'english-pos' || this.elements.positionalAttrSelection.value === 'german-pos') {
        optionDeleteList.push('english-pos', 'german-pos');
      } else {
        optionDeleteList.push('simple-pos');
      }
    }

    this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);

    this.tokenChipFactory(tokenQueryPrettyText, tokenQueryCQLText);
    this.tokenChipFactory(conditionText, conditionQueryContent);
    this.setTokenSelection(selectionDefault, optionDeleteList);
  }

  setTokenSelection(selection, optionDeleteList) {
    optionDeleteList.forEach(option => {
      this.elements.positionalAttrSelection.querySelector(`option[value=${option}]`).remove();
    });

    this.resetMaterializeSelection([this.elements.positionalAttrSelection], selection);

    this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
    this.toggleClass([selection], 'hide', 'remove');
    this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
    if (selection === "word" || selection === "lemma") {
      this.toggleClass(['input-field-options'], 'hide', 'remove');
    } else {
      this.toggleClass(['input-field-options'], 'hide', 'add');
    }
  }

  
  resetPositionalAttrModal() {
    let originalSelectionList = 
      `
        <option value="word" selected>word</option>
        <option value="lemma" >lemma</option>
        <option value="english-pos">english pos</option>
        <option value="german-pos">german pos</option>
        <option value="simple-pos">simple_pos</option>
        <option value="empty-token">empty token</option>
      `;
    this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
    this.elements.tokenQuery.innerHTML = '';
    this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
    this.toggleClass(['word', 'input-field-options'], 'hide', 'remove');
    this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');

    document.querySelector('#corpus-analysis-concordance-positional-attr-selection option[value="word"]').selected = true;

    this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
    this.resetMaterializeSelection([this.elements.positionalAttrSelection], "word");
  }
}