<?php
error_reporting(E_ALL ^ E_NOTICE);

include_once '../conexion.php';
include_once '../clases/TokenValidator.php';
require_once '../tcpdf/tcpdf.php';

$usuarioId = TokenValidator::validar($conn);

$bodyRequest = file_get_contents("php://input");
$datos = json_decode($bodyRequest, true);

if (json_last_error() !== JSON_ERROR_NONE) {
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode(["estado" => 0, "mensaje" => "JSON inválido: " . json_last_error_msg()], JSON_UNESCAPED_UNICODE);
    exit;
}

$ventaId = $datos[0] ?? 0;
$cab = $datos[1] ?? [];

function txt($v) {
    return trim((string)($v ?? ''));
}

function num2($v) {
    $v = str_replace([',', 'S/.', 'S/', '$', ' '], '', (string)($v ?? '0'));
    if ($v === '') $v = '0';
    return number_format((float)$v, 2, '.', '');
}

function num3($v) {
    $v = str_replace([',', 'KG', 'kg', 'Kg', ' '], '', (string)($v ?? '0'));
    if ($v === '') $v = '0';
    return number_format((float)$v, 3, '.', '');
}

function cantidadTicket($v) {
    $n = (float)($v ?? 0);
    if (floor($n) == $n) return number_format($n, 0, '.', '');
    return rtrim(rtrim(number_format($n, 3, '.', ''), '0'), '.');
}

function prepararLogoTemporal($valor) {
    $valor = trim((string)($valor ?? ''));
    if ($valor === '') return ["path" => "", "temporal" => false];

    if (is_file($valor)) return ["path" => $valor, "temporal" => false];

    $binario = false;
    $mime = "";

    if (preg_match('#^data:(image/(?:png|jpeg|jpg|webp));base64,(.+)$#is', $valor, $m)) {
        $mime = strtolower($m[1]);
        $binario = base64_decode(preg_replace('/\s+/', '', $m[2]), true);
    } elseif (filter_var($valor, FILTER_VALIDATE_URL)) {
        $contexto = stream_context_create(["http" => ["timeout" => 10], "https" => ["timeout" => 10]]);
        $binario = @file_get_contents($valor, false, $contexto);
    } else {
        $limpio = preg_replace('/\s+/', '', $valor);
        if ($limpio !== '' && preg_match('/^[A-Za-z0-9+\/]+=*$/', $limpio)) {
            $binario = base64_decode($limpio, true);
        }
    }

    if ($binario === false || $binario === '') return ["path" => "", "temporal" => false];

    $info = @getimagesizefromstring($binario);
    if ($info === false) return ["path" => "", "temporal" => false];

    if ($mime === "") $mime = strtolower((string)($info["mime"] ?? ""));
    $ext = in_array($mime, ["image/jpeg", "image/jpg"], true) ? "jpg" : ($mime === "image/webp" ? "webp" : "png");
    $ruta = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . "sicse_logo_" . bin2hex(random_bytes(8)) . "." . $ext;

    if (@file_put_contents($ruta, $binario) === false) return ["path" => "", "temporal" => false];

    return ["path" => $ruta, "temporal" => true];
}

function dibujarLogo($pdf, $ruta, $x, $y, $maxW, $maxH) {
    if ($ruta === "" || !is_file($ruta)) return;
    $tam = @getimagesize($ruta);
    if ($tam === false || empty($tam[0]) || empty($tam[1])) return;

    $escala = min($maxW / $tam[0], $maxH / $tam[1]);
    $w = $tam[0] * $escala;
    $h = $tam[1] * $escala;
    $pdf->Image($ruta, $x + (($maxW - $w) / 2), $y + (($maxH - $h) / 2), $w, $h, '', '', '', true, 300);
}

function borrarLogoTemporal($logoInfo) {
    if (!empty($logoInfo["temporal"]) && !empty($logoInfo["path"]) && is_file($logoInfo["path"])) {
        @unlink($logoInfo["path"]);
    }
}

/**
 * Busca un logo permanente en api_comercial/logos/.
 * El archivo principal debe llamarse con el RUC, por ejemplo:
 * api_comercial/logos/20606650583.png
 */
