"use-strict";

import CustomDataTable from "../../../../assets/js/app/CustomDataTable.js?v=1.0.0";
import {
  mostrarMensajes,
  mostrarToastify,
  obtenerHTMLBotonesDropdown,
} from "../../../../assets/js/app/funcionesGenerales.js?v=1.0.0";
import metodosFormularios from "../../../../assets/js/app/metodosFormularios.js?v=1.0.0";
import Usuario from "../../../../assets/js/models/usuarioModel.js?v=1.0.0";
import TipoPlanilla from "../models/tipoPlanillaModel.js?v=1.0.0";
import Empresa from "../../../../assets/js/models/empresaModel.js?v=1.0.0";
import Sucursal from "../../../../assets/js/models/sucursalModel.js?v=1.0.0";
import Proyecto from "../../../../assets/js/models/proyectoModel.js?v=1.0.0";

!(function () {
  document
    .getElementById("btn-guardar-configuracion")
    .addEventListener("click", () => {
      configUsuario.guardar();
    });

  document
    .getElementById("btn-cancelar-configuracion")
    .addEventListener("click", () => {
      configUsuario.cancelar();
    });

  document
    .getElementById("btn-asignar-tipo-planilla")
    .addEventListener("click", () => {
      configTipoPlanilla.editar();
    });

  document
    .getElementById("btn-asignar-empresa")
    .addEventListener("click", () => {
      configEmpresa.editar();
    });
  document
    .getElementById("btn-asignar-sucursal")
    .addEventListener("click", () => {
      configSucursal.editar();
    });
  document
    .getElementById("btn-asignar-proyecto")
    .addEventListener("click", () => {
      configProyecto.editar();
    });

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

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

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

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

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

    target.classList.contains("configurar-usuario") &&
      configUsuario.editar(target.dataset.id);

    target.classList.contains("eliminar-tipo-planilla") &&
      configTipoPlanilla.eliminar(target.dataset.id);

    target.classList.contains("eliminar-empresa") &&
      configEmpresa.eliminar(target.dataset.id);

    target.classList.contains("eliminar-sucursal") &&
      configSucursal.eliminar(target.dataset.id);

    target.classList.contains("eliminar-proyecto") &&
      configProyecto.eliminar(target.dataset.id);
  });
})();

window.onload = () => {
  inicializarTablas()
    .then(() => configUsuario.inicializar())
    .then(() => configTipoPlanilla.inicializar())
    .then(() => configEmpresa.inicializar())
    .then(() => {
      document.querySelector(".loader") &&
        document.querySelector(".loader").classList.add("d-none");
    })
    .catch(mostrarMensajes.error);
};

