// {} Librerías

// ! Utilidades
import { peticion } from '../../utilidades.js';

// ! Procedimiento
import procedimiento from '../configuracion/procedimientos.js';

// {}
export default class Selector {

  constructor({selector, configuracion}) {

    this.selector = {
      elemento: selector,
      grupo: selector.closest('.input-group'),
      boton: {},
      opcion: {
        valor: selector.getAttribute('value') ?? selector.value,
        indice: selector.selectedIndex + 1 ? selector.selectedIndex : 0,
        elemento: selector.selectedOptions[0]
      },
      deshabilitado: selector.disabled,
      configuracion: {
        minimumResultsForSearch: aplicacion.configuracion.cantidad_registros_mostrar_busqueda_selector,
        templateResult: (selector, opcion) => {

          if (selector.element && selector.element.nodeName === 'OPTION' && !selector.id)
            selector.text = ' '

          return selector.text

        },
        language: {
          noResults: () => { return '' },
          searching: () => { return 'Buscando...' },
          loadingMore: () => { return 'Cargando más resultados...' },
        }
      }
    }

    if (this.selector.elemento.hasAttribute('value'))
      this.selector.elemento.removeAttribute('value')
    ;

    if (this.selector.grupo) {

      this.selector.boton = {
        crear: this.selector.grupo.querySelector('[data-accion=crear]'),
        actualizar: this.selector.grupo.querySelector('.botonActualizar')
      }

    }

    // this.selector.configuracion.ajax = {
    //   url: `${window.aplicacion.enlace}/ejecutar`,
    //   data: () => this.selector.peticion.parametro,
    //   processResults: (respuesta) => {

    //     respuesta = respuesta.map((selector, indice) => {

    //       return {id: selector.valor, text: selector.descripcion}

    //     });

    //     return { results: respuesta }

    //   }
    // }

    Object.assign(this.selector.configuracion, configuracion);

    this.parametros()

  }

  parametros() {

    Object.assign(this.selector, {
      peticion: {
        parametro: { procedimiento: this.selector.elemento.dataset.peticionProcedimiento ?? 'p_traer_registros_consulta_principal' }
      }
    });

    let parametros = this.selector.elemento.dataset.peticionParametros;

    if (parametros)
      parametros.split(';').forEach((valor, iteracion) => {

        var [parametro, valor] = valor.trim().replaceAll('`', "'").split(':');

        valor = valor.trim();

        this.selector.peticion.parametro[parametro] = valor.startsWith('eval(') ? eval(valor) : valor

      })
    else
      Object.assign(this.selector.peticion.parametro, {
        origen_registros: this.selector.elemento.dataset.peticionTabla,
        campos: procedimiento.p_traer_registros_consulta_principal.parametro.campos(
          this.selector.elemento.dataset.peticionTabla,
          this.selector.elemento.name.replace('id_', '')
        )
      })
    ;

    this.selector.peticion.parametro['0'] = 0

  }