function buscarLogoPermanente($rucEmpresa) {
    $ruc = preg_replace('/\D+/', '', (string)$rucEmpresa);
    $carpetaLogos = realpath(__DIR__ . '/../logos');

    if ($carpetaLogos === false || !is_dir($carpetaLogos)) {
        return ["path" => "", "temporal" => false];
    }

    $candidatos = [];

    if ($ruc !== '') {
        $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . $ruc . '.png';
        $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . $ruc . '.jpg';
        $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . $ruc . '.jpeg';
    }

    $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . 'logo.png';
    $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . 'logo.jpg';
    $candidatos[] = $carpetaLogos . DIRECTORY_SEPARATOR . 'logo.jpeg';

    foreach ($candidatos as $ruta) {
        if (is_file($ruta) && is_readable($ruta)) {
            return ["path" => $ruta, "temporal" => false];
        }
    }

    return ["path" => "", "temporal" => false];
}

/**
 * Calcula el peso total del documento.
 *
 * En SICSE el campo "peso" del detalle corresponde al peso unitario
 * del producto, por eso el total se obtiene multiplicando:
 * cantidad x peso.
 *
 * Si el formulario envía peso_total se respeta ese valor cuando sea > 0.
 */
function calcularPesoTotal($detalle, $cab) {
    $pesoCab = (float)($cab["peso_total"] ?? 0);

    if ($pesoCab > 0) {
        return $pesoCab;
    }

    $total = 0.0;

    foreach ($detalle as $it) {
        $cantidad = (float)($it["cantidad"] ?? 0);
        $peso = (float)($it["peso"] ?? 0);
        $total += ($cantidad * $peso);
    }

    return $total;
}

/**
 * Devuelve la altura real aproximada que ocupará un MultiCell,
 * usando las mismas fuentes y anchos que el ticket.
 */
function altoTexto($pdf, $texto, $ancho, $tamFuente, $altoMinimo, $estilo = 'B') {
    $pdf->SetFont('dejavusanscondensed', $estilo, $tamFuente);
    $alto = $pdf->getStringHeight($ancho, txt($texto), false, true, '', 0);
    return max((float)$altoMinimo, (float)$alto);
}

/**
 * Calcula el alto del papel según el contenido real del documento.
 * Ya no existe una cantidad fija de 15 ítems ni un ticket fijo de 360 mm.
 *
 * Se deja un pequeño margen de seguridad al final para evitar cortes por
 * diferencias de renderizado entre versiones de TCPDF.
 */
