<?php
// factura_arca_procesar.php
// Procesa el formulario ARCA, llama a AFIP WSFE y muestra resultado

ini_set('display_errors', 1);
error_reporting(E_ALL);

require_once __DIR__ . '/../config.php';

// Ajustá estas rutas si tu carpeta afip está en otro lado
require_once __DIR__ . '/../afip/afip_config.php';
require_once __DIR__ . '/../afip/AfipWsaa.php';
require_once __DIR__ . '/../afip/AfipWsfe.php';

// -------------------------------------------------------------
// 1) Conexión a base de datos (por si después queremos guardar)
// -------------------------------------------------------------
try {
    $dsn = "mysql:host={$sql_details['host']};dbname={$sql_details['db']};port={$sql_details['port']};charset=utf8";
    $pdo = new PDO($dsn, $sql_details['user'], $sql_details['pass'], [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ]);
} catch (PDOException $e) {
    die("Error de conexión a la base de datos: " . htmlspecialchars($e->getMessage()));
}

// -------------------------------------------------------------
// 2) Leer y validar datos básicos del POST
// -------------------------------------------------------------
function limpiar_num($v) {
    $v = trim((string)$v);
    // Los hidden llegan como 1234.5600 (punto decimal), por seguridad
    $v = str_replace(',', '.', $v);
    return (float)$v;
}

$errores = [];

$cbteTipoLetra = $_POST['cbte_tipo_letra'] ?? '';
$puntoVenta    = (int)($_POST['punto_venta'] ?? 0);
$concepto      = (int)($_POST['concepto'] ?? 1);

// Comprobante asociado (para NC/ND)
$cbteAsocPv  = isset($_POST['cbte_asoc_pv']) ? (int)$_POST['cbte_asoc_pv'] : 0;
$cbteAsocNro = isset($_POST['cbte_asoc_nro']) ? (int)$_POST['cbte_asoc_nro'] : 0;


// Campos principales
$invoiceId  = $_POST['invoice_id']  ?? '';
$infoId     = $_POST['info_id']     ?? '';
$storeId    = $_POST['store_id']    ?? '';
$customerId = $_POST['customer_id'] ?? '';

$cbteTipoLetra = $_POST['cbte_tipo_letra'] ?? '';
$puntoVenta    = (int)($_POST['punto_venta'] ?? 0);
$concepto      = (int)($_POST['concepto'] ?? 1);

$fechaCbte     = $_POST['fecha_cbte']      ?? '';
$fchServDesde  = $_POST['fch_serv_desde']  ?? '';
$fchServHasta  = $_POST['fch_serv_hasta']  ?? '';

$docTipo       = (int)($_POST['doc_tipo'] ?? 0);
$docNroStr     = preg_replace('/\D+/', '', $_POST['doc_nro'] ?? ''); // sólo dígitos

$condicionIvaReceptorId = isset($_POST['condicion_iva_receptor_id'])
    ? (int)$_POST['condicion_iva_receptor_id']
    : 0;

// Comprobante asociado (para NC/ND)
$cbteAsocTipo = isset($_POST['cbte_asoc_tipo']) ? (int)$_POST['cbte_asoc_tipo'] : 0;
$cbteAsocPv   = isset($_POST['cbte_asoc_pv'])   ? (int)$_POST['cbte_asoc_pv']   : 0;
$cbteAsocNro  = isset($_POST['cbte_asoc_nro'])  ? (int)$_POST['cbte_asoc_nro']  : 0;


$totalNeto     = limpiar_num($_POST['total_neto']     ?? 0);
$totalIva      = limpiar_num($_POST['total_iva']      ?? 0);
$totalIibb     = limpiar_num($_POST['total_iibb']     ?? 0);
$totalGeneral  = limpiar_num($_POST['total_general']  ?? 0);

$itemsPost     = $_POST['items'] ?? [];

// Determinar tipo de comprobante numérico para validaciones
$cbteTipoForValidation = 0;
if ($cbteTipoLetra) {
    $partsTmp = explode('|', $cbteTipoLetra);
    $cbteTipoForValidation = isset($partsTmp[0]) ? (int)$partsTmp[0] : 0;
}


