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 UnidadTrabajo from "../models/unidadTrabajoModel.js?v=2.0.0";
import tipoHorasExtra from "../models/tipoHorasextraModel.js";
import tiposOtrosIngresos from "../models/tipoOtrosIngresosModel.js";

!(function () {
  document.getElementById("btn-agregar").addEventListener("click", () => {
    evaluarPestania();
  });

  document
    .getElementById("chk-planillaComplementariaHE")
    .addEventListener("change", (e) => {
      configtiposHorasExtra.evaluarPlanillaComplementaria();
    });

  document
    .getElementById("chk-planillaComplementariaOI")
    .addEventListener("change", (e) => {
      configTiposOtrosIngresos.evaluarPlanillaComplementaria();
    });

  document.getElementById("unidad-form").addEventListener("submit", (e) => {
    e.preventDefault();

    configUnidad.guardar();
  });

  document
    .getElementById("tipoHorasExtra-form")
    .addEventListener("submit", (e) => {
      e.preventDefault();

      configtiposHorasExtra.guardar();
    });

  document
    .getElementById("tiposOtrosIngresos-form")
    .addEventListener("submit", (e) => {
      e.preventDefault();
      configTiposOtrosIngresos.guardar();
    });

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

    if (target.classList.contains("eliminar-unidad"))
      configUnidad.eliminar(target.dataset.id);

    if (target.classList.contains("editar-tipoHora"))
      configtiposHorasExtra.editar(target.dataset.id);

    if (target.classList.contains("eliminar-tipoHora"))
      configtiposHorasExtra.eliminar(target.dataset.id);

    if (target.classList.contains("editar-otroIngreso"))
      configTiposOtrosIngresos.editar(target.dataset.id);

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

window.onload = async () => {
  try {
    inicializarTablas();
    await configUnidad.inicializar();
    //preparamos la carga en la ventana
    await configtiposHorasExtra.inicializar();
    //prepararamos tipo otros ingresos
    await configTiposOtrosIngresos.inicializar();

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

function inicializarTablas() {
  return new Promise((resolve, reject) => {
    try {
      configUnidad.tabla = new CustomDataTable({
        id: "unidades-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [5],
      });
      //inicializamos la tabla del segundo tabs
      configtiposHorasExtra.tabla = new CustomDataTable({
        id: "tipoHorasExtra",
        alineadoIzquierda: [1],
        noOrdenable: [8],
      });
      //inicializamos tipos otros ingresos
      configTiposOtrosIngresos.tabla = new CustomDataTable({
        id: "tipoOtrosingresos",
        alineadoIzquierda: [1],
        noOrdenable: [5],
      });
      resolve();
    } catch (err) {
      reject(err);
    }
  });
}

function evaluarPestania() {
  const pestaniaSeleccionada = document.querySelector(
    "#pestanias-principales li button.nav-link.active"
  );

  if (!!pestaniaSeleccionada) {
    let id = pestaniaSeleccionada.id;

    switch (id) {
      case "unidad-tab":
        configUnidad.editar();
        break;
      case "horaExtra-tab": //evaluamos pestana seleccionada
        configtiposHorasExtra.editar();
        break;
      case "tipoOtrosIngresos-tab":
        configTiposOtrosIngresos.editar();
        break;
    }
  }
}

//let en lugar de var
const configUnidad = {
  id: 0,
  cnt: 0, //contadodor
  data: {}, // es un objeto por lo tanto lleva llaves
  tabla: null,
  campos: {
    unidadTrabajo: document.getElementById("txt-unidadTrabajo"),
  },
  modal: {
    id: "modal-unidad",
    mostrar: () => $(`#${configUnidad.modal.id}`).modal("show"),
    ocultar: () => $(`#${configUnidad.modal.id}`).modal("hide"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: unidades = [] } = await UnidadTrabajo.obtenerTodos();

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

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

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

        this.tabla.redibujar();

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  editar: async function (id = 0) {
    await metodosFormularios.limpiar({ id: "unidad-form" });
    this.id = id;

    if (this.id > 0) {
      const unidad = this.data[this.id];

      this.campos.unidadTrabajo.value = unidad.unidadTrabajo;
    }

    this.modal.mostrar();
  },
  guardar: async function () {
    if (!metodosFormularios.validar({ id: "unidad-form" })) return;
    try {
      const unidad = new UnidadTrabajo({
        id: this.data[this.id]?.id || 0,
        unidadTrabajo: this.campos.unidadTrabajo.value,
        fechaRegistro:
          this.data[this.id]?.fechaRegistro ||
          moment().format("DD-MM-YYYY HH:mm"),
        usuario: this.data[this.id]?.usuario || null,
        cantidadEmpleados: this.data[this.id]?.cantidadEmpleados || 0,
      });

      const respuesta = await unidad.guardar();

      switch (respuesta.message) {
        case "success":
          unidad.id = respuesta.data.id;
          unidad.usuario = respuesta.data.usuario;

          let fila = this.prepararParaFila({
            datos: unidad,
            id: this.id > 0 ? this.id : this.cnt + 1,
          });

          if (this.id == 0) {
            this.cnt++;
            this.id = this.cnt;

            this.data[this.id] = unidad;

            this.tabla
              .agregarFila({ datos: fila, idFila: `trUnidad${this.cnt}` })
              .redibujar();
          } else {
            this.tabla
              .actualizarFila({ datos: fila, idFila: `trUnidad${this.id}` })
              .redibujar();
          }

          this.modal.ocultar();
          break;
        case "duplicado":
          mostrarToastify({
            type: "error",
            message: "Ya existe una unidad de trabajo con el mismo nombre",
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  eliminar: async function (id) {
    try {
      const unidad = new UnidadTrabajo(this.data[id]);

      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará la unidad de trabajo <strong>${unidad.unidadTrabajo}</strong>`,
      });

      if (!confirmacion) return;

      const respuesta = await unidad.eliminar();

      switch (respuesta.message) {
        case "success":
          this.tabla.eliminarFila({ idFila: `trUnidad${id}` }).redibujar();
          delete this.data[id];

          mostrarToastify({
            type: "success",
            message: "Unidad de trabajo eliminada correctamente",
          });
          break;
        default:
          mostrarMensajes.error(err);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.unidadTrabajo,
      2: datos.cantidadEmpleados,
      3: datos.fechaRegistro,
      4: datos.usuario,
      5: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-unidad",
          selectorId: id,
        },
      ]),
    };
  },
};

const configtiposHorasExtra = {
  //creamos el objeto
  id: 0,
  cnt: 0,
  tabla: null,
  data: {},
  campos: {
    codtipo: document.getElementById("num-codtipo"),
    tipoHoraExtra: document.getElementById("txt-tiposHorasExtra"),
    factor: document.getElementById("num-factor"),
    recargo: document.getElementById("num-recargo"),
    planillaComplementaria: document.getElementById(
      "chk-planillaComplementariaHE"
    ),
    aplicaCotizaciones: document.getElementById("chk-cotizacionesHoras"),
    aplicaRenta: document.getElementById("chk-rentaHoras"),
    calcularSobreSalario: document.getElementById("chk-calcularSobreSalario"),
  },
  modal: {
    //invocamos la el id de la tablamodal
    id: "modal-tiposHorasExtra",
    mostrar: () => $(`#${configtiposHorasExtra.modal.id}`).modal("show"),
    ocultar: () => $(`#${configtiposHorasExtra.modal.id}`).modal("hide"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: tipos } = await tipoHorasExtra.obtenerRegistro();
        tipos.forEach((tipo) => {
          this.cnt++;
          let factor = tipo.factor,
            recargo = tipo.recargo;
          if (factor == null || factor == ".000000") factor = 0;
          if (recargo == null || recargo == ".000000") recargo = 0;

          tipo = {
            ...tipo,
            factor,
            recargo,
          };

          this.data[this.cnt] = tipo;
          const fila = this.prepararParaFila({
            datos: tipo,
            id: this.cnt,
          });
          this.tabla.agregarFila({
            datos: fila,
            idFila: `trTipoHora${this.cnt}`,
          });
        });
        this.tabla.redibujar();
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: datos.codtipo,
      1: datos.tipoHoraExtra,
      2: parseFloat(datos.factor).toFixed(2),
      3: parseFloat(datos.recargo).toFixed(2),
      4: parseInt(datos.planillaComplementaria || 0) === 1 ? "Si" : "No",
      5: parseInt(datos.aplicaCotizaciones || 0) === 1 ? "Si" : "No",
      6: parseInt(datos.aplicaRenta || 0) === 1 ? "Si" : "No",
      7: parseInt(datos.calcularSobreSalario || 0) === 1 ? "Si" : "No",
      8: obtenerHTMLBotonesDropdown([
        {
          tipo: "edit",
          texto: "Editar",
          selectorClase: "editar-tipoHora",
          selectorId: id,
        },
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-tipoHora",
          selectorId: id,
        },
      ]),
    };
  },
  editar: async function (id = 0) {
    try {
      await metodosFormularios.limpiar({ id: "tipoHorasExtra-form" });

      this.id = id;

      this.evaluarPlanillaComplementaria();
      if (this.id > 0) {
        const tipo = this.data[this.id];

        this.campos.codtipo.value = tipo.codtipo;
        this.campos.tipoHoraExtra.value = tipo.tipoHoraExtra;
        this.campos.factor.value = tipo.factor;
        this.campos.recargo.value = tipo.recargo;
        this.campos.planillaComplementaria.checked =
          parseInt(tipo.planillaComplementaria || 0) === 1;
        this.campos.aplicaCotizaciones.checked =
          parseInt(tipo.aplicaCotizaciones || 0) === 1;
        this.campos.aplicaRenta.checked = parseInt(tipo.aplicaRenta || 0) === 1;
        this.campos.calcularSobreSalario.checked =
          parseInt(tipo.calcularSobreSalario || 0) === 1;
        this.evaluarPlanillaComplementaria();
      }

      this.modal.mostrar();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  guardar: async function () {
    try {
      if (!metodosFormularios.validar({ id: "tipoHorasExtra-form" })) return;

      let tipoIgual = null;

      for (let i in this.data) {
        if (
          parseInt(this.data[i].codtipo) ===
            parseInt(this.campos.codtipo.value) &&
          parseInt(this.id) !== parseInt(i)
        ) {
          tipoIgual = this.data[i];
          break;
        }
      }

      if (!!tipoIgual) {
        mostrarMensajes.warning({
          message: `Ya existe un tipo de hora extra con el código <strong>${this.campos.codtipo.value}</strong>`,
        });

        return;
      }

      const tipoHoraExtra = new tipoHorasExtra({
        codtipo: this.campos.codtipo.value,
        tipoHoraExtra: this.campos.tipoHoraExtra.value,
        factor: this.campos.factor.value,
        recargo: this.campos.recargo.value,
        aplicaCotizaciones: Number(this.campos.aplicaCotizaciones.checked),
        aplicaRenta: Number(this.campos.aplicaRenta.checked),
        calcularSobreSalario: Number(this.campos.calcularSobreSalario.checked),
        planillaComplementaria: Number(
          this.campos.planillaComplementaria.checked
        ),
      });

      const respuesta = await tipoHoraExtra.guardar();

      switch (respuesta.message) {
        case "success":
          let fila = this.prepararParaFila({
            datos: tipoHoraExtra,
            id: this.id > 0 ? this.id : this.cnt + 1,
          });

          if (this.id == 0) {
            this.cnt++;
            this.id = this.cnt;

            this.tabla
              .agregarFila({
                datos: fila,
                idFila: `trTipoHora${this.cnt}`,
              })
              .redibujar();
          } else {
            this.tabla
              .actualizarFila({ datos: fila, idFila: `trTipoHora${this.id}` })
              .redibujar();
          }

          this.data[this.id] = tipoHoraExtra;

          this.modal.ocultar();

          mostrarToastify({
            type: "success",
            message: "Tipo de hora extra guardada correctamente",
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  eliminar: async function (id) {
    try {
      const tipoHoraExtra = new tipoHorasExtra(this.data[id]);

      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el tipo de hora extra <strong>${tipoHoraExtra.tipoHoraExtra}</strong>`,
      });

      if (!confirmacion) return;

      const respuesta = await tipoHoraExtra.eliminar();

      switch (respuesta.message) {
        case "success":
          this.tabla.eliminarFila({ idFila: `trTipoHora${id}` }).redibujar();
          delete this.data[id];

          mostrarToastify({
            type: "success",
            message: "Tipo de hora extra eliminada correctamente",
          });
          break;
        default:
          mostrarMensajes.error(err);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  evaluarPlanillaComplementaria: function () {
    const planillaComplementaria = this.campos.planillaComplementaria.checked;

    planillaComplementaria && (this.campos.aplicaCotizaciones.checked = false);
    this.campos.aplicaCotizaciones.disabled = planillaComplementaria;
  },
};

const configTiposOtrosIngresos = {
  //creamos el objeto
  id: 0,
  cnt: 0,
  tabla: null,
  data: {},
  campos: {
    codtipo: document.getElementById("num-codTipoOtroIngreso"),
    tipoOtroIngreso: document.getElementById("txt-tipoOtroIngreso"),
    aplicaCotizaciones: document.getElementById("chk-cotizaciones"),
    aplicaRenta: document.getElementById("chk-renta"),
    planillaComplementaria: document.getElementById(
      "chk-planillaComplementariaOI"
    ),
  },
  modal: {
    //invocamos la el id de la tablamodal
    id: "modal-tiposOtrosIngresos",
    mostrar: () => $(`#${configTiposOtrosIngresos.modal.id}`).modal("show"),
    ocultar: () => $(`#${configTiposOtrosIngresos.modal.id}`).modal("hide"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: tipos } =
          await tiposOtrosIngresos.obtenerregistroTiposOtrosIngresos();
        tipos.forEach((tipo) => {
          this.cnt++;
          this.data[this.cnt] = tipo;

          const fila = this.prepararParaFila({
            datos: tipo,
            id: this.cnt,
          });
          this.tabla.agregarFila({
            datos: fila,
            idFila: `trOtroIngreso${this.cnt}`,
          });
        });
        this.tabla.redibujar();
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  editar: async function (id = 0) {
    await metodosFormularios.limpiar({ id: "tiposOtrosIngresos-form" });
    this.id = id;

    this.evaluarPlanillaComplementaria();

    if (this.id > 0) {
      const tiposOtrosI = this.data[this.id];

      this.campos.codtipo.value = tiposOtrosI.codtipo;
      this.campos.tipoOtroIngreso.value = tiposOtrosI.tipoOtroIngreso;
      this.campos.planillaComplementaria.checked =
        parseInt(tiposOtrosI.planillaComplementaria) === 1;
      this.campos.aplicaCotizaciones.checked =
        parseInt(tiposOtrosI.aplicaCotizaciones) === 1;
      this.campos.aplicaRenta.checked = parseInt(tiposOtrosI.aplicaRenta) === 1;
      this.evaluarPlanillaComplementaria();
    }

    this.modal.mostrar();
  },
  guardar: async function () {
    if (!metodosFormularios.validar({ id: "tiposOtrosIngresos-form" })) return;
    try {
      //Verificar duplicado
      let tipoIgual = null;

      for (let i in this.data) {
        if (
          parseInt(this.data[i].codtipo) ===
            parseInt(this.campos.codtipo.value) &&
          parseInt(this.id) !== parseInt(i)
        ) {
          tipoIgual = this.data[i];
          break;
        }
      }

      if (!!tipoIgual) {
        mostrarMensajes.warning({
          message: `Ya existe un tipo de otro ingreso con el código <strong>${this.campos.codtipo.value}</strong>`,
        });

        return;
      }

      const tipo = new tiposOtrosIngresos({
        codtipo: this.campos.codtipo.value,
        tipoOtroIngreso: this.campos.tipoOtroIngreso.value,
        planillaComplementaria: Number(
          this.campos.planillaComplementaria.checked
        ),
        aplicaCotizaciones: Number(this.campos.aplicaCotizaciones.checked),
        aplicaRenta: Number(this.campos.aplicaRenta.checked),
        fechaRegistro:
          this.data[this.id]?.fechaRegistro ||
          moment().format("DD-MM-YYYY HH:mm"),
      });

      const respuesta = await tipo.guardar();

      switch (respuesta.message) {
        case "success":
          let fila = this.prepararParaFila({
            datos: tipo,
            id: this.id > 0 ? this.id : this.cnt + 1,
          });

          if (this.id == 0) {
            this.cnt++;
            this.id = this.cnt;

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

          this.data[this.id] = tipo;

          this.modal.ocultar();
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  eliminar: async function (id) {
    const otroIngreso = new tiposOtrosIngresos(this.data[id]);

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el tipo de otro ingreso <strong>${otroIngreso.tipoOtroIngreso}</strong>`,
      });

      if (!confirmacion) return;

      const respuesta = await otroIngreso.eliminar();

      switch (respuesta.message) {
        case "success":
          this.tabla.eliminarFila({ idFila: `trOtroIngreso${id}` }).redibujar();
          delete this.data[id];

          mostrarToastify({
            type: "success",
            message: "Tipo de otro ingreso eliminado correctamente",
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: datos.codtipo,
      1: datos.tipoOtroIngreso,
      2: parseInt(datos.planillaComplementaria) === 1 ? "Si" : "No",
      3: parseInt(datos.aplicaCotizaciones) === 1 ? "Si" : "No",
      4: parseInt(datos.aplicaRenta) === 1 ? "Si" : "No",
      5: obtenerHTMLBotonesDropdown([
        {
          tipo: "edit",
          texto: "Editar",
          selectorClase: "editar-otroIngreso",
          selectorId: id,
        },
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-otroIngreso",
          selectorId: id,
        },
      ]),
    };
  },
  evaluarPlanillaComplementaria: function () {
    const planillaComplementaria = this.campos.planillaComplementaria.checked;

    planillaComplementaria && (this.campos.aplicaCotizaciones.checked = false);
    this.campos.aplicaCotizaciones.disabled = planillaComplementaria;
  },
};