function calcularAltoTicket($detalle, $cab, $logoPath) {
    $medidor = new TCPDF('P', 'mm', [80, 1000], true, 'UTF-8', false);
    $medidor->setPageUnit('mm');
    $medidor->SetMargins(1.5, 3, 1.5);
    $medidor->SetAutoPageBreak(false, 3);
    $medidor->SetCellPadding(0);
    $medidor->setPrintHeader(false);
    $medidor->setPrintFooter(false);

    $alto = 3.0; // margen superior

    if ($logoPath !== "") {
        $alto += 16.0;
    }

    // Cabecera de empresa
    $alto += altoTexto($medidor, $cab["razon_social_empresa"] ?? "", 77, 10.2, 4.2, 'B');
    $alto += 4.0; // RUC
    $alto += 0.6;
    $alto += altoTexto($medidor, $cab["rubro"] ?? "", 77, 8.2, 3.7, 'B');
    $alto += altoTexto($medidor, $cab["direccion_empresa"] ?? "", 77, 8.2, 3.7, 'B');

    if (!empty($cab["telefono"]) || !empty($cab["correo"])) {
        $alto += altoTexto(
            $medidor,
            txt($cab["telefono"] ?? "") . " " . txt($cab["correo"] ?? ""),
            77,
            7.2,
            3.2,
            'B'
        );
    }

    $alto += 1.2;
    $alto += 5.0; // tipo documento
    $alto += 5.0; // número
    $alto += 1.8; // separación + línea

    // Datos del cliente
    $alto += 3.8; // fecha/hora

    if (!empty($cab["fecha_vencimiento"])) {
        $alto += 3.8;
    }

    $alto += altoTexto($medidor, $cab["cliente"] ?? "", 52, 8.4, 3.8, 'B');
    $alto += 3.8; // RUC/DNI
    $alto += altoTexto($medidor, $cab["direccion_cliente"] ?? "", 52, 8.4, 3.8, 'B');
    $alto += 3.8; // condición

    if (!empty($cab["guia_remision"])) {
        $alto += 3.8;
    }

    $alto += 2.0; // línea y separación
    $alto += 4.2 + 1.2; // encabezado detalle

    // Detalle: cada fila crece según la longitud de la descripción.
    foreach ($detalle as $it) {
        $desc = txt($it["nomproducto"] ?? "");
        $altoDescripcion = altoTexto($medidor, $desc, 42, 9.0, 4.8, 'B');
        $altoFila = max(10.0, $altoDescripcion);
        $alto += $altoFila + 1.2;
    }

    // Separación antes de totales
    $alto += 2.2;

    // Totales: 7 líneas de 4 mm + TOTAL A PAGAR de 5 mm
    $alto += (7 * 4.0) + 5.0 + 1.5;

    // SON + condición + vendedor
    $alto += altoTexto($medidor, "SON: " . txt($cab["total_letras"] ?? ""), 77, 8.6, 4.0, 'B');
    $alto += 3.8 + 3.8;

    // Peso total
    $pesoTotal = calcularPesoTotal($detalle, $cab);
    if ($pesoTotal > 0) {
        $alto += 4.0;
    }

    if (!empty($cab["cuotas_credito"])) {
        $alto += 0.8;
        $alto += altoTexto(
            $medidor,
            "CUOTAS:\n" . txt($cab["cuotas_credito"]),
            77,
            7.8,
            3.6,
            'B'
        );
    }

    $hash = txt($cab["hash"] ?? "");
    if ($hash !== "" && stripos($hash, "jLabel") !== 0) {
        $alto += altoTexto($medidor, "Hash: " . $hash, 77, 6.8, 3.2, 'B');
    }

    $qr = txt($cab["qr"] ?? "");
    $tipoDoc = strtoupper(txt($cab["tipo_documento"] ?? ""));

    if ($qr !== "" && ($tipoDoc === "FACTURA ELECTRONICA" || $tipoDoc === "BOLETA ELECTRONICA")) {
        $alto += 20.5;
    } else {
        $alto += 1.7;
    }

    $observaciones = txt($cab["observaciones"] ?? "");
    if ($observaciones !== "") {
        $alto += 1.2;
        $alto += 3.8; // título
        $alto += altoTexto($medidor, $observaciones, 77, 8.0, 3.8, '');
        $alto += 1.2;
    }

    $alto += 4.2; // gracias
    $alto += 0.8;
    $alto += 3.3 + 3.3; // Amazonía

    // Margen inferior + colchón de seguridad.
    $alto += 10.0;

    // Un ticket demasiado pequeño también puede ser rechazado por algunos visores.
    $alto = max(120.0, ceil($alto));

    // Límite amplio para documentos excepcionalmente extensos.
    return min($alto, 5000.0);
}

