import { NOMBRE_SESION } from "./constantes.js?v=2.0.0";

const mostrarMensajes = {};

mostrarMensajes.success = function ({
  message = "Proceso realizado exitosamente",
  title = "¡Éxito!",
  autoClose = false,
  allowOutsideClick = true,
  showCancelButton = false,
  showCloseButton = false,
  type = "success",
}) {
  const mensaje =
    typeof message === "string"
      ? message
      : typeof message === "object"
      ? message.join("<br>")
      : "";

  const opciones = {
    title,
    html: mensaje,
    icon: type,
    showConfirmButton: true,
    confirmButtonText: "Aceptar",
    allowOutsideClick,
    showCancelButton,
    showCloseButton,
  };

  autoClose && (opciones.timer = 3000);

  Swal.fire(opciones);
};

mostrarMensajes.info = function ({
  message = "Proceso realizado exitosamente",
  title = "¡Éxito!",
  autoClose = false,
  allowOutsideClick = true,
  type = "info",
  showCancelButton = false,
  showCloseButton = false,
}) {
  mostrarMensajes.success({
    message,
    title,
    autoClose,
    allowOutsideClick,
    type,
    showCancelButton,
    showCloseButton,
  });
};
mostrarMensajes.warning = function ({
  message = "Parece que ocurrió algo inesperado",
  title = "¡Advertencia!",
  autoClose = false,
  allowOutsideClick = true,
  type = "warning",
}) {
  mostrarMensajes.success({
    message,
    title,
    autoClose,
    allowOutsideClick,
    type,
  });
};
mostrarMensajes.error = function ({
  status = 500,
  message = "Ocurrió un error interno en el servidor",
  title = "¡Error!",
  autoClose = false,
  allowOutsideClick = false,
  type = "error",
}) {
  document.querySelector(".loader") &&
    document.querySelector(".loader").classList.add("d-none");
  console.error(status, message);
  switch (status) {
    case 403:
      mostrarMensajes.success({
        message:
          "Parece que tu sesión ha expirado, por favor inicia sesión nuevamente",
        title: "¡Advertencia!",
        autoClose: false,
        allowOutsideClick: false,
        type: "warning",
      });
      break;
    default:
      mostrarMensajes.success({
        message,
        title,
        autoClose,
        allowOutsideClick,
        type,
      });
      break;
  }
};
mostrarMensajes.confirm = async function ({
  message = "",
  title = "¿Estás seguro?",
  confirmButtonText = "Aceptar",
  cancelButtonText = "Cancelar",
  icon = "question",
  allowOutsideClick = false,
  allowEscapeKey = false,
}) {
  return new Promise((resolve) => {
    Swal.fire({
      title,
      html: message,
      icon,
      showCancelButton: true,
      confirmButtonText,
      cancelButtonText,
      allowOutsideClick,
      allowEscapeKey,
      allowEnterKey: false,
      stopKeydownPropagation: false,
    }).then((result) => {
      resolve(result.isConfirmed);
    });
  });
};

const mostrarToastify = function ({
  message = "",
  type = "success",
  time = 3000,
}) {
  let color = "#2ecc71";
  switch (type) {
    case "success":
      color = "#2ecc71";
      break;
    case "error":
      color = "#e74c3c";
      break;
    case "warning":
      color = "#f1c40f";
      break;
    case "info":
      color = "#3498db";
      break;
    default:
      color = "#2ecc71";
      break;
  }

  Toastify({
    text: message,
    duration: time,
    close: true,
    gravity: "top",
    position: "right",
    stopOnFocus: true,
    style: {
      background: color,
    },
  }).showToast();
};

const obtenerParametroUrl = (nombreParametro) => {
  nombreParametro = nombreParametro
    .replace(/[\[]/, "\\[")
    .replace(/[\]]/, "\\]");

  let regex = new RegExp("[\\?&]" + nombreParametro + "=([^&#]*)"),
    resultado = regex.exec(location.search);

  return resultado === null
    ? ""
    : decodeURIComponent(resultado[1].replace(/\+/g, " "));
};

