#!/usr/bin/env python3
"""
Peticion directa al endpoint VeriFactu de la AEAT (sin pasar por la API).
Usa mTLS con los PEM ya convertidos en data/certs/.
"""

import hashlib
from datetime import datetime, timezone

import requests

# Certificado (los PEM no tienen contrasena)
CERT_PEM = "data/certs/cert_cert.pem"
KEY_PEM  = "data/certs/cert_key.pem"

# Identidad
NIF    = "53950250R"
NOMBRE = "JOSEP VICENT MESTRE LLOBELL"

# Endpoint de pruebas AEAT
URL = "https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP"

# Datos de la factura de prueba
NUM_SERIE    = "TEST-DIRECTO-003"
FECHA_EXP    = "13-05-2026"
TIPO_FACTURA = "F1"
BASE         = 100.00
CUOTA        =  21.00
TOTAL        = 121.00

# Registro anterior (encadenamiento)
PREV_NUM_SERIE = "TEST-DIRECTO-002"
PREV_FECHA_EXP = "13-05-2026"
PREV_HUELLA    = "B4F12C2C6407438501BBB5C81A8443E78860CD2D736D614C032CEDB4CC521D90"

# Timestamp generacion (mismo formato para hash y XML)
_now = datetime.now(timezone.utc)
FECHA_GEN = _now.strftime("%Y-%m-%dT%H:%M:%S+00:00")


def calcular_huella(nif, num_serie, fecha_exp, tipo, cuota, total, prev_hash, fecha_gen):
    """SHA-256 segun la especificacion VeriFactu (formato key=value&)."""
    campos = (
        f"IDEmisorFactura={nif}&"
        f"NumSerieFactura={num_serie}&"
        f"FechaExpedicionFactura={fecha_exp}&"
        f"TipoFactura={tipo}&"
        f"CuotaTotal={cuota:.2f}&"
        f"ImporteTotal={total:.2f}&"
        f"Huella={prev_hash}&"
        f"FechaHoraHusoGenRegistro={fecha_gen}"
    )
    print(f"  Campos huella : {campos}")
    return hashlib.sha256(campos.encode()).hexdigest().upper()


huella = calcular_huella(NIF, NUM_SERIE, FECHA_EXP, TIPO_FACTURA, CUOTA, TOTAL, PREV_HUELLA, FECHA_GEN)

SOAP = f"""<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:sum="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd"
    xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
  <soapenv:Header/>
  <soapenv:Body>
    <sum:RegFactuSistemaFacturacion>
      <sum:Cabecera>
        <sum1:ObligadoEmision>
          <sum1:NombreRazon>{NOMBRE}</sum1:NombreRazon>
          <sum1:NIF>{NIF}</sum1:NIF>
        </sum1:ObligadoEmision>
      </sum:Cabecera>
      <sum:RegistroFactura>
        <sum1:RegistroAlta>
          <sum1:IDVersion>1.0</sum1:IDVersion>
          <sum1:IDFactura>
            <sum1:IDEmisorFactura>{NIF}</sum1:IDEmisorFactura>
            <sum1:NumSerieFactura>{NUM_SERIE}</sum1:NumSerieFactura>
            <sum1:FechaExpedicionFactura>{FECHA_EXP}</sum1:FechaExpedicionFactura>
          </sum1:IDFactura>
          <sum1:NombreRazonEmisor>{NOMBRE}</sum1:NombreRazonEmisor>
          <sum1:TipoFactura>{TIPO_FACTURA}</sum1:TipoFactura>
          <sum1:DescripcionOperacion>Factura de prueba directa</sum1:DescripcionOperacion>
          <sum1:Destinatarios>
            <sum1:IDDestinatario>
              <sum1:NombreRazon>{NOMBRE}</sum1:NombreRazon>
              <sum1:NIF>{NIF}</sum1:NIF>
            </sum1:IDDestinatario>
          </sum1:Destinatarios>
          <sum1:Desglose>
            <sum1:DetalleDesglose>
              <sum1:ClaveRegimen>01</sum1:ClaveRegimen>
              <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
              <sum1:TipoImpositivo>21.00</sum1:TipoImpositivo>
              <sum1:BaseImponibleOimporteNoSujeto>{BASE:.2f}</sum1:BaseImponibleOimporteNoSujeto>
              <sum1:CuotaRepercutida>{CUOTA:.2f}</sum1:CuotaRepercutida>
            </sum1:DetalleDesglose>
          </sum1:Desglose>
          <sum1:CuotaTotal>{CUOTA:.2f}</sum1:CuotaTotal>
          <sum1:ImporteTotal>{TOTAL:.2f}</sum1:ImporteTotal>
          <sum1:Encadenamiento>
            <sum1:RegistroAnterior>
              <sum1:IDEmisorFactura>{NIF}</sum1:IDEmisorFactura>
              <sum1:NumSerieFactura>{PREV_NUM_SERIE}</sum1:NumSerieFactura>
              <sum1:FechaExpedicionFactura>{PREV_FECHA_EXP}</sum1:FechaExpedicionFactura>
              <sum1:Huella>{PREV_HUELLA}</sum1:Huella>
            </sum1:RegistroAnterior>
          </sum1:Encadenamiento>
          <sum1:SistemaInformatico>
            <sum1:NombreRazon>{NOMBRE}</sum1:NombreRazon>
            <sum1:NIF>{NIF}</sum1:NIF>
            <sum1:NombreSistemaInformatico>VerifactuMidAPI</sum1:NombreSistemaInformatico>
            <sum1:IdSistemaInformatico>01</sum1:IdSistemaInformatico>
            <sum1:Version>1.0.0</sum1:Version>
            <sum1:NumeroInstalacion>1</sum1:NumeroInstalacion>
            <sum1:TipoUsoPosibleSoloVerifactu>S</sum1:TipoUsoPosibleSoloVerifactu>
            <sum1:TipoUsoPosibleMultiOT>N</sum1:TipoUsoPosibleMultiOT>
            <sum1:IndicadorMultiplesOT>N</sum1:IndicadorMultiplesOT>
          </sum1:SistemaInformatico>
          <sum1:FechaHoraHusoGenRegistro>{FECHA_GEN}</sum1:FechaHoraHusoGenRegistro>
          <sum1:TipoHuella>01</sum1:TipoHuella>
          <sum1:Huella>{huella}</sum1:Huella>
        </sum1:RegistroAlta>
      </sum:RegistroFactura>
    </sum:RegFactuSistemaFacturacion>
  </soapenv:Body>
</soapenv:Envelope>"""

print(f"\n{'='*60}")
print(f"Endpoint  : {URL}")
print(f"NIF       : {NIF}")
print(f"Num serie : {NUM_SERIE}")
print(f"Huella    : {huella}")
print(f"Fecha gen : {FECHA_GEN}")
print(f"{'='*60}\n")

try:
    resp = requests.post(
        URL,
        data=SOAP.encode("utf-8"),
        headers={"Content-Type": "text/xml; charset=utf-8", "SOAPAction": ""},
        cert=(CERT_PEM, KEY_PEM),
        verify=True,
        timeout=30,
    )
    print(f"HTTP Status : {resp.status_code}")
    print(f"\nRespuesta AEAT:\n{resp.text}")

except requests.exceptions.SSLError as e:
    print(f"[ERROR SSL] Problema con el certificado: {e}")
except requests.exceptions.ConnectionError as e:
    print(f"[ERROR CONEXION] No se pudo conectar: {e}")
except Exception as e:
    print(f"[ERROR] {type(e).__name__}: {e}")
