import http from "../api/http";

const PASSWORD_PREFIX = "rsa:";

const decodeBase64 = (value: string): Uint8Array => {
  const normalized = String(value || "").trim();
  const binary = window.atob(normalized);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i += 1) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes;
};

const encodeBase64 = (bytes: Uint8Array): string => {
  let binary = "";
  bytes.forEach((byte) => {
    binary += String.fromCharCode(byte);
  });
  return window.btoa(binary);
};

const loadPasswordPublicKey = async (): Promise<CryptoKey> => {
  const resp = await http.get("/auth/password-public-key");
  const publicKey = String(resp?.data?.publicKey || "").trim();
  if (!publicKey) {
    throw new Error("Password public key is missing");
  }
  return window.crypto.subtle.importKey(
    "spki",
    decodeBase64(publicKey),
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    false,
    ["encrypt"],
  );
};

const getPasswordPublicKey = async (): Promise<CryptoKey> => {
  if (!window.isSecureContext || !window.crypto?.subtle) {
    throw new Error("Current page is not in a secure context");
  }
  return loadPasswordPublicKey();
};

export const encryptLoginPassword = async (password: string): Promise<string> => {
  try {
    const cryptoKey = await getPasswordPublicKey();
    const encoded = new TextEncoder().encode(password);
    const encrypted = await window.crypto.subtle.encrypt({ name: "RSA-OAEP" }, cryptoKey, encoded);
    return `${PASSWORD_PREFIX}${encodeBase64(new Uint8Array(encrypted))}`;
  } catch (error) {
    console.warn("Login password encryption is unavailable, falling back to plain password submission.", error);
    return password;
  }
};
