"use strict";

import CodigoObservacionPlanillaUnica from "../models/codigoObservacionPlanillaUnicaModel.js?v=1.0.0";
import CustomDataTable from "../../../../assets/js/app/CustomDataTable.js?v=1.0.0";
import DocumentoPlanillaUnica from "../models/documentoPlanillaUnicaModel.js?v=1.0.0";
import InstitucionPrevisional from "../../../../assets/js/models/institucionPrevisionalModel.js?v=1.0.0";
import metodosFormularios from "../../../../assets/js/app/metodosFormularios.js?v=1.0.0";
import { NOMBRE_SESION } from "../../../../assets/js/app/constantes.js?v=1.0.0";
import {
  mostrarMensajes,
  mostrarToastify,
  obtenerHTMLBotonesDropdown,
} from "../../../../assets/js/app/funcionesGenerales.js?v=1.0.0";
import TipoDocumento from "../../../../assets/js/models/tipoDocumentoModel.js?v=1.0.0";
import InstitucionPlanillaUnica from "../models/institucionPlanillaUnicaModel.js?v=1.0.0";

!(function () {
  document.getElementById("btnNuevo").addEventListener("click", () => {
    evaluarBtnNuevo();
  });

  let tabs = document.querySelectorAll(".nav-tabs .nav-link");

  tabs.forEach((tab) => {
    tab.addEventListener("show.bs.tab", (e) => {
      let tabId = e.target.getAttribute("data-bs-target");
      const tabsNuevos = ["codigosObservacion", "documentos", "instituciones"];

      if (!!tabId) {
        tabId = tabId.replace("#", "").replace("-tab-pane", "");
        document.getElementById("btnNuevo").classList.add("d-none");

        if (tabsNuevos.includes(tabId)) {
          document.getElementById("btnNuevo").classList.remove("d-none");
        }
      }
    });
  });

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

      configCodigoObservacion.guardar();
    });

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

    configDocumento.guardar();
  });

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

      configInstitucion.guardar();
    });

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

    if (target.classList.contains("editar-codigo"))
      configCodigoObservacion.editar(target.dataset.id);

    if (target.classList.contains("editar-documento"))
      configDocumento.editar(target.dataset.id);

    if (target.classList.contains("editar-institucion"))
      configInstitucion.editar(target.dataset.id);

    if (target.classList.contains("eliminar-codigo"))
      configCodigoObservacion.eliminar(target.dataset.id);

    if (target.classList.contains("eliminar-documento"))
      configDocumento.eliminar(target.dataset.id);

    if (target.classList.contains("eliminar-institucion"))
      configInstitucion.eliminar(target.dataset.id);
  });
})();

window.onload = () => {
  Promise.all([
    inicializarTablas(),
    configCodigoObservacion.inicializar(),
    configDocumento.inicializar(),
    configInstitucion.inicializar(),
  ])
    .then(() => {
      document.querySelector(".loader") &&
        document.querySelector(".loader").classList.add("d-none");
    })
    .catch(mostrarMensajes.error);
};

function inicializarTablas() {
  return new Promise((resolve, reject) => {
    try {
      configCodigoObservacion.tabla = new CustomDataTable({
        id: "codigosObservacion-tbl",
        alineadoIzquierda: [1, 2, 3, 5],
        noOrdenable: [6],
      });

      configDocumento.tabla = new CustomDataTable({
        id: "documentos-tbl",
        alineadoIzquierda: [1, 3],
        noOrdenable: [4],
      });

      configInstitucion.tabla = new CustomDataTable({
        id: "instituciones-tbl",
        alineadoIzquierda: [2, 4],
        noOrdenable: [5],
      });
      resolve();
    } catch (err) {
      reject(err.message);
    }
  });
}

function evaluarBtnNuevo() {
  let tabActivo = document.querySelector(".tab-pane.active").id;

  switch (tabActivo) {
    case "codigosObservacion-tab-pane":
      configCodigoObservacion.editar();
      break;
    case "documentos-tab-pane":
      configDocumento.editar();
      break;
    case "instituciones-tab-pane":
      configInstitucion.editar();
      break;
    default:
      console.log("No se encontro el tab activo");
      break;
  }
}

