import { mostrarMensajes } from "../app/funcionesGenerales.js?v=3.0.0";
import Empresa from "./empresaModel.js?v=3.0.0";
import Sucursal from "./sucursalModel.js?v=3.0.0";
import Proyecto from "./proyectoModel.js?v=3.0.0";

class UbicacionEmpresa {
  campos = {
    empresa: null,
    sucursal: null,
    proyecto: null,
  };

  codempresa = null;

  #admin = 0;
  #callback = null;

  catalogos = {
    empresas: [],
    sucursales: [],
    proyectos: [],
  };

  excluir = {
    empresas: [],
    sucursales: [],
    proyectos: [],
  };
  idSuperior = 0;
  idModulo = 0;
  rubros = [];
  agregarOpcionTodos = true;

  constructor({
    campoEmpresa,
    campoSucursal,
    campoProyecto,
    callback = null,
    autoInit = true,
    idModulo = 0,
    idSuperior = 0,
    admin = 0,
    rubros = [],
    codempresa = null,
    agregarOpcionTodos = true,
  }) {
    this.campos.empresa = document.querySelector(`#${campoEmpresa}`);
    this.campos.sucursal = document.querySelector(`#${campoSucursal}`);
    this.campos.proyecto = document.querySelector(`#${campoProyecto}`);

    this.campos.empresa.addEventListener("change", () =>
      this.#evaluarEmpresa()
    );

    this.campos.sucursal.addEventListener("change", () =>
      this.#evaluarSucursal()
    );

    this.campos.proyecto.addEventListener("change", () =>
      this.#evaluarProyecto()
    );

    this.#admin = admin;
    this.#callback = callback;
    this.idModulo = idModulo;
    this.idSuperior = idSuperior;
    this.rubros = rubros;
    this.codempresa = codempresa;

    if (autoInit) this.#inicializarEmpresas({ idModulo, idSuperior, rubros });
    this.agregarOpcionTodos = agregarOpcionTodos;
  }