// Validaciones mínimas (además de las del JS)
if ($invoiceId === '') {
    $errores[] = 'Falta invoice_id.';
}
if (!$puntoVenta) {
    $errores[] = 'Punto de venta inválido.';
}
if (!$docTipo) {
    $errores[] = 'DocTipo del receptor es obligatorio.';
}
if ($docNroStr === '') {
    $errores[] = 'DocNro del receptor es obligatorio.';
}
if ($totalGeneral <= 0) {
    $errores[] = 'El total de la factura debe ser mayor a cero.';
}
if (!is_array($itemsPost) || !count($itemsPost)) {
    $errores[] = 'Se requiere al menos un ítem.';
}

// Regla AFIP típica para B → Consumidor Final
// DocTipo 99 + monto < 10M → DocNro debe ser 0
if ($docTipo === 99 && $totalGeneral < 10000000 && $docNroStr !== '0') {
    $errores[] = 'Para DocTipo 99 (Consumidor Final) y montos menores a $10.000.000, el DocNro debe ser 0. '
               . 'Si querés informar un DNI, usá DocTipo 96.';
}

if (!empty($errores)) {
    echo "<h3>Error de validación (servidor)</h3><ul>";
    foreach ($errores as $e) {
        echo "<li>" . htmlspecialchars($e) . "</li>";
    }
    echo "</ul><p><a href=\"factura_arca.php?invoice_id=" . urlencode($invoiceId) . "\">Volver al formulario</a></p>";
    exit;
}


// Regla AFIP típica para B → Consumidor Final
// DocTipo 99 + monto < 10M → DocNro debe ser 0
if ($docTipo === 99 && $totalGeneral < 10000000 && $docNroStr !== '0') {
    $errores[] = 'Para DocTipo 99 (Consumidor Final) y montos menores a $10.000.000, el DocNro debe ser 0. '
               . 'Si querés informar un DNI, usá DocTipo 96.';
}

// Notas de Crédito / Débito deben tener comprobante asociado
if (in_array($cbteTipoForValidation, [2, 3, 7, 8], true)) {
    if ($cbteAsocPv <= 0 || $cbteAsocNro <= 0) {
        $errores[] = 'Para Notas de Crédito / Débito es obligatorio indicar el comprobante asociado (PtoVta y Número).';
    }
}

// -------------------------------------------------------------
// 3) Preparar campos para AFIP WSFE
// -------------------------------------------------------------

// cbte_tipo y letra (ej: "6|B")
$cbteTipo = 0;
$letra    = '';
if ($cbteTipoLetra) {
    $parts    = explode('|', $cbteTipoLetra);
    $cbteTipo = isset($parts[0]) ? (int)$parts[0] : 0;
    $letra    = $parts[1] ?? '';
}

// Formato fechas AFIP: yyyymmdd
$cbteFch          = str_replace('-', '', $fechaCbte);
$fchServDesdeAfip = ($concepto >= 2 && $fchServDesde) ? str_replace('-', '', $fchServDesde) : null;
$fchServHastaAfip = ($concepto >= 2 && $fchServHasta) ? str_replace('-', '', $fchServHasta) : null;
$fchVtoPagoAfip   = $cbteFch; // podés ajustarlo si querés otra fecha

$docNro = (float)$docNroStr;

// AFIP: montos
$impNeto  = round($totalNeto, 2);
$impIva   = round($totalIva, 2);
$impTrib  = round($totalIibb, 2);
$impTotal = round($totalGeneral, 2);

// TotConc, OpEx (en este escenario simple, 0)
$impTotConc = 0.00;
$impOpEx    = 0.00;

// -------------------------------------------------------------
// 3.b) Condición frente al IVA del receptor (RG 5616)
//      Campo nuevo: CondicionIVAReceptorId
// -------------------------------------------------------------
// Versión actual: sólo ajustado para Consumidor Final
// - DocTipo 96 (DNI) o 99 → Consumidor Final (id 5 según AFIP para comprobantes B/C).
$condicionIVAReceptorId = null;
if ($docTipo === 96 || $docTipo === 99) {
    $condicionIVAReceptorId = 5; // Consumidor Final
}
// Más adelante podemos mapear RI, Monotributo, etc. leyendo customers.customer_iva_cond

