import forge from 'node-forge';
import { apiGet, apiPost } from './apiClient.js';

let cachedPublicKeyPem = null;

const VERIFACTU_ERROR_MESSAGES = {
  missing_fields: 'Faltan campos obligatorios para registrar el certificado.',
  invalid_json: 'La peticion enviada a VeriFactu no tiene un JSON valido.',
  invalid_password_encrypted: 'La contraseña cifrada no tiene un formato valido.',
  decrypt_failed: 'No se pudo descifrar la contraseña del certificado.',
  file_not_found: 'No se encontro el archivo del certificado.',
  invalid_password_or_format: 'La contraseña del .p12 es incorrecta o el archivo no es valido.',
  certificate_not_yet_valid: 'El certificado aun no es valido por fecha.',
  certificate_expired: 'El certificado ha caducado.',
  temp_storage_failed: 'No se pudo guardar el certificado temporalmente.',
  storage_failed: 'No se pudo guardar el certificado de forma permanente.',
  token_generation_failed: 'No se pudo generar el token de sesion del certificado.',
  hash_storage_error: 'Error leyendo el hash previo de facturacion.',
  hash_save_error: 'Error guardando el hash de la factura.',
  internal_server_error: 'VeriFactu devolvio un error interno del servidor.'
};

export async function getVeriFactuHealth() {
  return apiGet('/api/VeriFactu/health', { auth: false });
}

export async function getVeriFactuPublicKey() {
  return apiGet('/api/VeriFactu/public-key', { auth: false });
}

async function getVeriFactuPublicKeyPem() {
  if (cachedPublicKeyPem) {
    return cachedPublicKeyPem;
  }

  const response = await getVeriFactuPublicKey();
  if (!response?.public_key) {
    throw new Error('La API no devolvio la clave publica de VeriFactu');
  }

  cachedPublicKeyPem = atob(response.public_key);
  return cachedPublicKeyPem;
}

export async function encryptVeriFactuPassword(password) {
  if (!password) {
    throw new Error('La contraseña del certificado no puede estar vacia');
  }

  console.log('[ENCRYPT] Input password:', password);
  const publicKeyPem = await getVeriFactuPublicKeyPem();
  console.log('[ENCRYPT] Got public key');
  const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
  console.log('[ENCRYPT] Parsed public key');
  const encryptedBytes = publicKey.encrypt(forge.util.encodeUtf8(password), 'RSAES-PKCS1-V1_5');
  console.log('[ENCRYPT] RSA encrypted, bytes length:', encryptedBytes.length);
  const result = forge.util.encode64(encryptedBytes);
  console.log('[ENCRYPT] Base64 encoded, result length:', result.length);
  return result;
}

export async function getVeriFactuFormats() {
  return apiGet('/api/VeriFactu/formats', { auth: false });
}

export async function registerVeriFactuCertificate(payload) {
  return apiPost('/api/VeriFactu/certificates/register', payload);
}

export function formatVeriFactuError(errorLike) {
  const raw = String(errorLike?.message || errorLike || '').trim();
  if (!raw) {
    return 'Error desconocido en VeriFactu.';
  }

  // Preserve backend text format for these errors to avoid changing JSON/detail structure.
  if (raw === 'invalid_json' || raw.startsWith('validation_failed') || raw.startsWith('aeat_error:') || raw.startsWith('aeat_fault:')) {
    return raw;
  }

  if (VERIFACTU_ERROR_MESSAGES[raw]) {
    return VERIFACTU_ERROR_MESSAGES[raw];
  }

  return raw;
}

export async function sendVeriFactuInvoice(payload) {
  return apiPost('/api/VeriFactu/facturas', payload);
}

export async function cancelVeriFactuInvoice(payload) {
  return apiPost('/api/VeriFactu/facturas/anular', payload);
}