const configCodigoObservacion = {
  id: 0,
  cnt: 0,
  data: {},
  tabla: null,
  catalogo: [],
  form: "codigoObservacion-form",
  modal: {
    id: "modal-codigoObservacion",
    mostrar: () => $(`#${configCodigoObservacion.modal.id}`).modal("show"),
    ocultar: () => $(`#${configCodigoObservacion.modal.id}`).modal("hide"),
  },
  campos: {
    codigo: document.getElementById("num-codigoObservacion"),
    concepto: document.getElementById("txt-conceptoCodigoObservacion"),
    validaciones: document.getElementById("txt-validacionesCodigoObservacion"),
    aplicaPersonaNatural: document.getElementById("chk-aplica-personaNatural"),
    aplicaPersonaJuridica: document.getElementById(
      "chk-aplica-personaJuridica"
    ),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        let { data: codigos } =
          await CodigoObservacionPlanillaUnica.obtenerTodos();

        codigos = codigos || [];

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

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

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

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

    this.id = id;

    if (this.id > 0) {
      this.campos.codigo.value = this.data[this.id].codigo;
      this.campos.concepto.value = this.data[this.id].concepto;
      this.campos.validaciones.value = this.data[this.id].validaciones;
    }

    this.modal.mostrar();
  },
  guardar: async function () {
    if (!metodosFormularios.validar({ id: this.form })) return;

    try {
      let codigoObservacion = new CodigoObservacionPlanillaUnica({
        aplicaPersonaJuridica: this.campos.aplicaPersonaJuridica.checked,
        aplicaPersonaNatural: this.campos.aplicaPersonaNatural.checked,
        codigo: this.campos.codigo.value,
        concepto: this.campos.concepto.value,
        id: this.data[this.id]?.id || 0,
        validaciones: this.campos.validaciones.value,
        fechaRegistro:
          this.data[this.id]?.fechaRegistro ||
          moment().format("DD-MM-YYYY hh:mm A"),
        usuario:
          this.data[this.id]?.usuario ||
          localStorage.getItem(`${NOMBRE_SESION}-UName`),
      });

      const respuesta = await codigoObservacion.guardar();

      switch (respuesta.message) {
        case "success":
          codigoObservacion.id = respuesta.data.id;
          if (this.id == 0) {
            codigoObservacion.fechaRegistro = respuesta.data.fechaRegistro;
            codigoObservacion.usuario = respuesta.data.usuario;
          }

          const fila = this.prepararParaFila({
            datos: codigoObservacion,
            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: `trCodigoObservacion${this.id}`,
              })
              .redibujar();
          } else {
            this.tabla
              .actualizarFila({
                datos: fila,
                idFila: `trCodigoObservacion${this.id}`,
              })
              .redibujar();
          }

          this.data[this.id] = codigoObservacion;
          mostrarToastify({
            type: "success",
            message: "Se ha guardado correctamente",
          });

          this.modal.ocultar();
          break;
        default:
          mostrarMensajes.error(err);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    let personasAplicadas = [];

    typeof datos.aplicaPersonaNatural == "string" &&
      datos.aplicaPersonaNatural.length > 0 &&
      (datos.aplicaPersonaNatural = parseInt(datos.aplicaPersonaNatural));

    typeof datos.aplicaPersonaJuridica == "string" &&
      datos.aplicaPersonaJuridica.length > 0 &&
      (datos.aplicaPersonaJuridica = parseInt(datos.aplicaPersonaJuridica));

    if (datos.aplicaPersonaNatural == true || datos.aplicaPersonaNatural == 1) {
      personasAplicadas.push("Persona Natural");
    }

    if (
      datos.aplicaPersonaJuridica == true ||
      datos.aplicaPersonaJuridica == 1
    ) {
      personasAplicadas.push("Persona Juridica");
    }

    let strPersonas = personasAplicadas
      .map((per) => `<span class="badge bg-primary">${per}</span>`)
      .join("<br />");
    return {
      0: datos.codigo,
      1: datos.concepto,
      2: strPersonas,
      3: datos.validaciones,
      4: datos.fechaRegistro,
      5: datos.usuario,
      6: obtenerHTMLBotonesDropdown([
        {
          tipo: "edit",
          selectorClase: "editar-codigo",
          selectorId: id,
          texto: "Editar",
        },
        {
          tipo: "delete",
          selectorClase: "eliminar-codigo",
          selectorId: id,
          texto: "Eliminar",
        },
      ]),
    };
  },
  eliminar: async function (id) {
    const codigo = this.data[id];

    if (!codigo) return;

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el código de observación <b>${codigo.concepto}</b>`,
      });

      if (!confirmacion) return;

      const respuesta = await CodigoObservacionPlanillaUnica.eliminar({
        id: codigo.id,
      });

      switch (respuesta.message) {
        case "success":
          this.tabla
            .eliminarFila({ idFila: `trCodigoObservacion${id}` })
            .redibujar();
          delete this.data[id];
          mostrarToastify({
            type: "info",
            message: "Se ha eliminado correctamente",
          });
          break;
        default:
          mostrarMensajes.error(respuesta.message);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
};

const configDocumento = {
  id: 0,
  cnt: 0,
  data: {},
  tabla: null,
  catalogo: [],
  form: "documento-form",
  modal: {
    id: "modal-documento",
    mostrar: () => $(`#${configDocumento.modal.id}`).modal("show"),
    ocultar: () => $(`#${configDocumento.modal.id}`).modal("hide"),
  },
  campos: {
    codigo: document.getElementById("num-codigoDocumento"),
    tipoDocumento: document.getElementById("cbo-tipoDocumento"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        let { data: documentos } = await TipoDocumento.obtenerTodos();
        this.catalogo = documentos;

        let { data: documentosPlanillaUnica } =
          await DocumentoPlanillaUnica.obtenerTodos();

        documentosPlanillaUnica = documentosPlanillaUnica || [];

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

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

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

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

    let documentosIncluidos = Object.values(this.data).map((doc) =>
      parseInt(doc.idTipoDocumento)
    );

    if (this.id > 0)
      documentosIncluidos = documentosIncluidos.filter(
        (doc) => doc != parseInt(this.data[this.id].idTipoDocumento)
      );

    let opcionesTipoDocumento = this.catalogo
      .filter((doc) => !documentosIncluidos.includes(parseInt(doc.id)))
      .map((doc) => `<option value="${doc.id}">${doc.tipoDocumento}</option>`);

    opcionesTipoDocumento.length > 0 &&
      opcionesTipoDocumento.unshift(
        '<option value="" selected disabled>Seleccione</option>'
      );

    this.campos.tipoDocumento.innerHTML = opcionesTipoDocumento.join("");

    if (this.id > 0) {
      const tmp = this.data[this.id];
      this.campos.codigo.value = tmp.codigo;
      this.campos.tipoDocumento.value = tmp.idTipoDocumento;
    }

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

    this.modal.mostrar();
  },
  guardar: async function () {
    if (!metodosFormularios.validar({ id: this.form })) return;

    try {
      let documentoPlanillaUnica = new DocumentoPlanillaUnica({
        id: this.data[this.id]?.id || 0,
        codigo: this.campos.codigo.value,
        idTipoDocumento: this.campos.tipoDocumento.value,
        tipoDocumento:
          this.campos.tipoDocumento.options[
            this.campos.tipoDocumento.selectedIndex
          ].text,
        fechaRegistro:
          this.data[this.id]?.fechaRegistro ||
          moment().format("DD-MM-YYYY hh:mm A"),
        usuario: this.data[this.id]?.usuario || null,
      });

      const respuesta = await documentoPlanillaUnica.guardar();

      switch (respuesta.message) {
        case "success":
          documentoPlanillaUnica.id = respuesta.data.id;
          if (this.id == 0)
            documentoPlanillaUnica.usuario = respuesta.data.usuario;

          const fila = this.prepararParaFila({
            datos: documentoPlanillaUnica,
            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: `trDocumento${this.id}`,
              })
              .redibujar();
          } else {
            this.tabla
              .updateRow({ idFila: `trDocumento${this.id}`, datos: fila })
              .redibujar();
          }

          this.data[this.id] = documentoPlanillaUnica;

          mostrarToastify({
            type: "success",
            message: "Se guardó correctamente.",
          });
          this.modal.ocultar();
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: datos.codigo,
      1: datos.tipoDocumento,
      2: datos.fechaRegistro,
      3: datos.usuario,
      4: obtenerHTMLBotonesDropdown([
        {
          tipo: "edit",
          selectorClase: "editar-documento",
          selectorId: id,
          texto: "Editar",
        },
        {
          tipo: "delete",
          selectorClase: "eliminar-documento",
          selectorId: id,
          texto: "Eliminar",
        },
      ]),
    };
  },
  eliminar: async function (id) {
    const documento = this.data[id];

    if (!documento) return;

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el tipo de documento <b>${documento.tipoDocumento}</b>`,
      });

      if (!confirmacion) return;

      const respuesta = await DocumentoPlanillaUnica.eliminar({
        id: documento.id,
      });

      switch (respuesta.message) {
        case "success":
          this.tabla.eliminarFila({ idFila: `trDocumento${id}` }).redibujar();
          delete this.data[id];
          mostrarToastify({
            type: "info",
            message: "Se eliminó correctamente.",
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
};

const configInstitucion = {
  id: 0,
  cnt: 0,
  data: {},
  tabla: null,
  form: "institucion-form",
  catalogo: [],
  modal: {
    id: "modal-institucion",
    mostrar: () => $(`#${configInstitucion.modal.id}`).modal("show"),
    ocultar: () => $(`#${configInstitucion.modal.id}`).modal("hide"),
  },
  campos: {
    codigo: document.getElementById("txt-codigoInstitucion"),
    institucion: document.getElementById("cbo-institucion"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        let { data: instituciones } =
          await InstitucionPrevisional.obtenerTodos();
        this.catalogo = instituciones;

        let { data: institucionesPlanillaUnica } =
          await InstitucionPlanillaUnica.obtenerTodos();

        institucionesPlanillaUnica = institucionesPlanillaUnica || [];

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

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

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

        this.tabla.redibujar();

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

    this.id = id;

    let institucionesIncluidas = Object.values(this.data).map((institucion) =>
      parseInt(institucion.idInstitucion)
    );

    if (this.id > 0)
      institucionesIncluidas = institucionesIncluidas.filter(
        (institucion) =>
          institucion != parseInt(this.data[this.id].idInstitucion)
      );

    let opcionesInstituciones = this.catalogo
      .filter((inst) => !institucionesIncluidas.includes(parseInt(inst.id)))
      .map(
        (inst) =>
          `<option value="${inst.id}">${inst.nombreInstitucion}</option>`
      );

    opcionesInstituciones.length > 0 &&
      opcionesInstituciones.unshift(
        '<option value="" selected disabled>Seleccione</option>'
      );

    this.campos.institucion.innerHTML = opcionesInstituciones.join("");

    if (this.id > 0) {
      const tmp = this.data[this.id];
      this.campos.codigo.value = tmp.codigo;
      this.campos.institucion.value = tmp.idInstitucion;
    }

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

    this.modal.mostrar();
  },
  guardar: async function () {
    if (!metodosFormularios.validar({ id: this.form })) return;

    try {
      let institucion = new InstitucionPlanillaUnica({
        id: this.data[this.id]?.id || 0,
        codigo: this.campos.codigo.value.trim(),
        idInstitucion: this.campos.institucion.value,
        nombreInstitucion:
          this.campos.institucion.options[this.campos.institucion.selectedIndex]
            .text,
        fechaRegistro:
          this.data[this.id]?.fechaRegistro ||
          moment().format("DD-MM-YYYY hh:mm A"),
        usuario: this.data[this.id]?.usuario || null,
      });

      const respuesta = await institucion.guardar();

      switch (respuesta.message) {
        case "success":
          institucion.id = respuesta.data.id;
          if (this.id == 0) institucion.usuario = respuesta.data.usuario;
          const fila = this.prepararParaFila({
            datos: institucion,
            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: `trInstitucion${this.id}` })
              .redibujar();
          } else {
            this.tabla
              .actualizarFila({
                idFila: `trInstitucion${this.id}`,
                datos: fila,
              })
              .redibujar();
          }
          this.data[this.id] = institucion;
          mostrarToastify({
            type: "success",
            message: "Se guardó correctamente.",
          });
          this.modal.ocultar();
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.codigo,
      2: datos.nombreInstitucion,
      3: datos.fechaRegistro,
      4: datos.usuario,
      5: obtenerHTMLBotonesDropdown([
        {
          tipo: "edit",
          selectorClase: "editar-institucion",
          selectorId: id,
          texto: "Editar",
        },
        {
          tipo: "delete",
          selectorClase: "eliminar-institucion",
          selectorId: id,
          texto: "Eliminar",
        },
      ]),
    };
  },
  eliminar: async function (id) {
    const institucion = this.data[id];

    if (!institucion) return;

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará la institución <b>${institucion.nombreInstitucion}</b>. Esta acción no se puede deshacer. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      const respuesta = await InstitucionPlanillaUnica.eliminar({
        id: institucion.id,
      });

      switch (respuesta.message) {
        case "success":
          this.tabla.eliminarFila({ idFila: `trInstitucion${id}` }).redibujar();
          delete this.data[id];
          mostrarToastify({
            type: "info",
            message: "Se eliminó correctamente.",
          });
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
};