const validarContrasenia = (contrasenia) => {
  let length = document.getElementById("pass-length"),
    letter = document.getElementById("pass-lower"),
    capital = document.getElementById("pass-upper"),
    number = document.getElementById("pass-number"),
    contraseniaValida = true;
  contrasenia.match(/[a-z]/g)
    ? (letter.classList.remove("invalid"), letter.classList.add("valid"))
    : (letter.classList.remove("valid"),
      letter.classList.add("invalid"),
      (contraseniaValida = false));
  contrasenia.match(/[A-Z]/g)
    ? (capital.classList.remove("invalid"), capital.classList.add("valid"))
    : (capital.classList.remove("valid"),
      capital.classList.add("invalid"),
      (contraseniaValida = false));
  contrasenia.match(/[0-9]/g)
    ? (number.classList.remove("invalid"), number.classList.add("valid"))
    : (number.classList.remove("valid"),
      number.classList.add("invalid"),
      (contraseniaValida = false));
  6 <= contrasenia.length
    ? (length.classList.remove("invalid"), length.classList.add("valid"))
    : (length.classList.remove("valid"),
      length.classList.add("invalid"),
      (contraseniaValida = false));

  return contraseniaValida;
};

const obtenerHTMLBotonesDropdown = (botones = []) => {
  let html = `<div class="dropdown">
    <button class="btn btn-soft-secondary btn-sm dropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false">
      <i class="ri-more-fill"></i>
    </button>
    <ul class="dropdown-menu dropdown-menu-end">
    ${botones.map((boton) => obtenerHTMLBotonLi(boton)).join("")}
    </ul>
  </div>`;

  return html;
};

const obtenerHTMLBotonLi = ({
  icono = "fas fa-info-circle",
  texto = "Información",
  muted = true,
  selectorClase = "",
  selectorId = "",
  tipo = "editar",
}) => {
  switch (tipo) {
    case "info":
      icono = "fas fa-info-circle";
      break;
    case "edit":
      icono = "ri-pencil-fill";
      break;
    case "delete":
      icono = "ri-delete-bin-6-fill";
      break;
    case "download":
      icono = "ri-download-2-fill";
      break;
    case "upload":
      icono = "ri-upload-2-fill";
      break;
    case "view":
      icono = "ri-eye-fill";
      break;
    case "password":
      icono = "ri-key-fill";
      break;
    case "view":
      icono = "ri-eye-fill";
      break;
    case "pdf":
      icono = "fa-solid fa-file-pdf";
      break;
    case "pay":
      icono = "ri-money-dollar-circle-fill";
      break;
    case "advertise":
      icono = "fas fa-exclamation-triangle";
      break;
    case "config":
      icono = "ri-settings-3-fill";
      break;
    case "lock":
      icono = "ri-lock-fill";
      break;
    case "unlock":
      icono = "ri-lock-unlock-line";
      break;
    default:
      break;
  }

  return `<li>
  <a class="dropdown-item ${selectorClase}" data-id="${selectorId}" href="javascript:void(0);">
  <i class="${icono} align-bottom me-2 ${muted && "text-muted"}"></i> ${texto}
  </a>
  </li>`;
};

const obtenerHTMLBadge = ({
  tipo = "success",
  texto = "¡Éxito!",
  claseIcono = null,
  tamanioTexto = null,
}) => {
  let clase = "bg-info";
  let htmlIcono = claseIcono ? `<i class="${claseIcono} me-2"></i>` : "";

  switch (tipo) {
    case "success":
      clase = "bg-success";
      break;
    case "error":
      clase = "bg-danger";
      break;
    case "warning":
      clase = "bg-warning";
      break;
    case "info":
      clase = "bg-info";
      break;
    case "primary":
      clase = "bg-primary";
      break;
    case "secondary":
      clase = "bg-secondary";
      break;
    case "dark":
      clase = "bg-dark";
      break;
    default:
      clase = "bg-info";
      break;
  }

  return `<span class="badge ${clase} ${tamanioTexto}">${htmlIcono} ${texto}</span>`;
};

const obtenerNombreModulo = () => {
  let modulo = obtenerParametroUrl("mod");
  if (modulo != null && modulo?.trim().length > 0)
    modulo = atob(decodeURIComponent(modulo));

  return modulo;
};

