"use strict";

import CustomDataTable from "../../../../assets/js/app/CustomDataTable.js?v=2.0.0";
import {
  mostrarMensajes,
  mostrarToastify,
  obtenerHTMLBotonesDropdown,
} from "../../../../assets/js/app/funcionesGenerales.js?v=2.0.0";
import metodosFormularios from "../../../../assets/js/app/metodosFormularios.js?v=2.0.0";
import HoraExtra from "../models/horaExtraModel.js?v=2.0.0";
import TipoPlanilla from "../models/tipoPlanillaModel.js?v=2.0.0";
import tipoHorasExtra from "../models/tipoHorasextraModel.js?v=2.0.0";
import OtroIngreso from "../models/otroIngresoModel.js?v=2.0.0";
import tiposOtrosIngresos from "../models/tipoOtrosIngresosModel.js?v=2.0.0";

!(function () {
  document
    .getElementById("cbo-tipoPlanilla")
    .addEventListener("change", function () {
      document.getElementById("btn-nuevaCargaHoraExtra").disabled = false;
      document.getElementById("btn-nuevaCargaOtrosIngresos").disabled = false;
    });

  document
    .getElementById("file-horasExtras")
    .addEventListener("change", function (e) {
      configCargaHorasExtras.verificarArchivo();
    });

  document
    .getElementById("file-otrosIngresos")
    .addEventListener("change", function (e) {
      configCargaOtrosIngresos.verificarArchivo();
    });

  document
    .getElementById("btn-formatoHorasExtras")
    .addEventListener("click", function (e) {
      $("#modal-formatoHorasExtras").modal("show");
    });

  document
    .getElementById("btn-formatoOtrosIngresos")
    .addEventListener("click", function (e) {
      $("#modal-formatoOtrosIngresos").modal("show");
    });

  document
    .getElementById("cargaHoraExtra-form")
    .addEventListener("submit", function (e) {
      e.preventDefault();
      configCargaHorasExtras.guardar();
    });

  document
    .getElementById("cargaOtrosIngresos-form")
    .addEventListener("submit", function (e) {
      e.preventDefault();
      configCargaOtrosIngresos.guardar();
    });

  document
    .getElementById("ubicacion-form")
    .addEventListener("submit", function (e) {
      e.preventDefault();
      configuracion.buscar();
    });

  document
    .getElementById("btn-limpiarCargaHoraExtra")
    .addEventListener("click", function (e) {
      configCargaHorasExtras.cancelar();
    });

  document
    .getElementById("btn-limpiarCargaOtrosIngresos")
    .addEventListener("click", function (e) {
      configCargaOtrosIngresos.cancelar();
    });

  document
    .getElementById("btn-nuevaCargaHoraExtra")
    .addEventListener("click", function (e) {
      configCargaHorasExtras.editar({});
    });

  document
    .getElementById("btn-nuevaCargaOtrosIngresos")
    .addEventListener("click", function (e) {
      configCargaOtrosIngresos.editar({});
    });

  $('#contenedor-horasExtras button[data-bs-toggle="tab"]').on(
    "shown.bs.tab",
    function (e) {
      let botonesHorasExtras = document.getElementById("btns-cargaHoraExtra"),
        botonesNuevoHoraExtra = document.getElementById(
          "btns-nuevaCargaHoraExtra"
        );

      botonesHorasExtras.classList.add("d-none");
      botonesNuevoHoraExtra.classList.add("d-none");

      switch (e.target.id) {
        case "historicoHorasExtras-tab":
          botonesNuevoHoraExtra.classList.remove("d-none");
          break;
        case "cargaHorasExtras-tab":
          botonesHorasExtras.classList.remove("d-none");
          break;
      }
    }
  );

  $('#contenedor-otrosIngresos button[data-bs-toggle="tab"]').on(
    "shown.bs.tab",
    function (e) {
      let botonesOtrosIngresos = document.getElementById(
          "btns-cargaOtrosIngresos"
        ),
        botonesNuevoOtrosIngresos = document.getElementById(
          "btns-nuevaCargaOtrosIngresos"
        );

      botonesOtrosIngresos.classList.add("d-none");
      botonesNuevoOtrosIngresos.classList.add("d-none");

      switch (e.target.id) {
        case "historicoOtrosIngresos-tab":
          botonesNuevoOtrosIngresos.classList.remove("d-none");
          break;
        case "cargaOtrosIngresos-tab":
          botonesOtrosIngresos.classList.remove("d-none");
          break;
      }
    }
  );

  document.addEventListener("click", function (e) {
    const target = e.target;

    if (target.classList.contains("eliminar-horaExtra"))
      configCargaHorasExtras.eliminar(target.dataset.id);

    if (target.classList.contains("eliminar-ProcesoHoraExtra"))
      configHistoricoHorasExtras.eliminar(target.dataset.id);

    if (target.classList.contains("editar-procesoHoraExtra"))
      configHistoricoHorasExtras.editar(target.dataset.id);

    if (target.classList.contains("eliminar-otroIngreso"))
      configCargaOtrosIngresos.eliminar(target.dataset.id);

    if (target.classList.contains("eliminar-ProcesoOtrosIngresos"))
      configHistoricoOtrosIngresos.eliminar(target.dataset.id);

    if (target.classList.contains("editar-procesoOtrosIngresos"))
      configHistoricoOtrosIngresos.editar(target.dataset.id);
  });
})();