try {
    $stmt = $conn->prepare("SELECT obtener_detalle_venta(:venta_id) AS resultado");
    $stmt->bindParam(":venta_id", $ventaId, PDO::PARAM_INT);
    $stmt->execute();

    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$row || empty($row["resultado"])) {
        header("Content-Type: application/json; charset=utf-8");
        echo json_encode(["estado" => 0, "mensaje" => "No se encontró detalle de venta."], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $data = json_decode($row["resultado"], true);
    $detalle = $data["detventas"] ?? [];

    if (empty($detalle)) {
        header("Content-Type: application/json; charset=utf-8");
        echo json_encode(["estado" => 0, "mensaje" => "El documento no tiene detalle."], JSON_UNESCAPED_UNICODE);
        exit;
    }

    $incluyeIgv = $cab["incluye_igv"] ?? "1";
    $moneda = txt($cab["simbolo_moneda"] ?? "S/.");

    $valorLogo = $cab["logo_base64"] ?? $cab["logo"] ?? $cab["logo_empresa"] ?? $cab["Logo"] ?? "";
    $logoInfo = prepararLogoTemporal($valorLogo);

    if ($logoInfo["path"] === "") {
        $logoInfo = buscarLogoPermanente($cab["ruc_empresa"] ?? "");
    }

    // ==========================================================
    // PAPEL DINÁMICO
    // Ya no se divide por 15 ítems ni se usa un alto fijo de 360.
    // El ticket se genera en una sola página continua de 80 mm.
    // ==========================================================
    $altoTicket = calcularAltoTicket($detalle, $cab, $logoInfo["path"]);

    $pdf = new TCPDF('P', 'mm', [80, $altoTicket], true, 'UTF-8', false);
    $pdf->setPageUnit('mm');
    $pdf->SetMargins(1.5, 3, 1.5);
    $pdf->SetAutoPageBreak(false, 3);
    $pdf->SetCellPadding(0);
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);
    $pdf->AddPage();

    if ($logoInfo["path"] !== "") {
        $yLogo = $pdf->GetY();
        dibujarLogo($pdf, $logoInfo["path"], 24, $yLogo, 32, 15);
        $pdf->SetY($yLogo + 16);
    }

    // CABECERA
    $pdf->SetFont('dejavusanscondensed', 'B', 10.2);
    $pdf->MultiCell(0, 4.2, txt($cab["razon_social_empresa"] ?? ""), 0, 'C');

    $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
    $pdf->Cell(0, 4, "RUC : " . txt($cab["ruc_empresa"] ?? ""), 0, 1, 'C');

    $pdf->Ln(0.6);

    $pdf->SetFont('dejavusanscondensed', 'B', 8.2);
    $pdf->MultiCell(0, 3.7, txt($cab["rubro"] ?? ""), 0, 'C');
    $pdf->MultiCell(0, 3.7, txt($cab["direccion_empresa"] ?? ""), 0, 'C');

    if (!empty($cab["telefono"]) || !empty($cab["correo"])) {
        $pdf->SetFont('dejavusanscondensed', 'B', 7.2);
        $pdf->MultiCell(0, 3.2, txt($cab["telefono"] ?? "") . " " . txt($cab["correo"] ?? ""), 0, 'C');
    }

    $pdf->Ln(1.2);

    $pdf->SetFont('dejavusanscondensed', 'B', 11.2);
    $pdf->Cell(0, 5, txt($cab["tipo_documento"] ?? "DOCUMENTO"), 0, 1, 'C');

    $pdf->SetFont('dejavusanscondensed', 'B', 10.2);
    $pdf->Cell(0, 5, txt($cab["numero_comprobante"] ?? ""), 0, 1, 'C');

    $pdf->Ln(0.8);

    // CLIENTE
    $pdf->Line(1.5, $pdf->GetY(), 78.5, $pdf->GetY());
    $pdf->Ln(1);

    $pdf->SetFont('dejavusanscondensed', 'B', 8.4);
    $pdf->Cell(25, 3.8, "FECHA:", 0, 0, 'L');
    $pdf->Cell(25, 3.8, txt($cab["fecha_emision"] ?? ""), 0, 0, 'L');
    $pdf->Cell(12, 3.8, "HORA:", 0, 0, 'L');
    $pdf->Cell(15, 3.8, txt($cab["hora_emision"] ?? ""), 0, 1, 'L');

    if (!empty($cab["fecha_vencimiento"])) {
        $pdf->Cell(25, 3.8, "F. VCTO:", 0, 0, 'L');
        $pdf->Cell(52, 3.8, txt($cab["fecha_vencimiento"]), 0, 1, 'L');
    }

    $pdf->Cell(25, 3.8, "CLIENTE:", 0, 0, 'L');
    $pdf->MultiCell(52, 3.8, txt($cab["cliente"] ?? ""), 0, 'L');

    $pdf->Cell(25, 3.8, "RUC/DNI:", 0, 0, 'L');
    $pdf->Cell(52, 3.8, txt($cab["ruc_cliente"] ?? ""), 0, 1, 'L');

    $pdf->Cell(25, 3.8, "DIRECCION:", 0, 0, 'L');
    $pdf->MultiCell(52, 3.8, txt($cab["direccion_cliente"] ?? ""), 0, 'L');

    $pdf->Cell(25, 3.8, "CONDICION:", 0, 0, 'L');
    $pdf->Cell(52, 3.8, txt($cab["condicion_pago"] ?? ""), 0, 1, 'L');

    if (!empty($cab["guia_remision"])) {
        $pdf->Cell(25, 3.8, "GUIA REM.:", 0, 0, 'L');
        $pdf->Cell(52, 3.8, txt($cab["guia_remision"]), 0, 1, 'L');
    }

    $pdf->Ln(1);
    $pdf->Line(1.5, $pdf->GetY(), 78.5, $pdf->GetY());
    $pdf->Ln(1);

    // CABECERA DETALLE
    $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
    $pdf->Cell(12, 4.2, "CANT.", 0, 0, 'C');
    $pdf->Cell(43, 4.2, "DESCRIPCION", 0, 0, 'L');
    $pdf->Cell(10, 4.2, "P.UNIT", 0, 0, 'R');
    $pdf->Cell(12, 4.2, "TOTAL", 0, 1, 'R');

    $pdf->Line(1.5, $pdf->GetY(), 78.5, $pdf->GetY());
    $pdf->Ln(1.2);

    // DETALLE COMPLETO: sin límite de 15 ítems.
    foreach ($detalle as $it) {
        $cantidad = cantidadTicket($it["cantidad"] ?? 0);
        $unidad = txt($it["descrip_precio"] ?? "");
        $desc = txt($it["nomproducto"] ?? "");

        $precio = ($incluyeIgv == "1" || $incluyeIgv === true || $incluyeIgv == "true")
            ? ($it["precioigv"] ?? 0)
            : ($it["precio"] ?? 0);

        $total = ($incluyeIgv == "1" || $incluyeIgv === true || $incluyeIgv == "true")
            ? ($it["subtotaligv"] ?? 0)
            : ($it["subtotal"] ?? 0);

        $yIni = $pdf->GetY();
        $xIni = $pdf->GetX();

        $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
        $pdf->MultiCell(12, 5.0, $cantidad . "\n" . $unidad, 0, 'C', false, 0, $xIni, $yIni);

        $xDesc = $xIni + 13;
        $pdf->SetXY($xDesc, $yIni);
        $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
        $pdf->MultiCell(42, 4.8, $desc, 0, 'L');

        $altoDesc = $pdf->GetY() - $yIni;

        $pdf->SetXY($xIni + 55, $yIni);
        $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
        $pdf->Cell(10, 4.8, num2($precio), 0, 0, 'R');
        $pdf->Cell(12, 4.8, num2($total), 0, 1, 'R');

        $alto = max($altoDesc, 10);
        $pdf->SetY($yIni + $alto + 1.2);
    }

    // TOTALES: empiezan inmediatamente después del último producto.
    $pdf->Ln(1);
    $pdf->Line(1.5, $pdf->GetY(), 78.5, $pdf->GetY());
    $pdf->Ln(1.2);

    $totalDocumento = num2($cab["total_pagar"] ?? $cab["total_a_pagar"] ?? $cab["total"] ?? 0);

    $pdf->SetFont('dejavusanscondensed', 'B', 9.0);

    $pdf->Cell(48, 4.0, "OP. GRAVADA:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["sub_total"] ?? 0), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "EXONERADA:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["exonerada"] ?? 0), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "DESCUENTO:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["descuento"] ?? 0), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "ICBPER:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["icbper"] ?? 0), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "IGV:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["igv"] ?? 0), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "TOTAL:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["total"] ?? $totalDocumento), 0, 1, 'R');

    $pdf->Cell(48, 4.0, "A CUENTA:", 0, 0, 'R');
    $pdf->Cell(29, 4.0, $moneda . " " . num2($cab["acuenta"] ?? 0), 0, 1, 'R');

    $pdf->SetFont('dejavusanscondensed', 'B', 10.8);
    $pdf->Cell(48, 5.0, "TOTAL A PAGAR:", 0, 0, 'R');
    $pdf->Cell(29, 5.0, $moneda . " " . $totalDocumento, 0, 1, 'R');

    $pdf->Ln(1.5);

    // PIE
    $pdf->SetFont('dejavusanscondensed', 'B', 8.6);
    $pdf->MultiCell(0, 4.0, "SON: " . txt($cab["total_letras"] ?? ""), 0, 'L');

    $pdf->SetFont('dejavusanscondensed', 'B', 8.4);
    $pdf->Cell(0, 3.8, "CONDICION: " . txt($cab["condicion_pago"] ?? ""), 0, 1, 'L');
    $pdf->Cell(0, 3.8, "VENDEDOR: " . txt($cab["vendedor"] ?? ""), 0, 1, 'L');

    // PESO TOTAL
    $pesoTotal = calcularPesoTotal($detalle, $cab);
    if ($pesoTotal > 0) {
        $pdf->SetFont('dejavusanscondensed', 'B', 8.4);
        $pdf->Cell(0, 4.0, "PESO TOTAL: " . num3($pesoTotal) . " KG", 0, 1, 'L');
    }

    if (!empty($cab["cuotas_credito"])) {
        $pdf->Ln(0.8);
        $pdf->SetFont('dejavusanscondensed', 'B', 7.8);
        $pdf->MultiCell(0, 3.6, "CUOTAS:\n" . txt($cab["cuotas_credito"]), 0, 'L');
    }

    $hash = txt($cab["hash"] ?? "");
    if ($hash !== "" && stripos($hash, "jLabel") !== 0) {
        $pdf->SetFont('dejavusanscondensed', 'B', 6.8);
        $pdf->MultiCell(0, 3.2, "Hash: " . $hash, 0, 'L');
    }

    $qr = txt($cab["qr"] ?? "");
    $tipoDoc = strtoupper(txt($cab["tipo_documento"] ?? ""));

    if (!empty($qr) && ($tipoDoc == "FACTURA ELECTRONICA" || $tipoDoc == "BOLETA ELECTRONICA")) {
        $pdf->Ln(1.2);
        $xQr = 31;
        $yQr = $pdf->GetY();

        $pdf->write2DBarcode($qr, 'QRCODE,L', $xQr, $yQr, 18, 18, [], 'N');
        $pdf->SetY($yQr + 19);
    } else {
        $pdf->Ln(1.2);
    }

    $pdf->Ln(0.5);

    /* =====================================================
       OBSERVACIONES
       ===================================================== */
    $observaciones = txt($cab["observaciones"] ?? "");

    if ($observaciones !== "") {
        $pdf->Ln(1.2);

        $pdf->SetFont('dejavusanscondensed', 'B', 8.0);
        $pdf->MultiCell(0, 3.8, "OBSERVACIONES:", 0, 'L');

        $pdf->SetFont('dejavusanscondensed', '', 8.0);
        $pdf->MultiCell(0, 3.8, $observaciones, 0, 'L');

        $pdf->Ln(1.2);
    }

    $pdf->SetFont('dejavusanscondensed', 'B', 9.0);
    $pdf->Cell(0, 4.2, "¡ GRACIAS POR SU PREFERENCIA !", 0, 1, 'C');

    $pdf->Ln(0.8);

    $pdf->SetFont('dejavusanscondensed', 'B', 7.0);
    $pdf->Cell(0, 3.3, "BIENES Y SERVICIOS TRANSFERIDOS EN LA AMAZONIA", 0, 1, 'C');
    $pdf->Cell(0, 3.3, "REGION SELVA PARA SER CONSUMIDOS EN LA MISMA", 0, 1, 'C');

    $carpeta = __DIR__ . "/../pdf_temp/";

    if (!file_exists($carpeta)) {
        mkdir($carpeta, 0777, true);
    }

    $nombrePdf = "ticket_" . $ventaId . "_" . time() . ".pdf";
    $rutaFisica = $carpeta . $nombrePdf;

    $pdf->Output($rutaFisica, "F");
    borrarLogoTemporal($logoInfo);

    $urlPdf = "http://ferretbarboza.sicsemkj.com/api_comercial/pdf_temp/" . $nombrePdf;

    header("Content-Type: application/json; charset=utf-8");
    echo json_encode([
        "estado" => 1,
        "url" => $urlPdf,
        "alto_mm" => $altoTicket,
        "peso_total" => num3($pesoTotal)
    ], JSON_UNESCAPED_UNICODE);
    exit;

} catch (Throwable $e) {
    if (isset($logoInfo)) borrarLogoTemporal($logoInfo);
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode([
        "estado" => 0,
        "mensaje" => "Error al generar PDF: " . $e->getMessage()
    ], JSON_UNESCAPED_UNICODE);
    exit;
}