// -------------------------------------------------------------
// 4) Calcular estructura de IVA discriminado para AFIP
// -------------------------------------------------------------
function afip_iva_id_from_tasa($tasa) {
    $tasa = (float)$tasa;
    switch (true) {
        case abs($tasa - 21.0) < 0.01:  return 5;
        case abs($tasa - 10.5) < 0.01: return 4;
        case abs($tasa - 27.0) < 0.01: return 6;
        case abs($tasa - 5.0)  < 0.01: return 8;
        case abs($tasa - 2.5)  < 0.01: return 9;
        case abs($tasa - 0.0)  < 0.01: return 3; // 0%
        default:
            // por defecto lo mando a 21% (ajustá si querés forzar error)
            return 5;
    }
}

$ivaPorAlicuota = []; // [IdIva => ['Id'=>, 'BaseImp'=>, 'Importe'=>]]

foreach ($itemsPost as $idx => $it) {
    $cantidad   = isset($it['cantidad']) ? (float)$it['cantidad'] : 0.0;
    $pUnit      = isset($it['precio_unitario']) ? (float)$it['precio_unitario'] : 0.0;
    $ivaPct     = isset($it['iva_porcentaje']) ? (float)$it['iva_porcentaje'] : 0.0;

    if ($cantidad <= 0 || $pUnit < 0) {
        continue;
    }

    $netoLinea = $cantidad * $pUnit;
    $ivaLinea  = $netoLinea * $ivaPct / 100.0;

    $idIva = afip_iva_id_from_tasa($ivaPct);
    if (!isset($ivaPorAlicuota[$idIva])) {
        $ivaPorAlicuota[$idIva] = [
            'Id'      => $idIva,
            'BaseImp' => 0.00,
            'Importe' => 0.00,
        ];
    }

    $ivaPorAlicuota[$idIva]['BaseImp'] += $netoLinea;
    $ivaPorAlicuota[$idIva]['Importe'] += $ivaLinea;
}

// Redondear importes IVA
foreach ($ivaPorAlicuota as &$row) {
    $row['BaseImp'] = round($row['BaseImp'], 2);
    $row['Importe'] = round($row['Importe'], 2);
}
unset($row);

// -------------------------------------------------------------
// 5) Tributos (ej: Ingresos Brutos)
// -------------------------------------------------------------
$tributos = [];
if ($impTrib > 0) {
    $tributos[] = [
        'Id'      => 2, // 2 = IIBB en WSFE
        'Desc'    => 'Ingresos Brutos',
        'BaseImp' => round($impNeto, 2), // o la base que corresponda
        'Alic'    => 0.00,
        'Importe' => $impTrib,
    ];
}

// -------------------------------------------------------------
// 6) Llamar a AFIP WSFE
// -------------------------------------------------------------
if (function_exists('afip_config')) {
    $configAfip = afip_config();
} else {
    $configAfip = require __DIR__ . '/../afip/afip_config.php';
}

$wsfe = new AfipWsfe($configAfip);