const loader = document.querySelector(".loader");

window.onload = async () => {
  try {
    await inicializarTablas();

    await configuracion.inicializar();

    loader && loader.classList.add("d-none");
  } catch (err) {
    mostrarMensajes.error(err);
  }
};

function inicializarTablas() {
  return new Promise((resolve, reject) => {
    try {
      configHistoricoHorasExtras.tabla = new CustomDataTable({
        id: "historicoHorasExtras-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [8],
      });

      configCargaHorasExtras.tabla = new CustomDataTable({
        id: "cargaHorasExtras-tbl",
        alineadoIzquierda: [3, 4],
        noOrdenable: [8],
      });

      configHistoricoOtrosIngresos.tabla = new CustomDataTable({
        id: "historicoOtrosIngresos-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [8],
      });

      configCargaOtrosIngresos.tabla = new CustomDataTable({
        id: "cargaOtrosIngresos-tbl",
        alineadoIzquierda: [3, 4],
        noOrdenable: [7],
      });
      resolve();
    } catch (err) {
      reject(err);
    }
  });
}

const configuracion = {
  tiposPlanilla: [],
  campos: {
    tipoPlanilla: document.querySelector("#cbo-tipoPlanilla"),
    anio: document.querySelector("#cbo-anio"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const anios = [];

        for (let i = -3; i <= 1; i++) {
          anios.push(new Date().getFullYear() + i);
        }

        let opciones = anios.map(
          (anio) =>
            `<option value="${anio}" ${
              anio == new Date().getFullYear() && "selected"
            }>${anio}</option>`
        );

        this.campos.anio.innerHTML = opciones.join("");

        const { data: tiposPlanilla = [] } =
          await TipoPlanilla.obtenerPorUsuario();

        this.tiposPlanilla = tiposPlanilla;

        opciones = tiposPlanilla.map(
          (tipoPlanilla) =>
            `<option value="${tipoPlanilla.codtipoplanilla}">${tipoPlanilla.tipoPlanilla}</option>`
        );

        opciones.length > 0
          ? opciones.unshift(
              '<option value="" selected disabled>Seleccione</option>'
            )
          : opciones.push(
              '<option value="" selected disabled>No hay datos</option>'
            );

        this.campos.tipoPlanilla.innerHTML = opciones.join("");

        $(`#${this.campos.tipoPlanilla.id}`)
          .selectpicker("destroy")
          .selectpicker();

        await configCargaHorasExtras.inicializar();
        await configCargaOtrosIngresos.inicializar();

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  obtenerTipoPlanillaPorId: function ({ codtipoplanilla }) {
    return this.tiposPlanilla.find(
      (tipoPlanilla) =>
        parseInt(tipoPlanilla.codtipoplanilla) === parseInt(codtipoplanilla)
    );
  },
  buscar: async function () {
    try {
      if (!metodosFormularios.validar({ id: "ubicacion-form" })) return;

      const { codtipoplanilla, anio, tipoPlanilla } = this.obtenerFiltros();

      await configHistoricoHorasExtras.buscar({
        codtipoplanilla,
        anio,
        tipoPlanilla,
      });
      await configHistoricoOtrosIngresos.buscar({
        codtipoplanilla,
        anio,
        tipoPlanilla,
      });
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  obtenerFiltros: function () {
    return {
      codtipoplanilla: this.campos.tipoPlanilla.value,
      anio: this.campos.anio.value,
      tipoPlanilla:
        this.campos.tipoPlanilla.options[this.campos.tipoPlanilla.selectedIndex]
          .text,
    };
  },
};

const configHistoricoHorasExtras = {
  id: 0,
  cnt: 0,
  tabla: null,
  data: {},
  buscar: function ({
    codtipoplanilla,
    anio = moment().format("Y"),
    tipoPlanilla = "",
  }) {
    return new Promise(async (resolve, reject) => {
      try {
        await this.limpiar();
        const { data = [] } =
          await HoraExtra.obtenerProcesosPorTipoPlanillaAnio({
            codtipoplanilla,
            anio,
          });

        data.forEach((proceso) => {
          this.cnt++;
          this.data[this.cnt] = proceso;

          const fila = this.prepararParaFila({
            datos: { ...proceso, tipoPlanilla },
            id: this.cnt,
          });

          this.tabla.agregarFila({
            datos: fila,
            idFila: `trProcesoHoraExtra${this.cnt}`,
          });
        });

        this.tabla.redibujar();

        if (data.length == 0) {
          mostrarToastify({
            type: "info",
            message: "No se encontraron procesos de carga de horas extras",
          });
        }

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  prepararParaFila: function ({ datos, id }) {
    let claseBadge = "bg-success",
      msgBadge = "Pendiente de pago";

    const fechaProyeccion = moment(datos.fechaProyeccion, "DD-MM-YYYY"),
      fechaActual = moment(),
      diasFaltantes = fechaProyeccion.diff(fechaActual, "days");

    if (diasFaltantes > 0 && diasFaltantes <= 3) {
      claseBadge = "bg-warning";
      msgBadge = "Próximo a pagar";
    }

    if (datos.correlativoPlanilla !== null && datos.fechaPago !== null) {
      claseBadge = "bg-secondary";
      msgBadge = "Pagado";
    }

    return {
      0: id,
      1: datos.tipoPlanilla,
      2: datos.fechaRegistro,
      3: datos.fechaProyeccion,
      4: datos.empleados,
      5: `$${parseFloat(datos.monto).toFixed(2)}`,
      6: datos.usuario,
      7: `<span class="badge ${claseBadge}">${msgBadge}</span>`,
      8: obtenerHTMLBotonesDropdown([
        {
          tipo: "view",
          texto: "Ver",
          selectorClase: "editar-procesoHoraExtra",
          selectorId: id,
        },
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-ProcesoHoraExtra",
          selectorId: id,
        },
      ]),
    };
  },
  eliminar: async function (id = 0) {
    try {
      const proceso = this.data[id];

      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el proceso de carga masiva de horas extras y sus detalles. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      const respuesta = await HoraExtra.eliminarProcesoCarga({
        id: proceso.id,
      });

      switch (respuesta.message) {
        case "success":
          delete this.data[id];
          this.tabla
            .eliminarFila({ idFila: `trProcesoHoraExtra${id}` })
            .redibujar();
          mostrarToastify({
            type: "success",
            message: "Proceso eliminado correctamente",
          });
          break;
        case "pagado":
          mostrarMensajes.warning({
            message: `No se puede eliminar el proceso porque ya fue pagado`,
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  limpiar: function () {
    return new Promise((resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      resolve();
    });
  },
  editar: function (id = 0) {
    const proceso = this.data[id];
    configCargaHorasExtras.editar({ proceso });
  },
};

const configCargaHorasExtras = {
  id: 0,
  cnt: 0,
  tabla: null,
  catalogos: {
    tiposHora: [],
  },
  data: {},
  form: "cargaHoraExtra-form",
  campos: {
    archivo: document.querySelector("#file-horasExtras"),
    totalRegistros: document.querySelector("#num-totalRegistrosHE"),
    totalEmpleados: document.querySelector("#num-totalEmpleadosHE"),
    montoTotal: document.querySelector("#num-totalMontoHE"),
    mesPago: document.querySelector("#txt-mesPagoHoraExtra"),
    quincenaPago: document.querySelector("#cbo-quincenaPagoHoraExtra"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: tiposHora = [] } = await tipoHorasExtra.obtenerRegistro();

        this.catalogos.tiposHora = tiposHora;

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  verificarArchivo: async function () {
    const archivo = this.campos.archivo.files[0];

    if (!archivo) return;

    try {
      await this.limpiar();

      const { data: detalles = [] } = await HoraExtra.verificarArchivo({
        archivo,
      });

      // this.campos.archivo.value = "";

      let codtiposplanilla = detalles.map((det) => parseInt(det.tipoPlanilla)),
        tiposPlanilla = [];

      if (codtiposplanilla.length > 0) {
        codtiposplanilla = [...new Set(codtiposplanilla)];
        tiposPlanilla = codtiposplanilla.map((codtipoplanilla) =>
          configuracion.obtenerTipoPlanillaPorId({ codtipoplanilla })
        );
      }

      detalles.forEach((detalle) => {
        let tipoHoraExtra = "No definido";

        const tipoHora = this.catalogos.tiposHora.find(
          (tipoHora) => parseInt(tipoHora.codtipo) == parseInt(detalle.tipoHora)
        );

        detalle.monto = 0;
        detalle.nombreTipoPlanilla =
          tiposPlanilla.find(
            (tipoPlanilla) =>
              parseInt(tipoPlanilla.codtipoplanilla) ===
              parseInt(detalle.tipoPlanilla)
          )?.tipoPlanilla || "No definido";

        if (tipoHora) {
          tipoHoraExtra = tipoHora.tipoHoraExtra;
          if (tipoHora.factor[0] === ".")
            tipoHora.factor = "0" + tipoHora.factor;
          if (tipoHora.recargo[0] === ".")
            tipoHora.recargo = "0" + tipoHora.recargo;

          let factor = parseFloat(tipoHora.factor),
            recargo = parseFloat(tipoHora.recargo),
            salarioQuincenal = parseFloat(detalle?.salario) || 0,
            salarioHora = 0;

          if (salarioQuincenal > 0) {
            salarioHora = salarioQuincenal / 15 / 8;
          }

          if (parseInt(tipoHora?.calcularSobreSalario || 0) === 1) {
            detalle.monto =
              salarioHora * (factor + recargo) * parseFloat(detalle.cantidad);
          } else {
            detalle.monto = parseFloat(factor) * parseFloat(detalle.cantidad);
          }
        }

        detalle.tipoHoraExtra = tipoHoraExtra;
        this.cnt++;
        this.data[this.cnt] = detalle;

        const fila = this.prepararParaFila({ datos: detalle, id: this.cnt });

        this.tabla.agregarFila({
          datos: fila,
          idFila: `trHoraExtra${this.cnt}`,
        });
      });

      this.calcularTotales();

      this.tabla.redibujar();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  editar: async function ({ proceso = {} }) {
    try {
      await this.limpiar();
      await metodosFormularios.limpiar({ id: this.form });
      this.id = proceso?.id || 0;
      document.getElementById("btn-guardarCargaHoraExtra").disabled = false;

      if (this.id > 0) {
        document.getElementById("btn-guardarCargaHoraExtra").disabled = true;
        this.campos.quincenaPago.value = proceso.quincenaPago;
        this.campos.mesPago._flatpickr.setDate(
          moment(`01-${proceso.mesPago}`, "DD-MM-YYYY").toDate()
        );

        const { data: detalles } = await HoraExtra.obtenerPorProcesoMasivo({
          id: this.id,
        });

        detalles.forEach((detalle) => {
          this.cnt++;
          this.data[this.cnt] = detalle;

          const fila = this.prepararParaFila({ datos: detalle, id: this.cnt });

          this.tabla.agregarFila({
            datos: fila,
            idFila: `trHoraExtra${this.cnt}`,
          });
        });

        this.calcularTotales();
        this.tabla.redibujar();
      }

      document
        .getElementById("cargaHorasExtras-tab")
        .classList.remove("disabled");
      document.getElementById("cargaHorasExtras-tab").click();
      document
        .getElementById("historicoHorasExtras-tab")
        .classList.add("disabled");
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  guardar: async function () {
    try {
      if (!metodosFormularios.validar({ id: this.form })) return;

      const horasExtras = Object.values(this.data);

      if (horasExtras.length === 0) {
        mostrarMensajes.warning({
          message: `No hay datos para guardar`,
        });
        return;
      }

      const mesPago = moment(
          this.campos.mesPago._flatpickr.selectedDates[0]
        ).format("MM-YYYY"),
        quincenaPago = this.campos.quincenaPago.value;

      const respuesta = await HoraExtra.guardarMasivo({
        id: this.id || 0,
        mesPago,
        quincenaPago,
        horasExtras,
      });

      switch (respuesta.message) {
        case "success":
          const primerTipoPlanilla =
            Object.values(this.data)[0]?.tipoPlanilla || 0;
          metodosFormularios.limpiar({ id: this.form });
          this.limpiar();
          document.getElementById("historicoHorasExtras-tab").click();
          mostrarToastify({
            type: "success",
            message: "Datos guardados correctamente",
          });

          const { codtipoplanilla, anio, tipoPlanilla } =
            configuracion.obtenerFiltros();

          if (
            codtipoplanilla &&
            anio &&
            codtipoplanilla == primerTipoPlanilla
          ) {
            await configHistoricoHorasExtras.buscar({
              codtipoplanilla,
              anio,
              tipoPlanilla,
            });
          }

          this.cancelar();
          break;
        case "vacio":
          mostrarMensajes.warning({
            message: `No hay datos para guardar`,
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.nombreTipoPlanilla,
      2: datos.codempleado,
      3: datos.nombreEmpleado,
      4: datos.concepto,
      5: datos.tipoHoraExtra,
      6: datos.cantidad,
      7: `$${parseFloat(datos.monto).toFixed(2)}`,
      8: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-horaExtra",
          selectorId: id,
        },
      ]),
    };
  },
  eliminar: async function (id) {
    const detalle = this.data[id];
    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el detalle de pago para el empleado <strong>${detalle.nombreEmpleado}</strong> con el concepto <strong>${detalle.concepto}</strong>. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      delete this.data[id];
      this.tabla.eliminarFila({ idFila: `trHoraExtra${id}` }).redibujar();

      this.calcularTotales();

      mostrarToastify({
        type: "success",
        message: "Detalle eliminado correctamente",
      });
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  calcularTotales: function () {
    let totalRegistros = Object.values(this.data).length,
      totalEmpleados = 0,
      montoTotal = Object.values(this.data).reduce(
        (acum, detalle) => acum + parseFloat(detalle.monto),
        0
      );

    let codempleados = Object.values(this.data).map((detalle) =>
      parseInt(detalle.codempleado)
    );

    if (codempleados.length > 0) {
      codempleados = [...new Set(codempleados)];
      totalEmpleados = codempleados.length;
    }

    this.campos.totalRegistros.value = totalRegistros;
    this.campos.totalEmpleados.value = totalEmpleados;
    this.campos.montoTotal.value = montoTotal.toFixed(2);
  },
  limpiar: function () {
    return new Promise((resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      resolve();
    });
  },
  cancelar: function () {
    document
      .getElementById("historicoHorasExtras-tab")
      .classList.remove("disabled");
    document.getElementById("historicoHorasExtras-tab").click();
    document.getElementById("cargaHorasExtras-tab").classList.add("disabled");
  },
};

const configHistoricoOtrosIngresos = {
  id: 0,
  cnt: 0,
  tabla: null,
  data: {},
  buscar: function ({
    codtipoplanilla,
    anio = moment().format("Y"),
    tipoPlanilla = "",
  }) {
    return new Promise(async (resolve, reject) => {
      try {
        await this.limpiar();
        const { data = [] } =
          await OtroIngreso.obtenerProcesosPorTipoPlanillaAnio({
            codtipoplanilla,
            anio,
          });

        data.forEach((proceso) => {
          this.cnt++;
          this.data[this.cnt] = proceso;

          const fila = this.prepararParaFila({
            datos: { ...proceso, tipoPlanilla },
            id: this.cnt,
          });

          this.tabla.agregarFila({
            datos: fila,
            idFila: `trProcesoOtrosIngresos${this.cnt}`,
          });
        });

        this.tabla.redibujar();

        if (data.length == 0) {
          mostrarToastify({
            type: "info",
            message: "No se encontraron procesos de carga de otros ingresos",
          });
        }

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  prepararParaFila: function ({ datos, id }) {
    let claseBadge = "bg-success",
      msgBadge = "Pendiente de pago";

    const fechaProyeccion = moment(datos.fechaProyeccion, "DD-MM-YYYY"),
      fechaActual = moment(),
      diasFaltantes = fechaProyeccion.diff(fechaActual, "days");

    if (diasFaltantes > 0 && diasFaltantes <= 3) {
      claseBadge = "bg-warning";
      msgBadge = "Próximo a pagar";
    }

    if (datos.correlativoPlanilla !== null && datos.fechaPago !== null) {
      claseBadge = "bg-secondary";
      msgBadge = "Pagado";
    }

    return {
      0: id,
      1: datos.tipoPlanilla,
      2: datos.fechaRegistro,
      3: datos.fechaProyeccion,
      4: datos.empleados,
      5: `$${parseFloat(datos.monto).toFixed(2)}`,
      6: datos.usuario,
      7: `<span class="badge ${claseBadge}">${msgBadge}</span>`,
      8: obtenerHTMLBotonesDropdown([
        {
          tipo: "view",
          texto: "Ver",
          selectorClase: "editar-procesoOtrosIngresos",
          selectorId: id,
        },
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-ProcesoOtrosIngresos",
          selectorId: id,
        },
      ]),
    };
  },
  eliminar: async function (id = 0) {
    try {
      const proceso = this.data[id];

      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el proceso de carga masiva de otros ingresos y sus detalles. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      const respuesta = await OtroIngreso.eliminarProcesoCarga({
        id: proceso.id,
      });

      switch (respuesta.message) {
        case "success":
          delete this.data[id];
          this.tabla
            .eliminarFila({ idFila: `trProcesoOtrosIngresos${id}` })
            .redibujar();
          mostrarToastify({
            type: "success",
            message: "Proceso eliminado correctamente",
          });
          break;
        case "pagado":
          mostrarMensajes.warning({
            message: `No se puede eliminar el proceso porque ya fue pagado`,
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  limpiar: function () {
    return new Promise((resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      resolve();
    });
  },
  editar: function (id = 0) {
    const proceso = this.data[id];
    configCargaOtrosIngresos.editar({ proceso });
  },
};

const configCargaOtrosIngresos = {
  id: 0,
  cnt: 0,
  tabla: null,
  catalogos: {
    tiposOtrosIngresos: [],
  },
  data: {},
  form: "cargaOtrosIngresos-form",
  campos: {
    archivo: document.querySelector("#file-otrosIngresos"),
    totalRegistros: document.querySelector("#num-totalRegistrosOI"),
    totalEmpleados: document.querySelector("#num-totalEmpleadosOI"),
    montoTotal: document.querySelector("#num-totalMontoOI"),
    mesPago: document.querySelector("#txt-mesPagoOtrosIngresos"),
    quincenaPago: document.querySelector("#cbo-quincenaOtrosIngresos"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: tipos = [] } =
          await tiposOtrosIngresos.obtenerregistroTiposOtrosIngresos();

        this.catalogos.tiposOtrosIngresos = tipos;

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  verificarArchivo: async function () {
    const archivo = this.campos.archivo.files[0];

    if (!archivo) return;

    try {
      await this.limpiar();

      const { data: detalles = [] } = await OtroIngreso.verificarArchivo({
        archivo,
      });

      // this.campos.archivo.value = "";

      let codtiposplanilla = detalles.map((det) => parseInt(det.tipoPlanilla)),
        tiposPlanilla = [];

      if (codtiposplanilla.length > 0) {
        codtiposplanilla = [...new Set(codtiposplanilla)];
        tiposPlanilla = codtiposplanilla.map((codtipoplanilla) =>
          configuracion.obtenerTipoPlanillaPorId({ codtipoplanilla })
        );
      }

      detalles.forEach((detalle) => {
        let tipoOtroIngreso = "No definido";

        const tipoIngreso = this.catalogos.tiposOtrosIngresos.find(
          (tipoIngreso) =>
            parseInt(tipoIngreso.codtipo) == parseInt(detalle.tipoIngreso)
        );
        detalle.nombreTipoPlanilla =
          tiposPlanilla.find(
            (tipoPlanilla) =>
              parseInt(tipoPlanilla.codtipoplanilla) ===
              parseInt(detalle.tipoPlanilla)
          )?.tipoPlanilla || "No definido";

        if (tipoIngreso) {
          tipoOtroIngreso = tipoIngreso.tipoOtroIngreso;
        }

        detalle.tipoOtroIngreso = tipoOtroIngreso;
        this.cnt++;
        this.data[this.cnt] = detalle;

        const fila = this.prepararParaFila({ datos: detalle, id: this.cnt });

        this.tabla.agregarFila({
          datos: fila,
          idFila: `trOtroIngreso${this.cnt}`,
        });
      });

      this.calcularTotales();

      this.tabla.redibujar();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  editar: async function ({ proceso = {} }) {
    try {
      await this.limpiar();
      await metodosFormularios.limpiar({ id: this.form });
      this.id = proceso?.id || 0;
      document.getElementById("btn-guardarCargaOtrosIngresos").disabled = false;

      if (this.id > 0) {
        document.getElementById(
          "btn-guardarCargaOtrosIngresos"
        ).disabled = true;
        this.campos.quincenaPago.value = proceso.quincenaPago;
        this.campos.mesPago._flatpickr.setDate(
          moment(`01-${proceso.mesPago}`, "DD-MM-YYYY").toDate()
        );
        const { data: detalles } = await OtroIngreso.obtenerPorProcesoMasivo({
          id: this.id,
        });

        detalles.forEach((detalle) => {
          this.cnt++;
          this.data[this.cnt] = detalle;
          const fila = this.prepararParaFila({ datos: detalle, id: this.cnt });
          this.tabla.agregarFila({
            datos: fila,
            idFila: `trOtroIngreso${this.cnt}`,
          });
        });
        this.calcularTotales();
        this.tabla.redibujar();
      }

      document
        .getElementById("cargaOtrosIngresos-tab")
        .classList.remove("disabled");
      document.getElementById("cargaOtrosIngresos-tab").click();
      document
        .getElementById("historicoOtrosIngresos-tab")
        .classList.add("disabled");
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  guardar: async function () {
    try {
      if (!metodosFormularios.validar({ id: this.form })) return;

      const otrosIngresos = Object.values(this.data);

      if (otrosIngresos.length === 0) {
        mostrarMensajes.warning({
          message: `No hay datos para guardar`,
        });
        return;
      }

      // console.log(this.campos);return;

      const mesPago = moment(
          this.campos.mesPago._flatpickr.selectedDates[0]
        ).format("MM-YYYY"),
        quincenaPago = this.campos.quincenaPago.value;

      const respuesta = await OtroIngreso.guardarMasivo({
        id: this.id || 0,
        mesPago,
        quincenaPago,
        otrosIngresos,
      });

      switch (respuesta.message) {
        case "success":
          const primerTipoPlanilla =
            Object.values(this.data)[0]?.tipoPlanilla || 0;
          await metodosFormularios.limpiar({ id: this.form });
          this.limpiar();
          document.getElementById("historicoOtrosIngresos-tab").click();
          mostrarToastify({
            type: "success",
            message: "Datos guardados correctamente",
          });

          const { codtipoplanilla, anio, tipoPlanilla } =
            configuracion.obtenerFiltros();

          if (
            codtipoplanilla &&
            anio &&
            codtipoplanilla == primerTipoPlanilla
          ) {
            await configHistoricoOtrosIngresos.buscar({
              codtipoplanilla,
              anio,
              tipoPlanilla,
            });
          }

          this.cancelar();
          break;
        case "vacio":
          mostrarMensajes.warning({
            message: `No hay datos para guardar`,
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.nombreTipoPlanilla,
      2: datos.codempleado,
      3: datos.nombreEmpleado,
      4: datos.concepto,
      5: datos.tipoOtroIngreso,
      6: `$${parseFloat(datos.monto).toFixed(2)}`,
      7: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-otroIngreso",
          selectorId: id,
        },
      ]),
    };
  },
  eliminar: async function (id) {
    const detalle = this.data[id];
    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el detalle de pago para el empleado <strong>${detalle.nombreEmpleado}</strong> con el concepto <strong>${detalle.concepto}</strong>. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      delete this.data[id];
      this.tabla.eliminarFila({ idFila: `trOtroIngreso${id}` }).redibujar();

      this.calcularTotales();

      mostrarToastify({
        type: "success",
        message: "Detalle eliminado correctamente",
      });
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  calcularTotales: function () {
    let totalRegistros = Object.values(this.data).length,
      totalEmpleados = 0,
      montoTotal = Object.values(this.data).reduce(
        (acum, detalle) => acum + parseFloat(detalle.monto),
        0
      );

    let codempleados = Object.values(this.data).map((detalle) =>
      parseInt(detalle.codempleado)
    );

    if (codempleados.length > 0) {
      codempleados = [...new Set(codempleados)];
      totalEmpleados = codempleados.length;
    }

    this.campos.totalRegistros.value = totalRegistros;
    this.campos.totalEmpleados.value = totalEmpleados;
    this.campos.montoTotal.value = montoTotal.toFixed(2);
  },
  limpiar: function () {
    return new Promise((resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      resolve();
    });
  },
  cancelar: function () {
    document
      .getElementById("historicoOtrosIngresos-tab")
      .classList.remove("disabled");
    document.getElementById("historicoOtrosIngresos-tab").click();
    document.getElementById("cargaOtrosIngresos-tab").classList.add("disabled");
  },
};
