import Elemento from "../elemento.js";

import { fusionar } from "../../utilidades.js";

export default class Tabla extends Elemento {

  constructor({
    elemento = document.querySelector('table'),
    columnas = [],
    datos = [],
    configuracion = {}
  } = {}) {

    super({
      elemento: elemento,
      configuracion: fusionar({
        personalizada: {
          campo: { peticion: false }
        },

        keys: { className: 'table-active', tabIndex: -1 },
        stateSave: false,
        info: false,
        columns: [],
        ordering: true,
        order: [],
        pageLength: 500,
        scrollY: '45vh',
        scrollCollapse: true,
        deferRender: true,
        language: {
          sProcessing: 'Procesando...',
          sLengthMenu: 'Mostrar _MENU_ registros',
          sZeroRecords: 'No se encontraron resultados',
          sEmptyTable: 'Ningún dato disponible en esta tabla',
          sInfo: 'Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros',
          sInfoEmpty: 'Mostrando registros del 0 al 0 de un total de 0 registros',
          sInfoFiltered: '(filtrado de un total de _MAX_ registros)',
          sSearch: '',
          sInfoThousands: ',',
          sLoadingRecords: 'Cargando...',
          oPaginate: {
            sFirst: 'Primero',
            sLast: 'Último',
            sPrevious: '<i class="fa-solid fa-arrow-left"></i>',
            sNext: '<i class="fa-solid fa-arrow-right"></i>'
          },
          oAria: {
            sSortAscending: ': Activar para ordenar la columna de manera ascendente',
            sSortDescending: ': Activar para ordenar la columna de manera descendente'
          },
          buttons: { copy: 'Copiar', colvis: 'Visibilidad' }
        },
        dom: `ft<'row justify-content-between'<'col-auto'B><'col-auto'p>>`,
        buttons: [{
          extend: 'colvis',
          className: 'btn btn-primary buttons-colvis',
          text: 'Columnas <i class="fa-solid fa-eye"></i>',
        }, {
          extend: 'print',
          className: 'btn buttons-print',
          text: 'Imprimir <i class="fa-solid fa-print px-1"></i>',
          footer: true,
          exportOptions: {
            page: 'current',
            columns: ':visible'
          },
          action: async function(evento, instancia, boton, configuracion) {

            let
              ventana = {
                elemento: window.open('', '_blank',
                  `width = 992, height = 600, left = ${(window.screen.width - 992) / 2}, top = ${(window.screen.height - 600) / 2}`
                ),
                tabla: {
                  elemento: $(`
                    <table class="${instancia.table().node().className}">
                      <thead>
                        <tr>
                          <td colspan="100%">
                            <h1 class="fs-6 text-center text-white">${document.title}</h1>
                          </td>
                        </tr>
                        <tr></tr>
                      </thead>
                      <tbody></tbody>
                      <tfoot><tr></tr></tfoot>
                    </table>
                  `),
                  cabecera: {
                    fila: {
                      elemento: $(`
                        <tr>
                          <td class="px-0 pt-0 bg-transparent" colspan="100%">
                            <div class="d-flex justify-content-between align-items-center"></div>
                          </td>
                        </tr>
                      `)
                    },
                    columna: { contenido: '' },
                    parametros: []
                  },
                  filas: { cuerpo: '' },
                  columnas: { cabeza: '', pie: '' }
                }
              },
              calendario = new Date().toLocaleString(`es-419`, {
                hour12: true,
                day: '2-digit',
                month: '2-digit',
                year: 'numeric',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
              }).split(', '),
              fecha = calendario[0],
              hora = calendario[1]
            ;

            if (!ventana)
              return alert('¡HA OCURRIDO UN ERROR AL INTENTAR IMPRIMIR!')
            ;

            ventana.elemento.document.head.innerHTML = document.head.outerHTML;
            ventana.elemento.document.body.classList.add('dt-print-view');

            instancia.contenedor = instancia.table();

            instancia.formulario = $(instancia.contenedor.container().closest('form'));

            instancia.contenedor.header().querySelectorAll('tr:last-child th').forEach(elemento =>
              ventana.tabla.columnas.cabeza += `<th class="${elemento.className}">${elemento.innerHTML}</th>`
            );
            ventana.tabla.elemento.find('thead tr:last').append(ventana.tabla.columnas.cabeza);

            instancia.contenedor.body().querySelectorAll('tr').forEach(elemento =>
              ventana.tabla.filas.cuerpo += elemento.outerHTML
            );
            ventana.tabla.elemento.find('tbody').append(ventana.tabla.filas.cuerpo);

            instancia.contenedor.footer().querySelectorAll('tr th').forEach(elemento =>
              ventana.tabla.columnas.pie += `<th class="${elemento.className}">${elemento.innerHTML}</th>`
            );
            ventana.tabla.elemento.find('tfoot tr').append(ventana.tabla.columnas.pie);

            $(ventana.elemento.document.body).append(ventana.tabla.elemento);

            parametros(instancia.formulario[0]).forEach((valor, campo) => {

              if (valor) {

                campo = { nombre: campo, elemento: instancia.formulario.find(`[name=${campo}]`) }
                campo.etiqueta = campo.elemento.closest('.form-group').find('label').text();
                campo.valor = campo.elemento.is('select') ? campo.elemento[0].selectedOptions[0].text : valor;

                if (/fecha|desde|hasta/i.test(campo.nombre))
                  campo.valor = new Date(`${campo.valor} 00:00:00.000`).toLocaleDateString('uk').replaceAll('.', '/')
                ;

                ventana.tabla.cabecera.parametros.push({
                  campo: campo.etiqueta,
                  valor: campo.valor
                })

              }

            });

            await $.ajax({
              url: `${window.aplicacion.enlace}/ejecutar`,
              type: 'GET',
              data: {
                procedimiento: 'p_traer_cabecera_impresion',
                json_filtros: JSON.stringify(ventana.tabla.cabecera.parametros)
              },
              beforeSend: function(peticion, configuracion) {},
              success: (respuesta, estado, peticion) => {

                respuesta.forEach(parametro => {

                  switch (parametro.campo) {

                    case 'logo':

                      parametro.campo = '';

                      parametro.valor = `
                        <img
                          class="w-25 mb-1"
                          src="${window.aplicacion.enlace}/archivos/imagenes/logotipo/${parametro.valor}.png"
                        >
                      `

                    break;

                    case 'ancho':
                      return ventana.tabla.cabecera.columna.contenido = `<p style="width: ${parametro.valor}"></p>`
                    break;

                    case 'filtros':
                      return ventana.tabla.cabecera.fila.elemento.find(`td.bg-transparent`).append(`
                        <p class="m-1 mb-0 text-center" style="font-size: 10px">${parametro.valor}</p>
                      `)
                    break;

                  }

                  if (parametro.campo)
                    parametro.valor = `
                      <p class="d-flex justify-content-between">
                        <span>${parametro.campo}</span>
                        <span>${parametro.valor}</span>
                      </p>
                    `
                  else {

                    if (!parametro.valor) {

                        ventana.tabla.cabecera.fila.elemento.find('td.bg-transparent div.d-flex.justify-content-between').append(`<div class="d-flex flex-column">${ventana.tabla.cabecera.columna.contenido}</div>`);

                        ventana.tabla.cabecera.columna.contenido = '';

                        return

                    }

                    parametro.valor = `<p>${parametro.valor}</p>`

                  }

                  ventana.tabla.cabecera.columna.contenido += parametro.valor

                })

              },
              error: function(peticion, estado) {},
              complete: (peticion, estado) => {}
            });

            ventana.tabla.elemento.find('thead').prepend(ventana.tabla.cabecera.fila.elemento);

            ventana.tabla.cabecera.parametros.filtros &&
            ventana.tabla.elemento.find('thead tr td.bg-transparent').append(`
              <p class="m-1 mb-0 text-center" style="font-size: 10px">${ventana.tabla.cabecera.parametros.filtros}</p>
            `);

            setTimeout(() => ventana.elemento.print(), 500)

          }
        }, {
          extend: 'excelHtml5',
          className: 'btn buttons-excel',
          filename: () => {

            return prompt('Ingrese el nombre del archivo Excel', `Reportes de ${document.title.split('s de ')[1]}`)

          },
          text: 'EXCEL <i class="fa-regular fa-file-excel px-1"></i>',
          footer: true,
          exportOptions: { page: 'current', columns: ':visible' }
        }],
        initComplete: (configuracion, datos) => {

          let tabla = {
            contenedor: $('.dataTables_wrapper').has(this.tabla),
            campo: {
              busqueda: {
                contenedor: $(this.configuracion.campo.busqueda.peticion
                  ? `<form class="form" autocomplete="off">
                      <div class="input-group">

                        <div class="form-group">
                          <label for="">Buscar</label>
                        </div>

                        <button type="submit" class="btn btn-primary">
                          <i class="fa-solid fa-magnifying-glass"></i>
                        </button>

                      </div>
                    </form>
                  `
                  : `<div class="form-group">
                      <label for="">Buscar</label>
                    </div>
                  `
                )
              }
            }
          }

          tabla.campo.busqueda.elemento = tabla.contenedor.find('.dataTables_filter input');

          if (this.configuracion.campo.busqueda.peticion)
            tabla.campo.busqueda.elemento.attr({
              name: 'entidad',
              onkeyup: `
                event.keyCode === 13 &&
                !$(this).closest('.dataTables_wrapper').find('table tbody .table-active').length &&
                $(this).closest('form').submit()`
            })
          ;

          $(tabla.campo.busqueda.elemento).insertAfter(tabla.campo.busqueda.contenedor.find('label'));

          tabla.contenedor.find('.dataTables_filter').append(tabla.campo.busqueda.contenedor);

          tabla.contenedor.find('.dataTables_filter > label').remove();

          $(this.tabla)
            .parent()
            .parent()
            .find('.dataTables_scrollHead th:not(.d-none)')
            .first()
            .css('border-top-left-radius', '5px')
          ;

          $(this.tabla)
            .parent()
            .parent()
            .find('.dataTables_scrollHead th:not(.d-none)')
            .last()
            .css('border-top-right-radius', '5px')
          ;

          $(this.tabla)
            .parent()
            .parent()
            .find('.dataTables_scrollFoot th:not(.d-none)')
            .first()
            .css('border-bottom-left-radius', '5px')
          ;

          $(this.tabla)
            .parent()
            .parent()
            .find('.dataTables_scrollFoot th:not(.d-none)')
            .last()
            .css('border-bottom-right-radius', '5px')
          ;

          $('.dt-buttons').removeClass('flex-wrap')

        }
      }, configuracion)
    });

    this.columnas = columnas;

    this.datos = datos

  }

  async inicializar() {

    if (!this.elemento.length)
      this.elemento = $(this.elemento)
    ;

    this.cabeza = { elemento: this.elemento.find('thead') }
    this.cuerpo = { elemento: this.elemento.find('tbody') }
    this.pie = { elemento: this.elemento.find('tfoot') }

    if (this.columnas instanceof Array)
      this.configuracion.columns = this.columnas
    else if (this.columnas instanceof Object && Object.keys(this.columnas.peticion).length)
      this.configuracion.columns = await $.get(this.columnas.peticion.ruta, this.columnas.peticion.parametros)
    else
      this.configuracion.columns = this.cabeza.elemento.find('th').toArray()
    ;

  }

  async peticion() {

    this.instancia.clear();

    await this.instancia.rows.add($.get(this.columnas.peticion.ruta, this.columnas.peticion.parametros));

    this.instancia.draw()

  }

  async destruir() {

    this.elemento.is('dataTable') &&
    this.instancia.destroy() &&
    this.elemento.removeClass('dataTable');

    this.configuracion.columns = [];

    $([this.cabeza.elemento.find('tr'), this.cuerpo.elemento, this.pie.elemento]).children().remove()

  }

}