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

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

export class Chat {
  constructor(element) {
    this.element = element;
    this.box = ElementHelpers.getElementsByAttribute(this.attributes.box);
    this.header = ElementHelpers.getElementByAttribute(this.attributes.header);
    this.textarea = ElementHelpers.getElementByAttribute(
      this.attributes.textarea
    );
    this.button = ElementHelpers.getElementByAttribute(this.attributes.button);
    this.quickSuggestButton = ElementHelpers.getElementsByAttribute(
      this.attributes.quickSuggestButton
    );
    this.minimized = ElementHelpers.getElementByAttribute(
      this.attributes.minimized
    );
    this.close = ElementHelpers.getElementByAttribute(this.attributes.close);
    this.settingsButton = ElementHelpers.getElementsByAttribute(
      this.attributes.settingsButton
    );
    this.settings = ElementHelpers.getElementByAttribute(
      this.attributes.settings
    );
    this.languageSelector = ElementHelpers.getElementByAttribute(
      this.attributes.languageSelector
    );
    this.languageSaveButton = ElementHelpers.getElementByAttribute(
      this.attributes.languageSaveButton
    );
    this.languageNotification = ElementHelpers.getElementByAttribute(
      this.attributes.languageNotification
    );
    this.popup = ElementHelpers.getElementByAttribute(this.attributes.popup);
    this.popupShow = ElementHelpers.getElementByAttribute(
      this.attributes.popupShow
    );
    this.popupHide = ElementHelpers.getElementsByAttribute(
      this.attributes.popupHide
    );
    this.saveLanguageButton = ElementHelpers.getElementByAttribute(
      this.attributes.languageSaveButton
    );
    this.addEventHandlers();
  }

  /**
   * Declare classes
   */
  get classes() {
    return {
      dividerIsHidden: 'divider--is-hidden',
      displayNone: 'display-none',
      isActive: 'is-active'
    };
  }

  /**
   * Declare attribute constants
   */
  get attributes() {
    return {
      box: attributeBase + '-box',
      header: attributeBase + '-header',
      textarea: attributeBase + '-textarea',
      button: attributeBase + '-button',
      quickSuggest: attributeBase + '-quick-suggest',
      quickSuggestButton: attributeBase + '-quick-suggest-button',
      minimized: attributeBase + '-minimized',
      close: attributeBase + '-close',
      content: attributeBase + '-content',
      settingsButton: attributeBase + '-settings-button',
      settings: attributeBase + '-settings',
      languageSelector: attributeBase + '-language-selector',
      languageSaveButton: attributeBase + '-language-save-button',
      languageNotification: attributeBase + '-language-notification',
      popupShow: attributeBase + '-popup-show',
      popupHide: attributeBase + '-popup-hide',
      popup: attributeBase + '-popup',
      saveLanguageButton: attributeBase + '-save-language'
    };
  }

  /**
   * Add event handlers
   */
  addEventHandlers() {
    this.handleHeaderDivider();
    this.toggleInputButton();
    this.quickSuggestButtonsHandler();
    this.openChat();
    this.closeChat();
    this.userInputToSpeechBubble();
    this.toggleSettingsHandler();
    this.languageSelectorHandler();
    this.popUpHandler();
    this.languageSaveButtonHandler();
  }

  /**
   * Adds a divider to the header when scrolling in the chat box
   */
  handleHeaderDivider() {
    this.box.forEach(element => {
      element.addEventListener('scroll', () => {
        const scrollTop = element.scrollTop;

        const header = element.previousElementSibling;

        const headerClassList = header.classList;

        if (scrollTop > 1) {
          headerClassList.remove(this.classes.dividerIsHidden);
        } else {
          headerClassList.add(this.classes.dividerIsHidden);
        }
      });
    });
  }

  /**
   * Toggles the button from enabled to disabled when typing in the textarea
   */
  toggleInputButton() {
    this.textarea.addEventListener('input', () => {
      if (this.textarea.value.length === 0) {
        this.button.disabled = true;
      } else {
        this.button.disabled = false;
      }
    });
  }

  /**
   * Opens the chat box when clicking on the chat-minimized button
   */
  openChat() {
    if (this.minimized) {
      const _this = this;

      this.minimized.addEventListener('click', function() {
        this.classList.add(_this.classes.displayNone);
        _this.element.classList.remove(_this.classes.displayNone);
      });
    }
  }

