import '@babel/polyfill';
import axios from 'axios';
import { renderHtml } from './helpers';

export class IbgeCities {
  /**
   *
   * @param {HTMLElement} zoneId select do estado
   * @param {HTMLElement} codigoMunicipio select do municipio
   * @param {HTMLElement} city input hidden da cidade
   */
  constructor(zoneId, codigoMunicipio, city, { baseUrl }) {
    this.zoneId = zoneId;
    this.codigoMunicipio = codigoMunicipio;
    this.city = city;
    this.baseUrl = baseUrl;
    this.citiesListContainer = null;
    this.init();
    this.initEvents();
  }
  init() {
    this.setCitiesListContainer();
    this.addZoneIdFirstOption();
    this.loadIbgeCitiesList.call(this, {
      codigo_municipio: this.zoneId.dataset.codigoMunicipio,
      city: this.zoneId.dataset.city,
    });

    this.zoneId.removeAttribute('data-codigo-municipio');
    this.zoneId.removeAttribute('data-city');
  }
  initEvents() {
    this.codigoMunicipio.addEventListener('change', this.setCityName.bind(this));
    this.zoneId.addEventListener('change', () => this.loadIbgeCitiesList());
  }
  setCitiesListContainer() {
    this.citiesListContainer = this.codigoMunicipio;
  }
  addZoneIdFirstOption() {
    this.firstOption = renderHtml('<option value="">--- Selecione ---</option>');

    const FIRST_OPTION = this.zoneId.item(0);
    if (FIRST_OPTION.value !== '') this.zoneId.insertBefore(this.firstOption, FIRST_OPTION);
  }
  setCityName() {
    this.city.value = this.codigoMunicipio.value
      ? this.codigoMunicipio.item(this.codigoMunicipio.selectedIndex).textContent
      : '';
  }
  triggerEventsOfSelects() {
    this.codigoMunicipio.dispatchEvent(new Event('change'));
  }
  getIbgeCitiesList() {
    return axios({
      headers: { 'content-type': 'application/x-www-form-urlencoded' },
      url: this.baseUrl + 'index.php?route=postcode/postcode/listCities',
      method: 'post',
      responseType: 'json',
      timeout: 10000,
      data: 'zone_id=' + this.zoneId.value,
    });
  }
  loadIbgeCitiesList(cityData = {}) {
    this.getIbgeCitiesList()
      .then(({ data }) => {
        const { cities } = data,
          { codigo_municipio } = cityData;

        this.citiesListContainer.innerHTML = this.renderOptions(cities, codigo_municipio);

        if (codigo_municipio) {
          this.triggerEventsOfSelects();
        }
      })
      .catch(error => console.error(error));
  }
  renderOptions(cities, codigo_municipio) {
    return `
      ${this.firstOption.outerHTML}
      ${Object.keys(cities)
        .map(
          key =>
            `<option value="${cities[key].codigo_municipio}" ${
              codigo_municipio == cities[key].codigo_municipio ? 'selected' : ''
            }>${cities[key].municipio}</option>`
        )
        .join('')}
    `;
  }
}

export class IbgeCitiesApp extends IbgeCities {
  setCitiesListContainer() {
    this.citiesListContainer = this.codigoMunicipio.parentNode.querySelector('.ftr-select__content');
  }
  setCityName() {
    const OPTION_SELECTED = this.citiesListContainer.querySelector('[data-selected=true]');
    this.city.value = this.codigoMunicipio.value && OPTION_SELECTED ? OPTION_SELECTED.textContent : '';
  }
  addZoneIdFirstOption() {}
  triggerEventsOfSelects() {
    this.zoneId.dispatchEvent(new Event('change', { bubbles: true }));
    this.codigoMunicipio.dispatchEvent(new Event('change', { bubbles: true }));
  }
  renderOptions(cities, codigo_municipio) {
    return Object.keys(cities)
      .map(
        key =>
          `<span class="ftr-select__content__item ftr-js-select__content__item tr-js-ripple-effect"
          data-value="${cities[key].codigo_municipio}"
          ${codigo_municipio == cities[key].codigo_municipio ? 'data-selected="true"' : ''}
        >${cities[key].municipio}</span>`
      )
      .join('');
  }
}