  async inicializar() {
    await this.#inicializarEmpresas({
      idModulo: this.idModulo,
      idSuperior: this.idSuperior,
      rubros: this.rubros,
    });
  }

  async #inicializarEmpresas({ idModulo, idSuperior, rubros }) {
    this.catalogos.empresas = [];

    try {
      const { data: empresas = [] } = await Empresa.obtenerPorUsuarioModulo({
        idModulo,
        idSuperior,
        rubros,
      });

      this.catalogos.empresas = empresas;

      let opciones = this.catalogos.empresas
        .filter(
          (empresa) =>
            !this.excluir.empresas.includes(parseInt(empresa.codempresa))
        )
        .map(
          (empresa) =>
            `<option value="${empresa.codempresa}">${empresa.nombreEmpresa}</option>`
        );

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

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

      if (this.codempresa) {
        this.campos.empresa.value = this.codempresa;
      }

      await this.#evaluarEmpresa();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  }

  async #evaluarEmpresa() {
    const codempresa = this.campos.empresa.value;

    try {
      let sucursales = [];

      if (codempresa) {
        const empresa = this.catalogos.empresas.find(
          (empresa) => parseInt(empresa.codempresa) === parseInt(codempresa)
        );
        const { data: sucursalesEmpresa = [] } =
          await Sucursal.obtenerPorUsuarioModulo({
            codempresa,
            idConfiguracion: empresa.idConfiguracion,
          });

        sucursales = sucursalesEmpresa;
      }

      this.catalogos.sucursales = sucursales;

      let opciones = this.catalogos.sucursales
        .filter(
          (sucursal) =>
            !this.excluir.sucursales.includes(parseInt(sucursal.codsucursal))
        )
        .map(
          (sucursal) =>
            `<option value="${sucursal.codsucursal}">${sucursal.nombreSucursal}</option>`
        );

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

      opciones.length > 0 && codempresa
        ? opciones.unshift(
            '<option value="" selected disabled>Seleccione una sucursal</option>'
          )
        : opciones.unshift(
            '<option value="" selected disabled>No hay sucursales disponibles</option>'
          );

      !codempresa &&
        (opciones = [
          `<option value="" selected disabled>Seleccione una empresa</option>`,
        ]);

      this.campos.sucursal.innerHTML = opciones.join("");
      $(`#${this.campos.sucursal.id}`).selectpicker("destroy").selectpicker();
      await this.#evaluarSucursal();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  }

  async #evaluarSucursal() {
    const codempresa = this.campos.empresa.value;
    const codsucursal = this.campos.sucursal.value;

    try {
      let proyectos = [];

      if (codempresa && codsucursal && codsucursal > 0) {
        const sucursal = this.catalogos.sucursales.find(
          (sucursal) => parseInt(sucursal.codsucursal) === parseInt(codsucursal)
        );
        const { data: proyectosSucursal = [] } =
          await Proyecto.obtenerPorUsuarioModulo({
            codempresa,
            codsucursal,
            idConfiguracion: sucursal.idConfiguracion || 0,
          });

        proyectos = proyectosSucursal;
      }

      this.catalogos.proyectos = proyectos;

      let opciones = this.catalogos.proyectos
        .filter(
          (proyecto) =>
            !this.excluir.proyectos.includes(parseInt(proyecto.codproyecto))
        )
        .map(
          (proyecto) =>
            `<option value="${proyecto.codproyecto}">${proyecto.nombreProyecto}</option>`
        );

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

      opciones.length > 0 && codsucursal && codsucursal > 0
        ? opciones.unshift(
            '<option value="" selected disabled>Seleccione un proyecto</option>'
          )
        : codsucursal == 0
        ? null
        : (opciones = [
            `<option value="" selected disabled>No hay proyectos disponibles</option>`,
          ]);

      !codsucursal &&
        (opciones = [
          `<option value="" selected disabled>Seleccione una sucursal</option>`,
        ]);

      codsucursal &&
        codsucursal == 0 &&
        (opciones = [`<option value="0">Todos los proyectos</option>`]);

      this.campos.proyecto.innerHTML = opciones.join("");
      $(`#${this.campos.proyecto.id}`).selectpicker("destroy").selectpicker();
      this.#evaluarProyecto();
    } catch (err) {
      mostrarMensajes.error(err);
    }
  }

  obtenerUbicacion() {
    return {
      codempresa: this.campos.empresa.value,
      codsucursal: this.campos.sucursal.value,
      codproyecto: this.campos.proyecto.value,
      labels: {
        empresa:
          this.campos.empresa.options[this.campos.empresa.selectedIndex].text,
        sucursal:
          this.campos.sucursal.options[this.campos.sucursal.selectedIndex].text,
        proyecto:
          this.campos.proyecto.options[this.campos.proyecto.selectedIndex].text,
      },
    };
  }

  async asignarSucursal({ codsucursal }) {
    if (
      this.catalogos.sucursales.find(
        (sucursal) => sucursal.codsucursal == codsucursal
      )
    ) {
      this.campos.sucursal.value = codsucursal;
      $(`#${this.campos.sucursal.id}`).selectpicker("destroy").selectpicker();
      await this.#evaluarSucursal();
    }
  }

  async asignarProyecto({ codproyecto }) {
    if (
      this.catalogos.proyectos.find(
        (proyecto) => proyecto.codproyecto == codproyecto
      )
    ) {
      this.campos.proyecto.value = codproyecto;
      $(`#${this.campos.proyecto.id}`).selectpicker("destroy").selectpicker();
      await this.#evaluarProyecto();
    }
  }

  async #evaluarProyecto() {
    const { codempresa, codsucursal, codproyecto } = this.obtenerUbicacion();

    if (codempresa && codsucursal && codproyecto) {
      this.#callback && this.#callback();
    }
  }

  bloquear() {
    this.campos.empresa.disabled = true;
    this.campos.sucursal.disabled = true;
    this.campos.proyecto.disabled = true;
    $(`#${this.campos.sucursal.id}`).selectpicker("destroy").selectpicker();
    $(`#${this.campos.proyecto.id}`).selectpicker("destroy").selectpicker();
  }

  desbloquear() {
    this.campos.empresa.disabled = false;
    this.campos.sucursal.disabled = false;
    this.campos.proyecto.disabled = false;
    $(`#${this.campos.sucursal.id}`).selectpicker("destroy").selectpicker();
    $(`#${this.campos.proyecto.id}`).selectpicker("destroy").selectpicker();
  }

  limpiar() {
    const empresas = this.catalogos.empresas.filter(
      (empresa) => !this.excluir.empresas.includes(empresa.codempresa)
    );
    let opciones = empresas.map(
      (empresa) =>
        `<option value="${empresa.codempresa}">${empresa.nombreEmpresa}</option>`
    );
    opciones.unshift(`<option value="" selected disabled>Seleccione</option>`);

    this.campos.empresa.innerHTML = opciones.join("");
    this.campos.sucursal.innerHTML = `<option value="" disabled selected>Seleccione una empresa</option>`;
    this.campos.proyecto.innerHTML = `<option value="" disabled selected>Seleccione una sucursal</option>`;
    $(`#${this.campos.sucursal.id}`).selectpicker("destroy").selectpicker();
    $(`#${this.campos.proyecto.id}`).selectpicker("destroy").selectpicker();
  }

  async destruir() {
    return new Promise((resolve) => {
      if (!!this.campos.empresa) {
        const clonEmpresa = this.campos.empresa.cloneNode(true),
          clonSucursal = this.campos.sucursal.cloneNode(true),
          clonProyecto = this.campos.proyecto.cloneNode(true);

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

        this.campos.empresa.parentNode.replaceChild(
          clonEmpresa,
          this.campos.empresa
        );
        this.campos.sucursal.parentNode.replaceChild(
          clonSucursal,
          this.campos.sucursal
        );
        this.campos.proyecto.parentNode.replaceChild(
          clonProyecto,
          this.campos.proyecto
        );
      }

      this.#admin = 0;

      this.campos.empresa.innerHTML = `<option value="" selected disabled>No hay empresas</option>`;
      this.campos.sucursal.innerHTML = `<option value="" selected disabled>Seleccione una empresa</option>`;
      this.campos.proyecto.innerHTML = `<option value="" selected disabled>Seleccione una sucursal</option>`;
      $(`#${this.campos.sucursal.id}`).selectpicker();
      $(`#${this.campos.proyecto.id}`).selectpicker();
      this.campos.empresa = null;
      this.campos.sucursal = null;
      this.campos.proyecto = null;

      resolve();
    });
  }

  obtenerSucursales() {
    return this.catalogos.sucursales;
  }

  obtenerProyectos() {
    return this.catalogos.proyectos;
  }
}

export default UbicacionEmpresa;
