import {nativeVlElement, define} from '/node_modules/vl-ui-core/dist/vl-core.js';
import '/node_modules/vl-ui-titles/dist/vl-titles.js';

/**
 * VlSearchFilter
 * @class
 * @classdesc De search filter laat de gebruiker toe om de zoekresulten te verfijnen.
 *
 * @extends HTMLDivElement
 * @mixes nativeVlElement
 *
 * @property {string} data-vl-alt - Alternatieve (transparante) achtergrond.
 * @property {string} data-vl-mobile-modal - Activeert geoptimaliseerde weergave voor op mobiele toestellen.
 * @property {string} [data-vl-mobile-modal-title=Filter] - De titel van deze search filter op mobiele toestellen indien niet gedeclareerd wordt het data-vl-title attribuut of de default genomen.
 * @property {string} data-vl-title - De titel van deze search filter.
 *
 * @see {@link https://www.github.com/milieuinfo/webcomponent-vl-ui-search-filter/releases/latest|Release notes}
 * @see {@link https://www.github.com/milieuinfo/webcomponent-vl-ui-search-filter/issues|Issues}
 * @see {@link https://webcomponenten.omgeving.vlaanderen.be/demo/vl-search-filter.html|Demo}
 */
export class VlSearchFilter extends nativeVlElement(HTMLDivElement) {
  static get _observedAttributes() {
    return ['title'];
  }

  static get _observedClassAttributes() {
    return ['alt', 'mobile-modal'];
  }

  constructor() {
    super();
    this.observer = this.__observeChildElements(() => this.__processClasses());
  }

  connectedCallback() {
    this.classList.add('vl-search-filter');
    this.__processClasses();
  }

  __observeChildElements(callback) {
    const observer = new MutationObserver(callback);
    observer.observe(this, {childList: true});
    return observer;
  }

  disconnectedCallback() {
    this.observer.disconnect();
  }

  __processClasses() {
    this.querySelectorAll('form').forEach((form) => form.classList.add(`${this._elementPrefix}form`));
    this.querySelectorAll('form > section').forEach((section) => section.classList.add(`${this._elementPrefix}section`));
    this.querySelectorAll('form > section > h2').forEach((title) => title.classList.add(`${this._elementPrefix}section-title`));
    this.querySelectorAll('form > section > div').forEach((field) => field.classList.add(`${this._elementPrefix}field`));
    this.querySelectorAll('form > section > div > label').forEach((label) => label.classList.add(`${this._elementPrefix}field__label`));
    this.querySelectorAll('form > div').forEach((div) => div.classList.add(`${this._elementPrefix}field`));

    if (this._footerElement) {
      this._footerElement.classList.add(`${this._elementPrefix}footer`);
    }
  }

  get formData() {
    return new FormData(this.querySelector('form'));
  }

  get _classPrefix() {
    return this._elementName + '--';
  }

  get _elementPrefix() {
    return this._elementName + '__';
  }

  get _elementName() {
    return 'vl-search-filter';
  }

  get _titleElement() {
    return this._introElement || this._mobileModalTitleElement;
  }

  get _introElement() {
    return this.querySelector(`.${this._elementPrefix}intro`);
  }

  get _headerElement() {
    return this.querySelector(`.${this._elementPrefix}header-modal`);
  }

  get _mobileModalTitleElement() {
    return this._headerElement ? this._headerElement.querySelector('h2') : undefined;
  }

  get _formElement() {
    return this.querySelector('form');
  }

  get _footerElement() {
    return this.querySelector(`form ~ div:not(.${this._elementPrefix}footer-modal):last-child`);
  }

  get _footerModalElement() {
    return this.querySelector(`.${this._elementPrefix}footer-modal`);
  }

  get _submitButton() {
    let button;
    if (this._formElement) {
      button = this._formElement.querySelector(':scope > div button[type="submit"]');
    }
    if (!button && this._footerModalElement) {
      button = this._footerModalElement.querySelector('button');
    }
    return button;
  }

  get _title() {
    return this.getAttribute('data-vl-title');
  }

  get _mobileModalTitle() {
    return this.getAttribute('data-vl-mobile-modal-title') || this._title || 'Filter';
  }

  _titleChangedCallback(oldValue, newValue) {
    if (this._titleElement == null) {
      this.insertBefore(this.__createTitleElement(), this.firstChild);
    } else {
      this._titleElement.textContent = newValue;
    }
  }

  _mobileModalTitleChangedCallback(oldValue, newValue) {
    if (this._mobileModalTitleElement) {
      this._mobileModalTitleElement.textContent = newValue;
    }
  }

  _mobileModalChangedCallback(oldValue, newValue) {
    if (newValue != undefined) {
      this.__enableModal();
    } else {
      this.__disableModal();
    }
  }

  __createTitleElement() {
    const title = document.createElement('p');
    title.classList.add(`${this._elementPrefix}intro`);
    title.textContent = this._title;
    return title;
  }

  __enableModal() {
    this.__convertFooterToHeader();
    this.__convertIntroToHeaderTitle();
    this.__convertSubmitButtonContainerToModalFooter();
  }

  __disableModal() {
    this.__convertHeaderTitleToIntro();
    this.__convertHeaderToFooter();
    this.__convertModalFooterToSubmitButtonContainer();
  }

  __convertFooterToHeader() {
    const header = this._footerElement || document.createElement('div');
    this.__prepareMobileModal(header);
    this.insertBefore(header, this.firstChild);
  }

  __convertIntroToHeaderTitle() {
    const title = document.createElement('h2', 'vl-h2');
    title.textContent = this._mobileModalTitle;
    this._headerElement.insertBefore(title, this._headerElement.firstChild);
    if (this._introElement) {
      this._introElement.remove();
    }
  }

  __convertSubmitButtonContainerToModalFooter() {
    if (this._submitButton) {
      this.hidden = false;
      this.__prepareSubmitButton();
      this._submitButton.addEventListener('click', () => {
        this.removeAttribute('data-vl-mobile-modal');
        this.hidden = true;
      }, {once: true});
      this._element.appendChild(this._submitButton.parentElement);
    }
  }

  __convertHeaderTitleToIntro() {
    if (this._title) {
      this.insertBefore(this.__createTitleElement(), this.firstChild);
    }

    if (this._mobileModalTitleElement) {
      this._mobileModalTitleElement.remove();
    }
  }

  __convertHeaderToFooter() {
    const footer = this._headerElement;
    if (footer) {
      this.__prepareMobileModal(footer);
      this._element.appendChild(footer);
    }
  }

  __convertModalFooterToSubmitButtonContainer() {
    if (this._submitButton) {
      this._formElement.appendChild(this._submitButton.parentElement);
      this.__prepareSubmitButton();
    }
  }

  __prepareMobileModal(element) {
    element.classList.toggle(`${this._elementPrefix}footer`);
    element.classList.toggle(`${this._elementPrefix}header-modal`);
    [...element.children].forEach((child) => child.classList.toggle(`${this._elementPrefix}header__clear`));
  }

  __prepareSubmitButton() {
    this._submitButton.toggleAttribute('data-vl-block');
    const container = this._submitButton.parentElement;
    container.classList.toggle(`${this._elementPrefix}footer-modal`);
    container.classList.toggle(`${this._elementPrefix}field`);
  }
}

define('vl-search-filter', VlSearchFilter, {extends: 'div'});