try {
    // 6.1) Obtener último comprobante autorizado para este PtoVta / Tipo
    $ultimo = $wsfe->FECompUltimoAutorizado($puntoVenta, $cbteTipo);
    $cbteNroDesde = isset($ultimo->CbteNro) ? ((int)$ultimo->CbteNro + 1) : 1;
    $cbteNroHasta = $cbteNroDesde;

    // 6.2) Armar SOLO el detalle que AfipWsfe espera en "Detalle"
        $detalle = [
        'Concepto'    => $concepto,
        'DocTipo'     => $docTipo,
        
        'DocNro'      => $docNro,
        'CbteDesde'   => $cbteNroDesde,
        'CbteHasta'   => $cbteNroHasta,
        'CbteFch'     => $cbteFch,
        'ImpTotal'    => $impTotal,
        'ImpTotConc'  => $impTotConc,
        'ImpNeto'     => $impNeto,
        'ImpOpEx'     => $impOpEx,
        'ImpTrib'     => $impTrib,
        'ImpIVA'      => $impIva,
        'MonId'       => 'PES',
        'MonCotiz'    => 1.00,
         'CondicionIVAReceptorId' => $condicionIvaReceptorId, // ← NUEVO
    ];

    // Si es Nota de Crédito / Débito, informar comprobante asociado
    if (in_array($cbteTipo, [2, 3, 7, 8], true) && $cbteAsocPv > 0 && $cbteAsocNro > 0) {
        // Por defecto asociamos a Factura A (1) o Factura B (6) según la letra
        $cbteAsocTipo = in_array($cbteTipo, [2, 3], true) ? 1 : 6;

        $detalle['CbtesAsoc'] = [
            'CbteAsoc' => [
                [
                    'Tipo'  => $cbteAsocTipo,
                    'PtoVta'=> $cbteAsocPv,
                    'Nro'   => $cbteAsocNro,
                    // Si en tu WSDL está Cuit / CbteFch y los necesitás,
                    // podés agregarlos acá más adelante.
                ],
            ],
        ];
    }

    // Campo nuevo exigido por RG 5616: CondicionIVAReceptorId
    if ($condicionIVAReceptorId !== null) {
        $detalle['CondicionIVAReceptorId'] = $condicionIVAReceptorId;
    }


    // Campo nuevo exigido por RG 5616: CondicionIVAReceptorId
    if ($condicionIVAReceptorId !== null) {
        $detalle['CondicionIVAReceptorId'] = $condicionIVAReceptorId;
    }

    if ($concepto == 2 || $concepto == 3) {
        $detalle['FchServDesde'] = $fchServDesdeAfip;
        $detalle['FchServHasta'] = $fchServHastaAfip;
        $detalle['FchVtoPago']   = $fchVtoPagoAfip;
    }

    if (!empty($ivaPorAlicuota)) {
        $detalle['Iva'] = [
            'AlicIva' => array_values($ivaPorAlicuota),
        ];
    }

    if (!empty($tributos)) {
        $detalle['Tributos'] = [
            'Tributo' => $tributos,
        ];
    }

    // Estructura que AfipWsfe.php espera:
    $solicitud = [
        'PtoVta'   => $puntoVenta,
        'CbteTipo' => $cbteTipo,
        'Detalle'  => $detalle, // un solo detalle plano
    ];

    $res = $wsfe->FECAESolicitar($solicitud);

} catch (Exception $e) {
    echo "<h3>Error al llamar a AFIP WSFE</h3>";
    echo "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>";
    echo "<p><a href=\"factura_arca.php?invoice_id=" . urlencode($invoiceId) . "\">Volver al formulario</a></p>";
    exit;
}

// -------------------------------------------------------------
// 7) Procesar respuesta de AFIP
// -------------------------------------------------------------
$detalleResp = null;
$resultado   = null;
$cae         = null;
$caeVto      = null;
$obs         = [];

if (isset($res->FeDetResp->FECAEDetResponse)) {
    $det = $res->FeDetResp->FECAEDetResponse;
    if (is_array($det)) {
        $detalleResp = $det[0];
    } else {
        $detalleResp = $det;
    }

    $resultado = (string)$detalleResp->Resultado;
    $cae       = isset($detalleResp->CAE) ? (string)$detalleResp->CAE : null;
    $caeVto    = isset($detalleResp->CAEFchVto) ? (string)$detalleResp->CAEFchVto : null;

    if (isset($detalleResp->Observaciones->Obs)) {
        $o = $detalleResp->Observaciones->Obs;
        if (is_array($o)) {
            foreach ($o as $ob) {
                $obs[] = '[' . $ob->Code . '] ' . $ob->Msg;
            }
        } else {
            $obs[] = '[' . $o->Code . '] ' . $o->Msg;
        }
    }
}

// Errores generales del WS
$erroresAfip = [];
if (isset($res->Errors->Err)) {
    $errs = $res->Errors->Err;
    if (is_array($errs)) {
        foreach ($errs as $er) {
            $erroresAfip[] = '[' . $er->Code . '] ' . $er->Msg;
        }
    } else {
        $erroresAfip[] = '[' . $errs->Code . '] ' . $errs->Msg;
    }
}