const inicializarTablas = () => {
  return new Promise((resolve, reject) => {
    try {
      configUsuario.tabla = new CustomDataTable({
        id: "usuarios-tbl",
        alineadoIzquierda: [2, 3],
        noOrdenable: [5],
      });

      configTipoPlanilla.tabla = new CustomDataTable({
        id: "tipos-planilla-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [2],
        filaSeleccionable: false,
        responsive: false,
        adicional: {
          lengthChange: false,
          searching: false,
        },
      });

      $("#tipos-planilla-tbl tbody").on("click", "td", function () {
        if ($(this).closest("tr").attr("id") && $(this).index() != 2) {
          if ($(this).closest("tr").hasClass("selected")) {
            $(this).closest("tr").removeClass("selected");
            configTipoPlanilla.data[configTipoPlanilla.seleccionado].empresas =
              configEmpresa.obtenerDatos();
            configTipoPlanilla.seleccionado = 0;
            configEmpresa.limpiar();
          } else {
            let trSelected = configTipoPlanilla.tabla.tabla.$("tr.selected");
            if (trSelected.length > 0) {
              let idSelected = trSelected
                .attr("id")
                .replace("trTipoPlanilla", "");
              configTipoPlanilla.data[idSelected].empresas =
                configEmpresa.obtenerDatos();
            }
            configTipoPlanilla.tabla.tabla
              .$("tr.selected")
              .removeClass("selected");
            $(this).closest("tr").addClass("selected");
            let id = $(this)
              .closest("tr")
              .attr("id")
              .replace("trTipoPlanilla", "");
            configTipoPlanilla.seleccionado = id;
            configEmpresa.configurar({
              empresas: configTipoPlanilla.data[id].empresas,
            });
          }
        }
      });

      configEmpresa.tabla = new CustomDataTable({
        id: "empresas-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [2],
        responsive: false,
        filaSeleccionable: false,
        adicional: {
          lengthChange: false,
          searching: false,
        },
      });

      $("#empresas-tbl tbody").on("click", "td", function () {
        if ($(this).closest("tr").attr("id") && $(this).index() != 2) {
          if ($(this).closest("tr").hasClass("selected")) {
            $(this).closest("tr").removeClass("selected");
            configEmpresa.data[configEmpresa.seleccionado].sucursales =
              configSucursal.obtenerDatos();
            configEmpresa.seleccionado = 0;
            configSucursal.limpiar();
          } else {
            let trSelected = configEmpresa.tabla.tabla.$("tr.selected");
            if (trSelected.length > 0) {
              let idSelected = trSelected.attr("id").replace("trEmpresa", "");
              configEmpresa.data[idSelected].sucursales =
                configSucursal.obtenerDatos();
            }
            configEmpresa.tabla.tabla.$("tr.selected").removeClass("selected");
            $(this).closest("tr").addClass("selected");
            let id = $(this).closest("tr").attr("id").replace("trEmpresa", "");
            configEmpresa.seleccionado = id;

            configSucursal.inicializar({
              codempresa: configEmpresa.data[id].codempresa,
              sucursales: configEmpresa.data[id].sucursales,
            });
          }
        }
      });

      configSucursal.tabla = new CustomDataTable({
        id: "sucursales-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [2],
        responsive: false,
        filaSeleccionable: false,
        adicional: {
          lengthChange: false,
          searching: false,
        },
      });

      $("#sucursales-tbl tbody").on("click", "td", function () {
        if ($(this).closest("tr").attr("id") && $(this).index() != 2) {
          if ($(this).closest("tr").hasClass("selected")) {
            $(this).closest("tr").removeClass("selected");
            configSucursal.data[configSucursal.seleccionado].proyectos =
              configProyecto.obtenerDatos();
            configSucursal.seleccionado = 0;
            configProyecto.limpiar();
          } else {
            let trSelected = configSucursal.tabla.tabla.$("tr.selected");
            if (trSelected.length > 0) {
              let idSelected = trSelected.attr("id").replace("trSucursal", "");
              configSucursal.data[idSelected].proyectos =
                configProyecto.obtenerDatos();
            }
            configSucursal.tabla.tabla.$("tr.selected").removeClass("selected");
            $(this).closest("tr").addClass("selected");
            let id = $(this).closest("tr").attr("id").replace("trSucursal", "");
            configSucursal.seleccionado = id;
            let empresa = configEmpresa.obtenerSeleccionado(),
              sucursal = configSucursal.obtenerSeleccionado();
            configProyecto.inicializar({
              codempresa: empresa.codempresa || 0,
              codsucursal: sucursal.codsucursal || 0,
              proyectos: configSucursal.data[id].proyectos,
            });
          }
        }
      });

      configProyecto.tabla = new CustomDataTable({
        id: "proyectos-tbl",
        alineadoIzquierda: [1],
        noOrdenable: [2],
        responsive: false,
        adicional: {
          lengthChange: false,
          searching: false,
        },
      });
      resolve();
    } catch (err) {
      reject(err);
    }
  });
};

