import { NOMBRE_SESION } from "../app/constantes.js?v=1.0.0";
import { mostrarMensajes } from "../app/funcionesGenerales.js?v=1.0.0";
import metodosFetch from "../app/metodosFetch.js?v=1.0.0";

class Usuario {
  constructor({
    apellidos,
    bloqueado = 0,
    email,
    estado,
    fechaRegistro,
    foto,
    id,
    nombres,
    roles = [],
    sesionActual,
    ultimoIngreso,
    username,
  }) {
    this.apellidos = apellidos;
    this.bloqueado = bloqueado;
    this.email = email;
    this.estado = estado;
    this.fechaRegistro = fechaRegistro;
    this.foto = foto;
    this.id = id;
    this.nombres = nombres;
    this.roles = roles;
    this.sesionActual = sesionActual;
    this.ultimoIngreso = ultimoIngreso;
    this.username = username;
  }

  async autenticar({ contrasenia }) {
    try {
      contrasenia = btoa(contrasenia);
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "autenticar",
          username: this.username,
          contrasenia,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async cambiarContrasenia({
    contrasenia,
    nuevaContrasenia,
    origen = "Usuario",
  }) {
    try {
      contrasenia = btoa(contrasenia);
      nuevaContrasenia = btoa(nuevaContrasenia);
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "cambiarContrasenia",
          id: this.id,
          username: this.username,
          contrasenia,
          nuevaContrasenia,
          origen,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async solicitarRestablecimientoContrasenia() {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "solicitarRestablecimientoContrasenia",
          email: this.email,
          username: this.username,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async cerrarSesion() {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "cerrarSesion",
        },
      });

      switch (respuesta.message) {
        case "success":
          let userId = localStorage.getItem(`${NOMBRE_SESION}-UId`);
          localStorage.removeItem(`${NOMBRE_SESION}-UId`);
          localStorage.removeItem(`${NOMBRE_SESION}-${userId}-menu`);
          localStorage.removeItem(`${NOMBRE_SESION}-${userId}-UName`);
          window.top.location.href = "./";
          break;
        default:
          mostrarMensajes.error(respuesta);
          break;
      }
    } catch (err) {
      mostrarMensajes.error(err);
    }
  }

  static async obtenerTodos() {
    try {
      const respuesta = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "obtenerTodos",
          loader: false,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async obtenerRoles({ id }) {
    try {
      const respuesta = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "obtenerRoles",
          id: btoa(id),
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async verificarDisponibilidad({ id = 0, username }) {
    try {
      const response = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "verificarDisponibilidad",
          id: btoa(id),
          username,
        },
      });

      return response;
    } catch (err) {
      throw err;
    }
  }

  async guardar({ contrasenia = null }) {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "guardar",
          ...this,
          id: btoa(this.id),
          contrasenia: contrasenia ? btoa(contrasenia) : null,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async crearContrasenia({ id, username, email }) {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "crearContrasenia",
          id: btoa(id),
          username,
          email,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async cambiarEstado() {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "cambiarEstado",
          id: btoa(this.id),
          bloqueado: this.bloqueado,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async eliminar() {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "eliminar",
          id: btoa(this.id),
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async actualizarFoto({ archivo }) {
    try {
      const data = new FormData();
      data.append("accion", "actualizarFoto");
      data.append("id", btoa(this.id));
      data.append("archivo", archivo);

      const respuesta = await metodosFetch.postWithFiles({
        archivo: "controllers/usuarioController",
        data,
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async obtenerTodosParaCombo() {
    try {
      const respuesta = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "obtenerTodosParaCombo",
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async obtenerPorModulo({ idModulo = 0 }) {
    try {
      const respuesta = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "obtenerPorModulo",
          idModulo: btoa(idModulo),
        },
        loader: false,
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  static async obtenerAsignacionesPorModulo({ idUsuario, idModulo = 0 }) {
    try {
      const respuesta = await metodosFetch.get({
        archivo: "controllers/usuarioController",
        parametros: {
          accion: "obtenerAsignacionesPorModulo",
          idUsuario: btoa(idUsuario),
          idModulo: btoa(idModulo),
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }

  async guardarAsignacionesModulo({ asignaciones }) {
    try {
      const respuesta = await metodosFetch.post({
        archivo: "controllers/usuarioController",
        data: {
          accion: "guardarAsignacionesModulo",
          id: btoa(this.id),
          asignaciones,
        },
      });

      return respuesta;
    } catch (err) {
      throw err;
    }
  }
}

export default Usuario;