// -------------------------------------------------------------
// 7.b) Guardar en base de datos si la factura fue APROBADA
// -------------------------------------------------------------
if ($detalleResp && $resultado === 'A') {

    // Fecha del comprobante desde AFIP (CbteFch) o fallback cbteFch
    $cbteFchAfip = !empty($detalleResp->CbteFch) ? $detalleResp->CbteFch : $cbteFch;
    $fechaCbteSql = null;
    if ($cbteFchAfip && preg_match('/^\d{8}$/', $cbteFchAfip)) {
        $dtCbte = DateTime::createFromFormat('Ymd', $cbteFchAfip);
        if ($dtCbte) {
            $fechaCbteSql = $dtCbte->format('Y-m-d');
        }
    }

    // CAE Vto
    $caeVtoSql = null;
    if (!empty($caeVto) && preg_match('/^\d{8}$/', $caeVto)) {
        $dtCaeVto = DateTime::createFromFormat('Ymd', $caeVto);
        if ($dtCaeVto) {
            $caeVtoSql = $dtCaeVto->format('Y-m-d');
        }
    }

    // Fechas de servicio / vto pago
    $fchServDesdeSql = null;
    if ($fchServDesdeAfip && preg_match('/^\d{8}$/', $fchServDesdeAfip)) {
        $dtSrvD = DateTime::createFromFormat('Ymd', $fchServDesdeAfip);
        if ($dtSrvD) {
            $fchServDesdeSql = $dtSrvD->format('Y-m-d');
        }
    }

    $fchServHastaSql = null;
    if ($fchServHastaAfip && preg_match('/^\d{8}$/', $fchServHastaAfip)) {
        $dtSrvH = DateTime::createFromFormat('Ymd', $fchServHastaAfip);
        if ($dtSrvH) {
            $fchServHastaSql = $dtSrvH->format('Y-m-d');
        }
    }

    $fchVtoPagoSql = null;
    if ($fchVtoPagoAfip && preg_match('/^\d{8}$/', $fchVtoPagoAfip)) {
        $dtVto = DateTime::createFromFormat('Ymd', $fchVtoPagoAfip);
        if ($dtVto) {
            $fchVtoPagoSql = $dtVto->format('Y-m-d');
        }
    }

    // Datos de cabecera AFIP
    $afipCuitEmisor = isset($res->FeCabResp->Cuit) ? (string)$res->FeCabResp->Cuit : null;
    $afipFchProceso = isset($res->FeCabResp->FchProceso) ? $res->FeCabResp->FchProceso : null;
    $afipReproceso  = isset($res->FeCabResp->Reproceso) ? $res->FeCabResp->Reproceso : null;

    $afipFchProcSql = null;
    if ($afipFchProceso && preg_match('/^\d{14}$/', $afipFchProceso)) {
        $dtProc = DateTime::createFromFormat('YmdHis', $afipFchProceso);
        if ($dtProc) {
            $afipFchProcSql = $dtProc->format('Y-m-d H:i:s');
        }
    }

    // Serializar request/response para auditoría (opcional)
    $rawRequest  = json_encode($solicitud, JSON_UNESCAPED_UNICODE);
    $rawResponse = json_encode($res, JSON_UNESCAPED_UNICODE);

    try {
        $pdo->beginTransaction();

        // 1) Insert en facturas_afip_info
        $stmtInfo = $pdo->prepare("
            INSERT INTO facturas_afip_info (
                invoice_id, info_id, store_id, customer_id,
                cbte_tipo, cbte_letra, punto_venta, cbte_numero,
                concepto, doc_tipo, doc_nro, condicion_iva_receptor_id,
                fecha_cbte, fch_serv_desde, fch_serv_hasta, fch_vto_pago,
                imp_neto, imp_iva, imp_trib, imp_op_ex, imp_tot_conc, imp_total,
                mon_id, mon_cotiz,
                resultado, cae, cae_vto,
                afip_cuit_emisor, afip_fch_proceso, afip_reproceso,
                raw_request, raw_response
            ) VALUES (
                :invoice_id, :info_id, :store_id, :customer_id,
                :cbte_tipo, :cbte_letra, :punto_venta, :cbte_numero,
                :concepto, :doc_tipo, :doc_nro, :condicion_iva_receptor_id,
                :fecha_cbte, :fch_serv_desde, :fch_serv_hasta, :fch_vto_pago,
                :imp_neto, :imp_iva, :imp_trib, :imp_op_ex, :imp_tot_conc, :imp_total,
                :mon_id, :mon_cotiz,
                :resultado, :cae, :cae_vto,
                :afip_cuit_emisor, :afip_fch_proceso, :afip_reproceso,
                :raw_request, :raw_response
            )
        ");

        $stmtInfo->execute([
            ':invoice_id' => $invoiceId,
            ':info_id'    => $infoId,
            ':store_id'   => $storeId,
            ':customer_id'=> $customerId,

            ':cbte_tipo'  => $cbteTipo,
            ':cbte_letra' => $letra,
            ':punto_venta'=> $puntoVenta,
            ':cbte_numero'=> $cbteNroDesde,

            ':concepto'   => $concepto,
            ':doc_tipo'   => $docTipo,
            ':doc_nro'    => $docNro,
            ':condicion_iva_receptor_id' => $condicionIVAReceptorId,

            ':fecha_cbte'    => $fechaCbteSql ?: date('Y-m-d'),
            ':fch_serv_desde'=> $fchServDesdeSql,
            ':fch_serv_hasta'=> $fchServHastaSql,
            ':fch_vto_pago'  => $fchVtoPagoSql,

            ':imp_neto'   => $impNeto,
            ':imp_iva'    => $impIva,
            ':imp_trib'   => $impTrib,
            ':imp_op_ex'  => $impOpEx,
            ':imp_tot_conc'=> $impTotConc,
            ':imp_total'  => $impTotal,

            ':mon_id'     => 'PES',
            ':mon_cotiz'  => 1.0000,

            ':resultado'  => $resultado,
            ':cae'        => $cae,
            ':cae_vto'    => $caeVtoSql,

            ':afip_cuit_emisor' => $afipCuitEmisor ?: null,
            ':afip_fch_proceso' => $afipFchProcSql,
            ':afip_reproceso'   => $afipReproceso,

            ':raw_request'  => $rawRequest,
            ':raw_response' => $rawResponse,
        ]);

        $facturaAfipId = (int)$pdo->lastInsertId();

        // 2) Insert de ítems
        if ($facturaAfipId > 0 && is_array($itemsPost) && count($itemsPost)) {
            $stmtItem = $pdo->prepare("
                INSERT INTO facturas_afip_items (
                    factura_afip_id, selling_item_id, product_id, descripcion,
                    cantidad, precio_unitario, iva_porcentaje,
                    importe_neto, importe_iva
                ) VALUES (
                    :factura_afip_id, :selling_item_id, :product_id, :descripcion,
                    :cantidad, :precio_unitario, :iva_porcentaje,
                    :importe_neto, :importe_iva
                )
            ");

            foreach ($itemsPost as $it) {
                $cantidad   = isset($it['cantidad']) ? (float)$it['cantidad'] : 0.0;
                $pUnit      = isset($it['precio_unitario']) ? (float)$it['precio_unitario'] : 0.0;
                $ivaPct     = isset($it['iva_porcentaje']) ? (float)$it['iva_porcentaje'] : 0.0;
                $netoLinea  = $cantidad * $pUnit;
                $ivaLinea   = $netoLinea * $ivaPct / 100.0;

                $stmtItem->execute([
                    ':factura_afip_id' => $facturaAfipId,
                    ':selling_item_id' => isset($it['selling_item_id']) ? (int)$it['selling_item_id'] : null,
                    ':product_id'      => isset($it['product_id']) ? (int)$it['product_id'] : null,
                    ':descripcion'     => isset($it['descripcion']) ? $it['descripcion'] : '',
                    ':cantidad'        => $cantidad,
                    ':precio_unitario' => $pUnit,
                    ':iva_porcentaje'  => $ivaPct,
                    ':importe_neto'    => round($netoLinea, 2),
                    ':importe_iva'     => round($ivaLinea, 2),
                ]);
            }
        }

        // 3) Actualizar selling_info
        try {
            $stmtUpd = $pdo->prepare("
                UPDATE selling_info
                SET afip_estado       = 'APROBADA',
                    afip_cbte_tipo    = :cbte_tipo,
                    afip_punto_venta  = :punto_venta,
                    afip_cbte_numero  = :cbte_numero,
                    afip_cae          = :cae,
                    afip_cae_vto      = :cae_vto
                WHERE invoice_id = :invoice_id AND info_id = :info_id
            ");
            $stmtUpd->execute([
                ':cbte_tipo'   => $cbteTipo,
                ':punto_venta' => $puntoVenta,
                ':cbte_numero' => $cbteNroDesde,
                ':cae'         => $cae,
                ':cae_vto'     => $caeVtoSql,
                ':invoice_id'  => $invoiceId,
                ':info_id'     => $infoId,
            ]);
        } catch (Exception $eUpd) {
            // Si falla el UPDATE no rompemos toda la transacción AFIP
            error_log("Aviso: no se pudo actualizar selling_info con datos AFIP: " . $eUpd->getMessage());
        }

        $pdo->commit();

    } catch (Exception $ex) {
        $pdo->rollBack();

        echo "<div class='alert alert-danger'>";
        echo "<strong>Error al guardar la factura AFIP en la base de datos:</strong><br>";
        echo htmlspecialchars($ex->getMessage());
        echo "</div>";
    }
}

// -------------------------------------------------------------
// 8) Mostrar resultado
// -------------------------------------------------------------
?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Resultado AFIP - Proforma <?= htmlspecialchars($invoiceId); ?></title>
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
</head>
<body class="bg-light">
<div class="container py-4">
    <h3 class="mb-3">Resultado de autorización AFIP (WSFE)</h3>

    <div class="card mb-3">
        <div class="card-body">
            <p><strong>Proforma / Invoice ID:</strong> <?= htmlspecialchars($invoiceId); ?></p>
            <p><strong>Punto de venta:</strong> <?= htmlspecialchars($puntoVenta); ?></p>
            <p><strong>Tipo de comprobante (AFIP):</strong> <?= htmlspecialchars($cbteTipo); ?> <?= htmlspecialchars($letra); ?></p>
            <p><strong>Número de comprobante solicitado:</strong> <?= htmlspecialchars($cbteNroDesde ?? ''); ?></p>
            <p><strong>Total:</strong> $ <?= number_format($impTotal, 2, ',', '.'); ?></p>
        </div>
    </div>

    <?php if (!empty($erroresAfip)): ?>
        <div class="alert alert-danger">
            <h5>Errores devueltos por AFIP:</h5>
            <ul class="mb-0">
                <?php foreach ($erroresAfip as $e): ?>
                    <li><?= htmlspecialchars($e); ?></li>
                <?php endforeach; ?>
            </ul>
        </div>
    <?php endif; ?>

    <?php if ($detalleResp): ?>
        <div class="card mb-3">
            <div class="card-header">
                Detalle de respuesta
            </div>
            <div class="card-body">
                <p><strong>Resultado:</strong> <?= htmlspecialchars($resultado ?? ''); ?></p>
                <p><strong>CAE:</strong> <?= htmlspecialchars($cae ?? ''); ?></p>
                <p><strong>Vencimiento CAE:</strong> <?= htmlspecialchars($caeVto ?? ''); ?></p>

                <?php if (!empty($obs)): ?>
                    <h6>Observaciones:</h6>
                    <ul>
                        <?php foreach ($obs as $o): ?>
                            <li><?= htmlspecialchars($o); ?></li>
                        <?php endforeach; ?>
                    </ul>
                <?php endif; ?>

                <details>
                    <summary>Ver objeto completo devuelto por AFIP</summary>
                    <pre><?php print_r($res); ?></pre>
                </details>
            </div>
        </div>
    <?php else: ?>
        <div class="alert alert-warning">
            No se encontró detalle de respuesta FECAEDetResponse en la respuesta de AFIP.
        </div>
        <pre><?php print_r($res); ?></pre>
    <?php endif; ?>

    <a href="facturas_arca_list.php" class="btn btn-secondary">Volver al listado de proformas</a>
</div>
</body>
</html>