  /**
   * Closes the chatbox when clicking on the close button
   */
  closeChat() {
    if (this.close && this.minimized) {
      this.close.addEventListener('click', (e) => {
        e.preventDefault();
        this.element.classList.add(this.classes.displayNone);
        this.minimized.classList.remove(this.classes.displayNone);
      });
    }
  }

  /**
   * Creates a speech bubbel when clicking on the quick suggestion buttons
   */
  quickSuggestButtonsHandler() {
    if (this.quickSuggestButton) {
      this.quickSuggestButton.forEach(item => {
        item.addEventListener('click', () => {
          const text = item.innerHTML;
          const parentElement = item.parentElement;
          parentElement.removeAttribute(this.attributes.content);
          parentElement.removeAttribute(this.attributes.quickSuggest);
          parentElement.setAttribute(this.attributes.content, 'user');
          parentElement.innerHTML = `<div class="chat__content chat__content--user speech-bubble speech-bubble--user">
            ${text}
          </div>`;

          this.box.scrollTop = this.box.scrollHeight;
        });
      });
    }
  }

  /**
   * Changes the input text to a user speech bubble when clicking on the button
   */
  userInputToSpeechBubble() {
    const createSpeechBubble = e => {
      if (e.type === 'click' || e.key === 'Enter') {
        const inputText = this.textarea.value;

        // Remove the quickSuggestionButtons if they exist;
        const quickSuggestion = ElementHelpers.getElementByAttribute(
          this.attributes.quickSuggest
        );
        if (quickSuggestion) {
          quickSuggestion.remove();
        }

        // If the last element is from the bot it should add a --first modifier to it
        const box = ElementHelpers.getElementByAttribute(
          this.attributes.box,
          'chat'
        );

        box.innerHTML = box.innerHTML += `<div class='chat-content__wrapper' data-rs-chat-content='user'><div class="chat__content chat__content--user speech-bubble speech-bubble--user">
        ${inputText}</div></div>`;

        if (box.lastElementChild) {
          const islastElementFromBot =
            box.lastElementChild.getAttribute(this.attributes.content) ===
            'bot';

          if (islastElementFromBot) {
            box.lastElementChild.classList.add('chat-content__wrapper--first');
          }
        }

        // Empty the text box
        this.textarea.value = '';
        // Set height back to original'
        this.textarea.style.height = 'auto';

        // Disable the button
        this.button.disabled = true;
        // Scroll to the bottom of the box
        box.scrollTop = box.scrollHeight;
      }
    };

    this.button.addEventListener('click', createSpeechBubble);
    this.textarea.addEventListener('keydown', createSpeechBubble);
  }

  toggleSettingsHandler() {
    this.settingsButton.forEach(item => {
      item.addEventListener('click', () => {
        this.openAndCloseSettings();
      });
    });
  }

  languageSelectorHandler() {
    this.languageSelector.addEventListener('change', () => {
      const value = this.languageSelector.value;
      if (value !== '') {
        this.languageSaveButton.removeAttribute('disabled');
        this.languageNotification.classList.remove('display-none');
      } else {
        this.languageSaveButton.setAttribute('disabled', 'disabled');
        this.languageNotification.classList.add('display-none');
      }
    });
  }

  popUpHandler() {
    this.popupShow.addEventListener('click', () => {
      this.popup.classList.add('is-active');
    });

    this.popupHide.forEach(element => {
      element.addEventListener('click', () => {
        this.popup.classList.remove('is-active');
      });
    });
  }

  languageSaveButtonHandler() {
    this.saveLanguageButton.addEventListener('click', () => {
      const box = ElementHelpers.getElementByAttribute(
        this.attributes.box,
        'chat'
      );

      // Empty the box content
      box.innerHTML = '';

      this.openAndCloseSettings();
    });
  }

  openAndCloseSettings() {
    const settingsPanelClasses = this.settings.classList;
    if (!settingsPanelClasses.contains(this.classes.isActive)) {
      settingsPanelClasses.add(this.classes.isActive);
    } else {
      settingsPanelClasses.remove(this.classes.isActive);
    }
  }

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