  async peticion(tipo) {

    if (tipo === 'opciones')
      await $.ajax({
        url: window.aplicacion.enlace + '/ejecutar',
        data: this.selector.peticion.parametro,
        beforeSend: (peticion, configuracion) => {

          // ?
          this.selector.elemento.disabled = true;

          // ?
          if (this.selector.boton.crear)
            this.selector.boton.crear.disabled = true
          ;

          // ?
          if (this.selector.boton.actualizar) {

            this.selector.boton.actualizar.disabled = true;

            this.selector.boton.actualizar.firstChild.classList.add('fa-spin')

          }

          // ?
          $(this.selector.elemento.options).remove()

        },
        success: (respuesta, estado, peticion) => {

          // ?
          if (
            this.selector.peticion.parametro.procedimiento === 'p_traer_registros_consulta_principal' &&
            respuesta.length > 1
          )
            this.selector.elemento.innerHTML = '<option></option>'
          else if (respuesta[0].descripcion === '' && respuesta.length === 2)
            respuesta = [respuesta[1]]
          ;

          // ? Iteración para recorrer la respuesta
          respuesta.forEach((registro, iteracion) => {

            // *
            let opcion = $(
              registro.descripcion === ''
                ? '<option></option>'
                : `<option value="${registro.valor}">${registro.descripcion}</option>`
            )[0];

            // *
            if (registro.campos) {

              opcion.dataset.campos = registro.campos;

              opcion.dataset.camposValores = registro.valores_campos ?? ''

            }

            // *
            if (Number(registro.valor_predeterminado)) {

              this.selector.opcion.valor = registro.valor;

              if (!this.selector.elemento.dataset.campoValorPredeterminado)
                this.selector.elemento.dataset.campoValorPredeterminado = registro.valor
              ;

              // console.log(this.selector.elemento.querySelector(`[value="${this.selector.elemento.dataset.campoValorPredeterminado}"]`))
// console.log(document.querySelector(registro.campo).dataset.campoValorPredeterminado, this.selector.elemento.querySelector(`[value="${this.selector.elemento.dataset.campoValorPredeterminado}"]`))
              // if (registro.campo)
              //   document.querySelector(registro.campo).dataset.campoValorPredeterminado =
              //   this.selector.elemento.querySelector(`[value="${this.selector.elemento.dataset.campoValorPredeterminado}"]`).value

            }

            // *
            if (registro.campos_habilitar)
              opcion.dataset.camposHabilitar = registro.campos_habilitar
            ;

            // *
            if (registro.campos_deshabilitar)
              opcion.dataset.camposDeshabilitar = registro.campos_deshabilitar
            ;

            // *
            if (registro.atributos)
              $.each($(`<option ${registro.atributos}></option>`)[0].attributes, (indice, atributo) =>
                opcion.setAttribute(atributo.name, atributo.value)
              )
            ;

            // *
            $(this.selector.elemento).append(opcion)

          });

          // ?
          if (this.selector.deshabilitado || this.selector.elemento.options.length <= 1)
            this.selector.elemento.disabled = true
          else {

            this.selector.elemento.disabled = false;

            if (this.selector.boton.crear)
              this.selector.boton.crear.disabled = false

          }

          // ?
          if (this.selector.boton.actualizar) {

            this.selector.boton.actualizar.disabled = false;

            this.selector.boton.actualizar.firstChild.classList.remove('fa-spin')

          }

          // ?
          if (this.selector.elemento.attributes.value?.nodeValue)
            this.selector.opcion.valor = this.selector.elemento.attributes.value.nodeValue
          ;

          // ?
          if (this.selector.opcion.valor)
            this.selector.elemento.value = this.selector.opcion.valor
          else
            this.selector.elemento.selectedIndex = this.selector.opcion.indice
          ;

          $(this.selector.elemento).change();

          if (this.selector.elemento.selectedOptions.length && this.selector.elemento.selectedOptions[0].dataset.campo)
            document
              .querySelector(this.selector.elemento.selectedOptions[0].dataset.campo)
              .dataset.campoValorPredeterminado = this.selector.elemento.selectedOptions[0].dataset.campoValor

        },
        error: function(peticion, estado) {},
        complete: function(peticion, estado) {}
      })

  }

  async inicializar() {

    await $(this.selector.elemento).select2(this.selector.configuracion);

    $(this.selector.elemento).on('select2:open select2:close', function(evento) {

      let selector = {}

      if (evento.type === 'select2:open') {

        selector = {
          campo: { busqueda: $('.select2-search__field').addClass('form-control') },
          opcion: {
            seleccionada: $('.select2-results__option--selected'),
            alto: $('.select2-results__option:first').innerHeight()
          }
        }

        selector.contenedor = {
          opciones: {
            elemento: $('.select2-results__options'),
            alto: Number(window.aplicacion.configuracion.cantidad_registros_visible_selector) * selector.opcion.alto
          }
        }

        selector.contenedor.opciones.elemento.css('max-height', `${selector.contenedor.opciones.alto}px`);

        // if (!selector.opcion.seleccionada.text().trim())
        //   setTimeout(() => selector.contenedor.opciones.elemento[0].scrollTo(0, selector.opcion.alto), 1)

      } else {

        selector.formulario = {
          elemento: $(this).closest('form'),
          campo: {}
        }
        selector.formulario.campos = {
          habilitados: selector.formulario.elemento.find('[name]:visible:enabled:not(button)')
        }

        selector.formulario.campo.enfocar = { indice: selector.formulario.campos.habilitados.toArray().indexOf(this) + 1 }

        selector.formulario.campo.enfocar.elemento = selector.formulario.campos.habilitados.eq(selector.formulario.campo.enfocar.indice);

        selector.formulario.campo.enfocar.elemento.focus().select()

      }

    })

  }

  async destruir() {

    if (this.selector.elemento.className.includes('select2-hidden-accessible'))
      await $(this.selector.elemento).select2('destroy')
    ;

    $(this.selector.elemento).unbind('select2:open select2:close')

  }

}