const configUsuario = {
  id: 0,
  cnt: 0,
  data: {},
  tabla: null,
  tabs: {
    usuarios: document.getElementById("usuarios-tab"),
    edicion: document.getElementById("configuracion-tab"),
  },
  botones: {
    guardar: document.getElementById("btns-configuracion"),
  },
  campos: {
    nombreUsuario: document.getElementById("txt-nombre-usuario"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: usuarios = [] } = await Usuario.obtenerPorModulo({
          idModulo: 0,
        });

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

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

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

        this.tabla.redibujar();

        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  editar: async function (id = 0) {
    if (!id) {
      mostrarMensajes.warning({ message: "Debe seleccionar un usuario" });
      return;
    }

    try {
      this.id = id;

      const usuario = this.data[id];

      this.campos.nombreUsuario.value = usuario?.nombreCompleto || "";

      const { data: asignaciones = [] } =
        await Usuario.obtenerAsignacionesPorModulo({
          idUsuario: usuario.id,
        });

      await configTipoPlanilla.configurar({
        tiposAsignados: asignaciones,
      });

      Object.values(this.tabs).forEach((tab) =>
        tab.classList.toggle("disabled")
      );
      this.tabs.edicion.click();
      Object.values(this.botones).forEach((btn) =>
        btn.classList.toggle("d-none")
      );
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  guardar: async function () {
    const asignaciones = configTipoPlanilla.obtenerDatos();
    try {
      let confirmacion = true;

      if (asignaciones.length === 0) {
        confirmacion = await mostrarMensajes.confirm({
          message:
            "Está a punto de guardar una configuración vacía, ¿desea continuar?",
        });
      }

      if (!confirmacion) return;

      let usuario = new Usuario({ id: this.data[this.id].id });

      const respuesta = await usuario.guardarAsignacionesModulo({
        asignaciones,
      });

      switch (respuesta.message) {
        case "success":
          mostrarToastify({
            type: "success",
            message: "Configuración guardada correctamente",
          });
          this.cancelar();
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: `<div class="tbl-img-container">
                  <div class="tbl-img" style="background-image:url('main/assets/images/users/${datos.foto}')"></div>
              </div>`,
      2: datos.nombreCompleto,
      3: `<span class="text-muted">[No es posible mostrar, debe ingresar a la configuración]</span>`,
      4: datos.fechaRegistro,
      5: obtenerHTMLBotonesDropdown([
        {
          tipo: "custom",
          icono: "fa-solid fa-gears",
          selectorClase: "configurar-usuario",
          selectorId: id,
          texto: "Configurar",
        },
      ]),
    };
  },
  cancelar: function () {
    Object.values(this.tabs).forEach((tab) => tab.classList.toggle("disabled"));
    this.tabs.usuarios.click();
    Object.values(this.botones).forEach((btn) =>
      btn.classList.toggle("d-none")
    );
  },
};

const configTipoPlanilla = {
  id: 0,
  cnt: 0,
  seleccionado: 0,
  data: {},
  tabla: null,
  catalogo: [],
  form: "tipoPlanilla-form",
  modal: {
    id: "modal-tipoPlanilla",
    mostrar: () => $(`#${configTipoPlanilla.modal.id}`).modal("show"),
    ocultar: () => $(`#${configTipoPlanilla.modal.id}`).modal("hide"),
  },
  campos: {
    tipoPlanilla: document.getElementById("cbo-tipo-planilla"),
  },
  inicializar: function () {
    return new Promise(async (resolve, reject) => {
      try {
        const { data: tipos = [] } = await TipoPlanilla.obtenerTodosParaCombo();

        this.catalogo = tipos;
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  configurar: function ({ tiposAsignados = [] }) {
    return new Promise(async (resolve) => {
      await this.limpiar();
      tiposAsignados.forEach((tipo) => {
        this.cnt++;
        this.data[this.cnt] = tipo;

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

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

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

    try {
      this.id = id;

      let tiposIncluidos = Object.values(this.data).map((tipo) =>
        parseInt(tipo.idTipoPlanilla)
      );

      if (this.id > 0) {
        let tmp = this.data[this.id];

        tiposIncluidos = tiposIncluidos.filter(
          (tipo) => tipo !== parseInt(tmp.idTipoPlanilla)
        );
      }

      const tiposPlanilla = !tiposIncluidos.includes(0)
        ? this.catalogo.filter(
            (tipo) => !tiposIncluidos.includes(parseInt(tipo.id))
          )
        : [];

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

      opciones.length > 0
        ? opciones.unshift(
            `<option value="" selected disabled>Seleccione</option>`
          )
        : opciones.push(
            `<option value="" selected disabled>No hay tipos de planilla disponibles</option>`
          );

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

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

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

    let tipoPlanilla =
      this.catalogo.find(
        (tipo) => parseInt(tipo.id) == parseInt(this.campos.tipoPlanilla.value)
      ) || {};

    const datos = {
      idTipoPlanilla: this.campos.tipoPlanilla.value,
      codtipoplanilla: tipoPlanilla.codtipoplanilla || 0,
      tipoPlanilla:
        this.campos.tipoPlanilla.options[this.campos.tipoPlanilla.selectedIndex]
          .text,
      empresas: [],
    };

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

    this.data[this.id] = datos;
    this.modal.ocultar();
  },
  eliminar: async function (id) {
    let tmp = this.data[id];

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el tipo de planilla <strong>${tmp.tipoPlanilla}</strong> y todos los datos asociados a este. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

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

      if (id == this.seleccionado) {
        this.seleccionado = 0;
        configEmpresa.limpiar();
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.tipoPlanilla,
      2: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-tipo-planilla",
          selectorId: id,
        },
      ]),
    };
  },
  limpiar: function () {
    return new Promise(async (resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      if (this.seleccionado > 0) {
        await configEmpresa.limpiar();
      }
      this.seleccionado = 0;
      resolve();
    });
  },
  obtenerDatos: function () {
    if (this.seleccionado > 0) {
      this.data[this.seleccionado].empresas = configEmpresa.obtenerDatos();
    }
    return JSON.parse(JSON.stringify(Object.values(this.data)));
  },
};

const configEmpresa = {
  id: 0,
  cnt: 0,
  seleccionado: 0,
  data: {},
  empresas: [],
  tabla: null,
  modal: {
    id: "modal-empresa",
    mostrar: () => $(`#${configEmpresa.modal.id}`).modal("show"),
    ocultar: () => $(`#${configEmpresa.modal.id}`).modal("hide"),
  },
  form: "empresa-form",
  campos: {
    empresa: document.getElementById("cbo-empresa"),
  },
  inicializar: function () {
    return new Promise((resolve, reject) => {
      Empresa.obtenerPorModulo({ idModulo: 0 })
        .then((response) => {
          this.empresas = response.data || [];
          resolve();
        })
        .catch(reject);
    });
  },
  configurar: async function ({ empresas = [] }) {
    try {
      await this.limpiar();

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

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

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

      this.tabla.redibujar();
      document.getElementById("btn-asignar-empresa").disabled = false;
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  editar: function (id = 0) {
    metodosFormularios.limpiar({ id: this.form }).then(() => {
      this.id = 0;

      let empresasIncluidas = Object.values(this.data).map((emp) =>
        parseInt(emp.idEmpresa)
      );

      if (this.id > 0) {
        let tmp = this.data[id];

        empresasIncluidas = empresasIncluidas.filter(
          (emp) => emp != parseInt(tmp.idEmpresa)
        );
      }

      const empresas = !empresasIncluidas.includes(0)
        ? this.empresas.filter(
            (empresa) => !empresasIncluidas.includes(parseInt(empresa.id))
          )
        : [];

      let opciones = empresas.map(
        (empresa) =>
          `<option value="${empresa.id}">${empresa.nombreEmpresa}</option>`
      );

      opciones.length > 0 &&
        opciones.length == Object.values(this.empresas).length &&
        opciones.unshift(`<option value="0">Todas las empresas</option>`);

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

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

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

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

    let empresa =
      this.empresas.find(
        (emp) => parseInt(emp.id) == parseInt(this.campos.empresa.value)
      ) || {};

    const data = {
      id: this.id > 0 ? this.data[this.id].id : 0,
      idEmpresa: empresa.id || 0,
      codempresa: empresa.codempresa || 0,
      nombreEmpresa:
        this.campos.empresa.options[this.campos.empresa.selectedIndex].text,
      sucursales:
        this.campos.empresa.value == "0"
          ? [
              {
                id: 0,
                codsucursal: 0,
                nombreSucursal: "Todas las sucursales",
                proyectos: [
                  {
                    id: 0,
                    codproyecto: 0,
                    nombreProyecto: "Todos los proyectos",
                  },
                ],
              },
            ]
          : [],
    };

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

    this.data[this.id] = data;
    this.tabla.redibujar();
    this.modal.ocultar();
  },
  eliminar: async function (id) {
    let tmp = this.data[id];
    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará la empresa <strong>${tmp.nombreEmpresa}</strong> y todos los datos asociados a esta. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

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

      if (id == this.seleccionado) {
        this.seleccionado = 0;
        await configSucursal.limpiar();
      }
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.nombreEmpresa,
      2: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-empresa",
          selectorId: id,
        },
      ]),
    };
  },
  limpiar: function () {
    return new Promise(async (resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      if (this.seleccionado > 0) {
        await configSucursal.limpiar();
      }
      this.seleccionado = 0;
      document.getElementById("btn-asignar-empresa").disabled = true;
      resolve();
    });
  },
  obtenerDatos: function () {
    if (this.seleccionado > 0) {
      this.data[this.seleccionado].sucursales = configSucursal.obtenerDatos();
    }
    return JSON.parse(JSON.stringify(Object.values(this.data)));
  },
  obtenerSeleccionado: function () {
    return this.data[this.seleccionado] || {};
  },
};

const configSucursal = {
  id: 0,
  cnt: 0,
  data: {},
  sucursales: [],
  tabla: null,
  modal: {
    id: "modal-sucursal",
    mostrar: () => $(`#${configSucursal.modal.id}`).modal("show"),
    ocultar: () => $(`#${configSucursal.modal.id}`).modal("hide"),
  },
  form: "sucursal-form",
  campos: {
    sucursal: document.getElementById("cbo-sucursal"),
  },
  inicializar: function ({ codempresa = 0, sucursales = [] }) {
    if (codempresa == 0) {
      this.sucursales = [];
      this.configurar({ sucursales });
      return;
    }

    Sucursal.obtenerTodosPorEmpresa({ codempresa })
      .then((response) => {
        const suc = response.data || [];

        this.sucursales = suc;

        this.configurar({ sucursales });
      })
      .catch(mostrarMensajes.error);
  },
  configurar: async function ({ sucursales = [] }) {
    await this.limpiar();

    try {
      sucursales.forEach((sucursal) => {
        this.cnt++;
        this.data[this.cnt] = sucursal;

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

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

      this.tabla.redibujar();
      document.getElementById("btn-asignar-sucursal").disabled = false;
    } catch (err) {
      if (!!err) mostrarMensajes.error(err);
    }
  },
  editar: async function (id = 0) {
    await metodosFormularios.limpiar({ id: this.form });

    this.id = id;

    let sucursalesIncluidas = Object.values(this.data).map((suc) =>
      parseInt(suc.codsucursal)
    );

    if (this.id > 0) {
      let tmp = this.data[id];

      sucursalesIncluidas = sucursalesIncluidas.filter(
        (suc) => suc != parseInt(tmp.codsucursal)
      );
    }

    const sucursales = !sucursalesIncluidas.includes(0)
      ? this.sucursales.filter(
          (sucursal) =>
            !sucursalesIncluidas.includes(parseInt(sucursal.codsucursal))
        )
      : [];

    let opciones = sucursales.map(
      (sucursal) =>
        `<option value="${sucursal.codsucursal}">${sucursal.nombreSucursal}</option>`
    );

    opciones.length > 0 &&
      opciones.length == Object.values(this.sucursales).length &&
      opciones.unshift(`<option value="0">Todas las sucursales</option>`);

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

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

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

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

    let sucursal =
      this.sucursales.find(
        (suc) =>
          parseInt(suc.codsucursal) == parseInt(this.campos.sucursal.value)
      ) || {};

    const data = {
      id: this.data[this.id]?.id || 0,
      codsucursal: sucursal.codsucursal || 0,
      nombreSucursal:
        this.campos.sucursal.options[this.campos.sucursal.selectedIndex].text,
      proyectos:
        this.campos.sucursal.value == "0"
          ? [
              {
                id: 0,
                codproyecto: 0,
                nombreProyecto: "Todos los proyectos",
              },
            ]
          : [],
    };

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

    this.data[this.id] = data;
    this.tabla.redibujar();
    this.modal.ocultar();
  },
  eliminar: async function (id) {
    let tmp = this.data[id];

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará la sucursal <strong>${tmp.nombreSucursal}</strong> y todos los datos asociados a esta. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

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

      if (id == this.seleccionado) {
        this.seleccionado = 0;
        await configProyecto.limpiar();
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.nombreSucursal,
      2: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-sucursal",
          selectorId: id,
        },
      ]),
    };
  },
  limpiar: function () {
    return new Promise(async (resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      if (this.seleccionado > 0) {
        await configProyecto.limpiar();
      }
      this.seleccionado = 0;
      document.getElementById("btn-asignar-sucursal").disabled = true;
      resolve();
    });
  },
  obtenerDatos: function () {
    if (this.seleccionado > 0) {
      this.data[this.seleccionado].proyectos = configProyecto.obtenerDatos();
    }
    return JSON.parse(JSON.stringify(Object.values(this.data)));
  },
  obtenerSeleccionado: function () {
    return this.data[this.seleccionado];
  },
};

const configProyecto = {
  id: 0,
  cnt: 0,
  data: {},
  proyectos: [],
  tabla: null,
  modal: {
    id: "modal-proyecto",
    mostrar: () => $(`#${configProyecto.modal.id}`).modal("show"),
    ocultar: () => $(`#${configProyecto.modal.id}`).modal("hide"),
  },
  form: "proyecto-form",
  campos: {
    proyecto: document.getElementById("cbo-proyecto"),
  },
  inicializar: async function ({
    codempresa = 0,
    codsucursal = 0,
    proyectos = [],
  }) {
    if (codempresa == 0 || codsucursal == 0) {
      this.proyectos = [];
      await this.configurar({ proyectos });
      return;
    }

    try {
      const { data: pro = [] } = await Proyecto.obtenerTodosPorEmpresaSucursal({
        codempresa,
        codsucursal,
      });

      this.proyectos = pro;

      await this.configurar({ proyectos });
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  configurar: function ({ proyectos = [] }) {
    return new Promise(async (resolve, reject) => {
      await this.limpiar();

      try {
        proyectos.forEach((proyecto) => {
          this.cnt++;
          this.data[this.cnt] = proyecto;

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

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

        this.tabla.redibujar();
        document.getElementById("btn-asignar-proyecto").disabled = false;
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  },
  editar: async function (id = 0) {
    await metodosFormularios.limpiar({ id: this.form });

    this.id = id;
    let proyectosIncluidos = Object.values(this.data).map((pro) =>
      parseInt(pro.codproyecto)
    );

    if (this.id > 0) {
      let tmp = this.data[id];

      proyectosIncluidos = proyectosIncluidos.filter(
        (pro) => pro != parseInt(tmp.codproyecto)
      );
    }

    const proyectos = !proyectosIncluidos.includes(0)
      ? this.proyectos.filter(
          (proyecto) =>
            !proyectosIncluidos.includes(parseInt(proyecto.codproyecto))
        )
      : [];

    let opciones = proyectos.map(
      (proyecto) =>
        `<option value="${proyecto.codproyecto}">${proyecto.nombreProyecto}</option>`
    );

    opciones.length > 0 &&
      opciones.length == Object.values(this.proyectos).length &&
      opciones.unshift(`<option value="0">Todos los proyectos</option>`);

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

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

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

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

    let proyecto =
      this.proyectos.find(
        (pro) =>
          parseInt(pro.codproyecto) == parseInt(this.campos.proyecto.value)
      ) || {};

    const data = {
      id: this.data[this.id]?.id || 0,
      codproyecto: proyecto.codproyecto || 0,
      nombreProyecto:
        this.campos.proyecto.options[this.campos.proyecto.selectedIndex].text,
    };

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

    this.data[this.id] = data;
    this.tabla.redibujar();
    this.modal.ocultar();
  },
  eliminar: async function (id) {
    let tmp = this.data[id];

    try {
      const confirmacion = await mostrarMensajes.confirm({
        message: `Se eliminará el proyecto <strong>${tmp.nombreProyecto}</strong> y todos los datos asociados a este. ¿Desea continuar?`,
      });

      if (!confirmacion) return;

      delete this.data[id];
      this.tabla.eliminarFila({ idFila: `trProyecto${id}` }).redibujar();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  },
  prepararParaFila: function ({ datos, id }) {
    return {
      0: id,
      1: datos.nombreProyecto,
      2: obtenerHTMLBotonesDropdown([
        {
          tipo: "delete",
          texto: "Eliminar",
          selectorClase: "eliminar-proyecto",
          selectorId: id,
        },
      ]),
    };
  },
  limpiar: function () {
    return new Promise((resolve) => {
      this.id = 0;
      this.cnt = 0;
      this.data = {};
      this.tabla.limpiar().redibujar();
      document.getElementById("btn-asignar-proyecto").disabled = true;
      resolve();
    });
  },
  obtenerDatos: function () {
    return JSON.parse(JSON.stringify(Object.values(this.data)));
  },
};