const descargarArchivo = ({ nombreArchivo, blobURL = null, url }) => {
  if (blobURL != null && blobURL.trim().length > 0) url = blobURL;
  let link = document.createElement("a");
  link.href = url;
  link.download = nombreArchivo;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

function str_pad({ input, padLength, padString, padType }) {
  let half = "";
  let padToGo;
  const _strPadRepeater = function (s, len) {
    let collect = "";
    while (collect.length < len) {
      collect += s;
    }
    collect = collect.substr(0, len);
    return collect;
  };
  input += "";
  padString = padString !== undefined ? padString : " ";
  if (
    padType !== "STR_PAD_LEFT" &&
    padType !== "STR_PAD_RIGHT" &&
    padType !== "STR_PAD_BOTH"
  ) {
    padType = "STR_PAD_RIGHT";
  }
  if ((padToGo = padLength - input.length) > 0) {
    if (padType === "STR_PAD_LEFT") {
      input = _strPadRepeater(padString, padToGo) + input;
    } else if (padType === "STR_PAD_RIGHT") {
      input = input + _strPadRepeater(padString, padToGo);
    } else if (padType === "STR_PAD_BOTH") {
      half = _strPadRepeater(padString, Math.ceil(padToGo / 2));
      input = half + input + half;
      input = input.substr(0, padLength);
    }
  }
  return input;
}

const validarCorreoElectronico = ({ email }) => {
  if (email.trim().length == 0) return false;

  const expresionRegular = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
  return expresionRegular.test(email);
};

const obtenerArrayColores = (e) => {
  if (null !== document.getElementById(e)) {
    e = document.getElementById(e).getAttribute("data-colors");
    if (e)
      return (e = JSON.parse(e)).map(function (e) {
        var t = e.replace(" ", "");
        if (-1 === t.indexOf(",")) {
          var a = getComputedStyle(document.documentElement).getPropertyValue(
            t
          );
          return a || t;
        }
        e = e.split(",");
        return 2 != e.length
          ? t
          : "rgba(" +
              getComputedStyle(document.documentElement).getPropertyValue(
                e[0]
              ) +
              "," +
              e[1] +
              ")";
      });
  }
};

const iniciarAnimacionContador = () => {
  var e = document.querySelectorAll(".counter-value");
  function s(e) {
    return e.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }
  e &&
    Array.from(e).forEach(function (o) {
      !(function e() {
        var t = +o.getAttribute("data-target"),
          a = +o.innerText,
          n = t / 250;
        n < 1 && (n = 1),
          a < t
            ? ((o.innerText = (a + n).toFixed(0)), setTimeout(e, 1))
            : (o.innerText = s(t)),
          s(o.innerText);
      })();
    });
};

const obtenerNombreUsuario = () => {
  let nombreUsuario = "",
    idUsuario = localStorage.getItem(`${NOMBRE_SESION}-UId`);

  if (idUsuario) {
    nombreUsuario = localStorage.getItem(`${NOMBRE_SESION}-${idUsuario}-UName`);
  }

  return nombreUsuario;
};

const calcularEdad = ({ fechaNacimiento = null }) => {
  let edad = "";

  if (fechaNacimiento != null && fechaNacimiento.trim().length > 0) {
    edad = moment().diff(moment(fechaNacimiento, "DD-MM-YYYY"), "years");
  }

  return edad;
};

const abrirPDF = ({
  modulo = null,
  nombreArchivo = null,
  contenedor = null,
  blobURL = null,
  urlReal = null,
}) => {
  if (!!urlReal) blobURL = urlReal;
  if (!nombreArchivo && !blobURL) {
    mostrarMensajes.error({
      message: "No se ha especificado el nombre del archivo o la URL del mismo",
    });
    return;
  }

  let urlModulo = modulo ? `${modulo}/` : "",
    urlArchivo = blobURL || `../../../../${urlModulo}docs/${nombreArchivo}`,
    url = `main/assets/libs/pdfjs/web/viewer.html?file=${encodeURIComponent(
      urlArchivo
    )}`;

  if (contenedor) {
    document.getElementById(contenedor).src = url;
    return;
  }

  let link = document.createElement("a");
  link.href = url;
  link.target = "_blank";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

const b64toBlob = (b64Data, contentType = "", sliceSize = 512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, { type: contentType });
  return blob;
};

export {
  abrirPDF,
  b64toBlob,
  calcularEdad,
  descargarArchivo,
  iniciarAnimacionContador,
  mostrarMensajes,
  mostrarToastify,
  obtenerArrayColores,
  obtenerHTMLBadge,
  obtenerHTMLBotonesDropdown,
  obtenerHTMLBotonLi,
  obtenerNombreModulo,
  obtenerNombreUsuario,
  obtenerParametroUrl,
  str_pad,
  validarContrasenia,
  validarCorreoElectronico,
};
