<?php
session_start();
require_once 'db/config.php';
require_once 'includes/callcenter_test_helpers.php';
require_once 'includes/contraentrega_cobertura.php';

header('Content-Type: application/json; charset=utf-8');

if (!isset($_SESSION['user_id']) || !cc_test_current_user_can_access_module(db())) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'No autorizado']);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Método no permitido']);
    exit;
}

function cc_test_normalize_nullable_text(string $key, int $maxLen = 3000): ?string
{
    $value = trim((string) ($_POST[$key] ?? ''));
    if ($value === '') {
        return null;
    }

    if (mb_strlen($value) > $maxLen) {
        throw new RuntimeException('El campo ' . $key . ' es demasiado largo.');
    }

    return $value;
}

function cc_test_normalize_optional_image_upload(string $key): ?array
{
    if (!isset($_FILES[$key]) || !is_array($_FILES[$key])) {
        return null;
    }

    $file = $_FILES[$key];
    $error = (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE);
    if ($error === UPLOAD_ERR_NO_FILE) {
        return null;
    }

    if ($error !== UPLOAD_ERR_OK) {
        throw new RuntimeException('No se pudo subir la imagen de sustento.');
    }

    $tmpName = (string) ($file['tmp_name'] ?? '');
    if ($tmpName === '' || !is_uploaded_file($tmpName)) {
        throw new RuntimeException('La imagen de sustento no es válida.');
    }

    $size = (int) ($file['size'] ?? 0);
    if ($size <= 0) {
        throw new RuntimeException('La imagen de sustento está vacía.');
    }

    if ($size > 8 * 1024 * 1024) {
        throw new RuntimeException('La imagen de sustento no puede pesar más de 8 MB.');
    }

    return $file;
}

function cc_test_store_tracking_evidence_image(array $file, string $prefix, string $sourceKey, int $userId): array
{
    $tmpName = (string) ($file['tmp_name'] ?? '');
    $imgInfo = @getimagesize($tmpName);
    if ($imgInfo === false || empty($imgInfo['mime'])) {
        throw new RuntimeException('El archivo no parece ser una imagen válida.');
    }

    $mime = (string) $imgInfo['mime'];
    $allowed = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
    ];

    if (!isset($allowed[$mime])) {
        throw new RuntimeException('Formato no permitido. Use JPG, PNG o WEBP.');
    }

    $uploadDir = __DIR__ . '/assets/uploads/callcenter_tracking';
    if (!is_dir($uploadDir) && !mkdir($uploadDir, 0775, true) && !is_dir($uploadDir)) {
        throw new RuntimeException('No se pudo preparar la carpeta de imágenes.');
    }

    $filename = sprintf(
        '%s_%s_%d_%d_%s.%s',
        $prefix,
        substr($sourceKey, 0, 12),
        max(0, $userId),
        time(),
        bin2hex(random_bytes(4)),
        $allowed[$mime]
    );

    $targetPath = $uploadDir . '/' . $filename;
    if (!move_uploaded_file($tmpName, $targetPath)) {
        throw new RuntimeException('No se pudo guardar la imagen en el servidor.');
    }

    return [
        'absolute_path' => $targetPath,
        'relative_path' => 'assets/uploads/callcenter_tracking/' . $filename,
    ];
}

function cc_test_fetch_source_order(PDO $pdo, string $sourceKey): ?array
{
    $stmt = $pdo->prepare(
        'SELECT
            source_key,
            store_key,
            codigo,
            import_id,
            drive_imported_at,
            first_seen_at,
            nombre,
            celular,
            producto,
            cantidad,
            precio,
            coordenadas,
            direccion_drive,
            referencia_drive,
            sede_drive,
            ciudad_drive,
            distrito_drive,
            dni_drive,
            observaciones_drive
        FROM callcenter_test_orders
        WHERE source_key = ?
        LIMIT 1'
    );
    $stmt->execute([$sourceKey]);

    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return $row ?: null;
}

function cc_test_build_contraentrega_notes(array $parts): string
{
    $cleanParts = [];
    foreach ($parts as $part) {
        $part = trim((string) $part);
        if ($part !== '') {
            $cleanParts[] = $part;
        }
    }

    return implode("\n\n", $cleanParts);
}

function cc_test_prepare_route_order_payload(array $sourceOrder, array $formData, int $fallbackUserId): array
{
    if (($sourceOrder['store_key'] ?? '') !== 'otra_tienda') {
        throw new RuntimeException('En este primer paso la subida automática a ruta está activa solo para TUANI.');
    }

    $nombreCompleto = trim((string) ($sourceOrder['nombre'] ?? ''));
    $celular = trim((string) ($sourceOrder['celular'] ?? ''));
    $direccion = trim((string) ($formData['direccion'] ?? ''));
    $referencia = trim((string) ($formData['referencia'] ?? ''));
    $departamento = trim((string) ($formData['sede'] ?? ''));
    $provincia = trim((string) ($formData['ciudad'] ?? ''));
    $distrito = trim((string) ($formData['distrito'] ?? ''));
    $dni = trim((string) (($formData['dni'] ?? '') !== '' ? ($formData['dni'] ?? '') : ($sourceOrder['dni_drive'] ?? '')));
    $observacionesPedido = trim((string) (($formData['observaciones'] ?? '') !== '' ? ($formData['observaciones'] ?? '') : ($sourceOrder['observaciones_drive'] ?? '')));
    $notaSeguimiento = trim((string) ($formData['nota_seguimiento'] ?? ''));
    $fechaEntrega = $formData['fecha_entrega_programada'] ?? null;
    $coordenadasRaw = trim((string) ($formData['coordenadas'] ?? ''));

    if ($nombreCompleto === '' || $celular === '') {
        throw new RuntimeException('El pedido no tiene nombre o celular suficientes para enviarlo a Ruta Contraentrega.');
    }

    if ($fechaEntrega === null || $fechaEntrega === '') {
        throw new RuntimeException('Debes seleccionar la fecha de entrega antes de subir el pedido.');
    }

    if ($direccion === '' || $departamento === '' || $provincia === '' || $distrito === '') {
        throw new RuntimeException('Para subir el pedido completa dirección, departamento, provincia y distrito.');
    }

    $departamentos = contraentregaProvinciasPorDepartamento();
    $distritosPorProvincia = contraentregaDistritosPorProvincia();

    if (!array_key_exists($departamento, $departamentos)) {
        throw new RuntimeException('Selecciona un departamento válido para Ruta Contraentrega.');
    }

    $provinciasPermitidas = $departamentos[$departamento] ?? [];
    if ($provincia === '' || !in_array($provincia, $provinciasPermitidas, true)) {
        throw new RuntimeException('Selecciona una provincia válida para el departamento elegido.');
    }

    $distritosPermitidos = $distritosPorProvincia[$provincia] ?? null;
    if (is_array($distritosPermitidos) && !empty($distritosPermitidos) && !in_array($distrito, $distritosPermitidos, true)) {
        throw new RuntimeException('Selecciona un distrito válido para la provincia elegida.');
    }

    $coordenadas = cc_test_normalize_contraentrega_coordinates($coordenadasRaw);
    if ($coordenadas === null) {
        throw new RuntimeException('Ingresa coordenadas válidas con el formato -12.082029, -77.069024.');
    }

    $productoBase = trim((string) ($formData['producto'] ?? ''));
    if ($productoBase === '') {
        $productoBase = trim((string) ($sourceOrder['producto'] ?? ''));
    }
    $cantidadBase = trim((string) ($formData['cantidad'] ?? ''));
    if ($cantidadBase === '') {
        $cantidadBase = trim((string) ($sourceOrder['cantidad'] ?? ''));
    }
    $precioBase = trim((string) ($formData['precio'] ?? ''));
    if ($precioBase === '') {
        $precioBase = trim((string) ($sourceOrder['precio'] ?? ''));
    }

    $productoPrincipal = trim((string) ($formData['confirmacion_producto'] ?? ''));
    if ($productoPrincipal === '') {
        $productoPrincipal = $productoBase;
    }

    $cantidadPrincipalRaw = trim((string) ($formData['confirmacion_cantidad'] ?? ''));
    if ($cantidadPrincipalRaw === '') {
        $cantidadPrincipalRaw = $cantidadBase;
    }

    $precioPrincipalRaw = trim((string) ($formData['confirmacion_precio'] ?? ''));
    if ($precioPrincipalRaw === '') {
        $precioPrincipalRaw = $precioBase;
    }

    if ($productoPrincipal === '') {
        throw new RuntimeException('El pedido no tiene producto principal para subir a Ruta Contraentrega.');
    }

    $cantidadPrincipal = cc_test_parse_quantity($cantidadPrincipalRaw);
    if ($cantidadPrincipal === null) {
        throw new RuntimeException('La cantidad principal del pedido no es válida.');
    }

    $precioPrincipal = cc_test_parse_amount($precioPrincipalRaw);
    if ($precioPrincipal === null) {
        throw new RuntimeException('El precio principal del pedido no es válido.');
    }

    $productoExtra = trim((string) ($formData['confirmacion_producto_extra'] ?? ''));
    $cantidadExtraRaw = trim((string) ($formData['confirmacion_cantidad_extra'] ?? ''));
    $precioExtraRaw = trim((string) ($formData['confirmacion_precio_extra'] ?? ''));
    $hayExtra = $productoExtra !== '' || $cantidadExtraRaw !== '' || $precioExtraRaw !== '';

    $productos = [$productoPrincipal];
    $detalleProductos = [$productoPrincipal . ' (x' . $cantidadPrincipal . ')'];
    $cantidadTotal = $cantidadPrincipal;
    $montoTotal = $precioPrincipal;

    if ($hayExtra) {
        if ($productoExtra === '' || $cantidadExtraRaw === '' || $precioExtraRaw === '') {
            throw new RuntimeException('Si usas producto adicional, completa producto, cantidad y precio adicional.');
        }

        $cantidadExtra = cc_test_parse_quantity($cantidadExtraRaw);
        if ($cantidadExtra === null) {
            throw new RuntimeException('La cantidad del producto adicional no es válida.');
        }

        $precioExtra = cc_test_parse_amount($precioExtraRaw);
        if ($precioExtra === null) {
            throw new RuntimeException('El precio del producto adicional no es válido.');
        }

        $productos[] = $productoExtra;
        $detalleProductos[] = $productoExtra . ' (x' . $cantidadExtra . ')';
        $cantidadTotal += $cantidadExtra;
        $montoTotal += $precioExtra;
    }

    $identificadorPedido = trim((string) ($sourceOrder['codigo'] ?? ''));
    if ($identificadorPedido === '') {
        $identificadorPedido = trim((string) ($sourceOrder['import_id'] ?? ''));
    }
    if ($identificadorPedido === '') {
        $identificadorPedido = 'source:' . substr((string) ($sourceOrder['source_key'] ?? ''), 0, 12);
    }

    $notas = cc_test_build_contraentrega_notes([
        'Origen: Call Center TUANI',
        'Pedido base: ' . $identificadorPedido,
        'Detalle confirmado: ' . implode(', ', $detalleProductos),
        $observacionesPedido !== '' ? 'Observaciones del pedido: ' . $observacionesPedido : '',
        $notaSeguimiento !== '' ? 'Nota interna Call Center: ' . $notaSeguimiento : '',
    ]);

    $seguimiento = 'Subido desde Call Center TUANI';
    $codigoTracking = trim((string) ($sourceOrder['codigo'] ?? ''));

    return [
        'source_key' => (string) ($sourceOrder['source_key'] ?? ''),
        'dni_cliente' => $dni,
        'nombre_completo' => $nombreCompleto,
        'celular' => $celular,
        'agencia' => 'CONTRAENTREGA',
        'sede_envio' => $departamento,
        'codigo_rastreo' => trim($provincia . ' / ' . $distrito, ' /'),
        'codigo_tracking' => $codigoTracking !== '' ? $codigoTracking : null,
        'direccion_exacta' => $direccion,
        'referencia_domicilio' => $referencia !== '' ? $referencia : null,
        'coordenadas' => $coordenadas,
        'producto' => implode(', ', $productos),
        'cantidad' => $cantidadTotal,
        'monto_total' => round($montoTotal, 2),
        'asesor_id' => $fallbackUserId > 0 ? $fallbackUserId : null,
        'notas' => $notas,
        'nota_adicional' => $notaSeguimiento !== '' ? $notaSeguimiento : null,
        'observacion' => $observacionesPedido !== '' ? $observacionesPedido : null,
        'descargo' => $observacionesPedido !== '' ? $observacionesPedido : null,
        'seguimiento' => $seguimiento,
        'fecha_entrega' => $fechaEntrega,
        'tipo_paquete' => 'CONTRAENTREGA',
        'estado' => 'RUTA_CONTRAENTREGA',
    ];
}

function cc_test_sync_route_order(PDO $pdo, ?int $existingPedidoId, array $payload): array
{
    $existing = null;
    if ($existingPedidoId !== null && $existingPedidoId > 0) {
        $stmtExisting = $pdo->prepare('SELECT * FROM pedidos WHERE id = ? LIMIT 1');
        $stmtExisting->execute([$existingPedidoId]);
        $existing = $stmtExisting->fetch(PDO::FETCH_ASSOC) ?: null;
    }

    if ($existing) {
        $montoAdelantado = round((float) ($existing['monto_adelantado'] ?? 0), 2);
        $montoDebe = round(max(0, $payload['monto_total'] - $montoAdelantado), 2);

        $stmtUpdate = $pdo->prepare(
            'UPDATE pedidos SET
                dni_cliente = :dni_cliente,
                nombre_completo = :nombre_completo,
                celular = :celular,
                agencia = :agencia,
                sede_envio = :sede_envio,
                codigo_rastreo = :codigo_rastreo,
                codigo_tracking = COALESCE(NULLIF(:codigo_tracking, \'\'), codigo_tracking),
                referencia_domicilio = :referencia_domicilio,
                direccion_exacta = :direccion_exacta,
                coordenadas = :coordenadas,
                producto = :producto,
                cantidad = :cantidad,
                monto_total = :monto_total,
                monto_debe = :monto_debe,
                asesor_id = :asesor_id,
                notas = :notas,
                nota_adicional = :nota_adicional,
                observacion = :observacion,
                descargo = :descargo,
                seguimiento = :seguimiento,
                fecha_entrega = :fecha_entrega,
                tipo_paquete = :tipo_paquete,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = :id'
        );

        $stmtUpdate->execute([
            ':dni_cliente' => $payload['dni_cliente'],
            ':nombre_completo' => $payload['nombre_completo'],
            ':celular' => $payload['celular'],
            ':agencia' => $payload['agencia'],
            ':sede_envio' => $payload['sede_envio'],
            ':codigo_rastreo' => $payload['codigo_rastreo'],
            ':codigo_tracking' => $payload['codigo_tracking'] ?? '',
            ':referencia_domicilio' => $payload['referencia_domicilio'],
            ':direccion_exacta' => $payload['direccion_exacta'],
            ':coordenadas' => $payload['coordenadas'],
            ':producto' => $payload['producto'],
            ':cantidad' => $payload['cantidad'],
            ':monto_total' => $payload['monto_total'],
            ':monto_debe' => $montoDebe,
            ':asesor_id' => $payload['asesor_id'],
            ':notas' => !empty(trim((string) ($existing['notas'] ?? ''))) ? $existing['notas'] : $payload['notas'],
            ':nota_adicional' => !empty(trim((string) ($existing['nota_adicional'] ?? ''))) ? $existing['nota_adicional'] : $payload['nota_adicional'],
            ':observacion' => !empty(trim((string) ($existing['observacion'] ?? ''))) ? $existing['observacion'] : $payload['observacion'],
            ':descargo' => !empty(trim((string) ($existing['descargo'] ?? ''))) ? $existing['descargo'] : $payload['descargo'],
            ':seguimiento' => !empty(trim((string) ($existing['seguimiento'] ?? ''))) ? $existing['seguimiento'] : $payload['seguimiento'],
            ':fecha_entrega' => $payload['fecha_entrega'],
            ':tipo_paquete' => $payload['tipo_paquete'],
            ':id' => (int) $existing['id'],
        ]);

        return [
            'pedido_id' => (int) $existing['id'],
            'action' => 'updated',
        ];
    }

    $stmtInsert = $pdo->prepare(
        'INSERT INTO pedidos (
            dni_cliente,
            nombre_completo,
            celular,
            agencia,
            sede_envio,
            codigo_rastreo,
            codigo_tracking,
            referencia_domicilio,
            direccion_exacta,
            coordenadas,
            producto,
            cantidad,
            monto_total,
            monto_adelantado,
            monto_debe,
            estado,
            asesor_id,
            notas,
            nota_adicional,
            observacion,
            descargo,
            seguimiento,
            fecha_entrega,
            tipo_paquete
        ) VALUES (
            :dni_cliente,
            :nombre_completo,
            :celular,
            :agencia,
            :sede_envio,
            :codigo_rastreo,
            :codigo_tracking,
            :referencia_domicilio,
            :direccion_exacta,
            :coordenadas,
            :producto,
            :cantidad,
            :monto_total,
            0,
            :monto_debe,
            :estado,
            :asesor_id,
            :notas,
            :nota_adicional,
            :observacion,
            :descargo,
            :seguimiento,
            :fecha_entrega,
            :tipo_paquete
        )'
    );

    $stmtInsert->execute([
        ':dni_cliente' => $payload['dni_cliente'],
        ':nombre_completo' => $payload['nombre_completo'],
        ':celular' => $payload['celular'],
        ':agencia' => $payload['agencia'],
        ':sede_envio' => $payload['sede_envio'],
        ':codigo_rastreo' => $payload['codigo_rastreo'],
        ':codigo_tracking' => $payload['codigo_tracking'],
        ':referencia_domicilio' => $payload['referencia_domicilio'],
        ':direccion_exacta' => $payload['direccion_exacta'],
        ':coordenadas' => $payload['coordenadas'],
        ':producto' => $payload['producto'],
        ':cantidad' => $payload['cantidad'],
        ':monto_total' => $payload['monto_total'],
        ':monto_debe' => $payload['monto_total'],
        ':estado' => $payload['estado'],
        ':asesor_id' => $payload['asesor_id'],
        ':notas' => $payload['notas'],
        ':nota_adicional' => $payload['nota_adicional'],
        ':observacion' => $payload['observacion'],
        ':descargo' => $payload['descargo'],
        ':seguimiento' => $payload['seguimiento'],
        ':fecha_entrega' => $payload['fecha_entrega'],
        ':tipo_paquete' => $payload['tipo_paquete'],
    ]);

    return [
        'pedido_id' => (int) $pdo->lastInsertId(),
        'action' => 'created',
    ];
}


function cc_test_prepare_rotulado_order_payload(array $sourceOrder, array $formData, int $fallbackUserId): array
{
    if (($sourceOrder['store_key'] ?? '') !== 'otra_tienda') {
        throw new RuntimeException('En este primer paso la subida automática a Pedidos Rotulados está activa solo para TUANI.');
    }

    $nombreCompleto = trim((string) ($sourceOrder['nombre'] ?? ''));
    $celular = trim((string) ($sourceOrder['celular'] ?? ''));
    $dni = trim((string) (($formData['dni'] ?? '') !== '' ? ($formData['dni'] ?? '') : ($sourceOrder['dni_drive'] ?? '')));
    $agencia = cc_test_normalize_shipping_agency($formData['agencia'] ?? '');
    $sedeEnvio = trim((string) ($formData['sede_agencia'] ?? ''));
    $montoAdelantado = cc_test_parse_amount((string) ($formData['monto_adelantado'] ?? ''));
    $observacionesPedido = trim((string) (($formData['observaciones'] ?? '') !== '' ? ($formData['observaciones'] ?? '') : ($sourceOrder['observaciones_drive'] ?? '')));
    $notaSeguimiento = trim((string) ($formData['nota_seguimiento'] ?? ''));

    if ($nombreCompleto === '' || $celular === '') {
        throw new RuntimeException('El pedido no tiene nombre o celular suficientes para enviarlo a Pedidos Rotulados.');
    }

    if ($dni === '') {
        throw new RuntimeException('Debes completar el DNI antes de subir el pedido a Pedidos Rotulados.');
    }

    if ($agencia === null || !in_array($agencia, cc_test_shipping_agency_options(), true)) {
        throw new RuntimeException('Selecciona una agencia válida para Pedidos Rotulados.');
    }

    if ($sedeEnvio === '') {
        throw new RuntimeException('Debes completar la sede de envío antes de subir el pedido a Pedidos Rotulados.');
    }

    if ($montoAdelantado === null) {
        throw new RuntimeException('Debes ingresar un monto de adelanto válido antes de subir el pedido a Pedidos Rotulados.');
    }

    $productoBase = trim((string) ($formData['producto'] ?? ''));
    if ($productoBase === '') {
        $productoBase = trim((string) ($sourceOrder['producto'] ?? ''));
    }
    $cantidadBase = trim((string) ($formData['cantidad'] ?? ''));
    if ($cantidadBase === '') {
        $cantidadBase = trim((string) ($sourceOrder['cantidad'] ?? ''));
    }
    $precioBase = trim((string) ($formData['precio'] ?? ''));
    if ($precioBase === '') {
        $precioBase = trim((string) ($sourceOrder['precio'] ?? ''));
    }

    $productoPrincipal = trim((string) ($formData['confirmacion_producto'] ?? ''));
    if ($productoPrincipal === '') {
        $productoPrincipal = $productoBase;
    }

    $cantidadPrincipalRaw = trim((string) ($formData['confirmacion_cantidad'] ?? ''));
    if ($cantidadPrincipalRaw === '') {
        $cantidadPrincipalRaw = $cantidadBase;
    }

    $precioPrincipalRaw = trim((string) ($formData['confirmacion_precio'] ?? ''));
    if ($precioPrincipalRaw === '') {
        $precioPrincipalRaw = $precioBase;
    }

    if ($productoPrincipal === '') {
        throw new RuntimeException('El pedido no tiene producto principal para subir a Pedidos Rotulados.');
    }

    $cantidadPrincipal = cc_test_parse_quantity($cantidadPrincipalRaw);
    if ($cantidadPrincipal === null) {
        throw new RuntimeException('La cantidad principal del pedido no es válida.');
    }

    $precioPrincipal = cc_test_parse_amount($precioPrincipalRaw);
    if ($precioPrincipal === null) {
        throw new RuntimeException('El precio principal del pedido no es válido.');
    }

    $productoExtra = trim((string) ($formData['confirmacion_producto_extra'] ?? ''));
    $cantidadExtraRaw = trim((string) ($formData['confirmacion_cantidad_extra'] ?? ''));
    $precioExtraRaw = trim((string) ($formData['confirmacion_precio_extra'] ?? ''));
    $hayExtra = $productoExtra !== '' || $cantidadExtraRaw !== '' || $precioExtraRaw !== '';

    $productos = [$productoPrincipal];
    $detalleProductos = [$productoPrincipal . ' (x' . $cantidadPrincipal . ')'];
    $cantidadTotal = $cantidadPrincipal;
    $montoTotal = $precioPrincipal;

    if ($hayExtra) {
        if ($productoExtra === '' || $cantidadExtraRaw === '' || $precioExtraRaw === '') {
            throw new RuntimeException('Si usas producto adicional, completa producto, cantidad y precio adicional.');
        }

        $cantidadExtra = cc_test_parse_quantity($cantidadExtraRaw);
        if ($cantidadExtra === null) {
            throw new RuntimeException('La cantidad del producto adicional no es válida.');
        }

        $precioExtra = cc_test_parse_amount($precioExtraRaw);
        if ($precioExtra === null) {
            throw new RuntimeException('El precio del producto adicional no es válido.');
        }

        $productos[] = $productoExtra;
        $detalleProductos[] = $productoExtra . ' (x' . $cantidadExtra . ')';
        $cantidadTotal += $cantidadExtra;
        $montoTotal += $precioExtra;
    }

    $identificadorPedido = trim((string) ($sourceOrder['codigo'] ?? ''));
    if ($identificadorPedido === '') {
        $identificadorPedido = trim((string) ($sourceOrder['import_id'] ?? ''));
    }
    if ($identificadorPedido === '') {
        $identificadorPedido = 'source:' . substr((string) ($sourceOrder['source_key'] ?? ''), 0, 12);
    }

    $notas = cc_test_build_contraentrega_notes([
        'Origen: Call Center TUANI',
        'Pedido base: ' . $identificadorPedido,
        'Detalle confirmado: ' . implode(', ', $detalleProductos),
        'Agencia: ' . $agencia,
        'Sede de envío: ' . $sedeEnvio,
        'Monto de adelanto: S/ ' . number_format($montoAdelantado, 2, '.', ''),
        $observacionesPedido !== '' ? 'Observaciones del pedido: ' . $observacionesPedido : '',
        $notaSeguimiento !== '' ? 'Nota interna Call Center: ' . $notaSeguimiento : '',
    ]);

    $codigoTracking = trim((string) ($sourceOrder['codigo'] ?? ''));
    $montoTotal = round($montoTotal, 2);
    $montoAdelantado = round($montoAdelantado, 2);
    $montoDebe = round(max(0, $montoTotal - $montoAdelantado), 2);

    return [
        'source_key' => (string) ($sourceOrder['source_key'] ?? ''),
        'dni_cliente' => $dni,
        'nombre_completo' => $nombreCompleto,
        'celular' => $celular,
        'agencia' => $agencia,
        'sede_envio' => $sedeEnvio,
        'codigo_tracking' => $codigoTracking !== '' ? $codigoTracking : null,
        'producto' => implode(', ', $productos),
        'cantidad' => $cantidadTotal,
        'monto_total' => $montoTotal,
        'monto_adelantado' => $montoAdelantado,
        'monto_debe' => $montoDebe,
        'asesor_id' => $fallbackUserId > 0 ? $fallbackUserId : null,
        'notas' => $notas,
        'nota_adicional' => $notaSeguimiento !== '' ? $notaSeguimiento : null,
        'observacion' => $observacionesPedido !== '' ? $observacionesPedido : null,
        'descargo' => $observacionesPedido !== '' ? $observacionesPedido : null,
        'seguimiento' => 'Subido desde Call Center TUANI',
        'estado' => 'ROTULADO 📦',
    ];
}

function cc_test_sync_rotulado_order(PDO $pdo, ?int $existingPedidoId, array $payload): array
{
    $existing = null;
    if ($existingPedidoId !== null && $existingPedidoId > 0) {
        $stmtExisting = $pdo->prepare('SELECT * FROM pedidos WHERE id = ? LIMIT 1');
        $stmtExisting->execute([$existingPedidoId]);
        $existing = $stmtExisting->fetch(PDO::FETCH_ASSOC) ?: null;
    }

    if ($existing) {
        $stmtUpdate = $pdo->prepare(
            'UPDATE pedidos SET
                dni_cliente = :dni_cliente,
                nombre_completo = :nombre_completo,
                celular = :celular,
                agencia = :agencia,
                sede_envio = :sede_envio,
                codigo_tracking = COALESCE(NULLIF(:codigo_tracking, \'\'), codigo_tracking),
                producto = :producto,
                cantidad = :cantidad,
                monto_total = :monto_total,
                monto_adelantado = :monto_adelantado,
                monto_debe = :monto_debe,
                asesor_id = :asesor_id,
                notas = :notas,
                nota_adicional = :nota_adicional,
                observacion = :observacion,
                descargo = :descargo,
                seguimiento = :seguimiento,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = :id'
        );

        $stmtUpdate->execute([
            ':dni_cliente' => $payload['dni_cliente'],
            ':nombre_completo' => $payload['nombre_completo'],
            ':celular' => $payload['celular'],
            ':agencia' => $payload['agencia'],
            ':sede_envio' => $payload['sede_envio'],
            ':codigo_tracking' => $payload['codigo_tracking'] ?? '',
            ':producto' => $payload['producto'],
            ':cantidad' => $payload['cantidad'],
            ':monto_total' => $payload['monto_total'],
            ':monto_adelantado' => $payload['monto_adelantado'],
            ':monto_debe' => $payload['monto_debe'],
            ':asesor_id' => $payload['asesor_id'],
            ':notas' => !empty(trim((string) ($existing['notas'] ?? ''))) ? $existing['notas'] : $payload['notas'],
            ':nota_adicional' => !empty(trim((string) ($existing['nota_adicional'] ?? ''))) ? $existing['nota_adicional'] : $payload['nota_adicional'],
            ':observacion' => !empty(trim((string) ($existing['observacion'] ?? ''))) ? $existing['observacion'] : $payload['observacion'],
            ':descargo' => !empty(trim((string) ($existing['descargo'] ?? ''))) ? $existing['descargo'] : $payload['descargo'],
            ':seguimiento' => !empty(trim((string) ($existing['seguimiento'] ?? ''))) ? $existing['seguimiento'] : $payload['seguimiento'],
            ':id' => (int) $existing['id'],
        ]);

        return [
            'pedido_id' => (int) $existing['id'],
            'action' => 'updated',
        ];
    }

    $stmtInsert = $pdo->prepare(
        'INSERT INTO pedidos (
            dni_cliente,
            nombre_completo,
            celular,
            agencia,
            sede_envio,
            codigo_tracking,
            producto,
            cantidad,
            monto_total,
            monto_adelantado,
            monto_debe,
            estado,
            asesor_id,
            notas,
            nota_adicional,
            observacion,
            descargo,
            seguimiento
        ) VALUES (
            :dni_cliente,
            :nombre_completo,
            :celular,
            :agencia,
            :sede_envio,
            :codigo_tracking,
            :producto,
            :cantidad,
            :monto_total,
            :monto_adelantado,
            :monto_debe,
            :estado,
            :asesor_id,
            :notas,
            :nota_adicional,
            :observacion,
            :descargo,
            :seguimiento
        )'
    );

    $stmtInsert->execute([
        ':dni_cliente' => $payload['dni_cliente'],
        ':nombre_completo' => $payload['nombre_completo'],
        ':celular' => $payload['celular'],
        ':agencia' => $payload['agencia'],
        ':sede_envio' => $payload['sede_envio'],
        ':codigo_tracking' => $payload['codigo_tracking'],
        ':producto' => $payload['producto'],
        ':cantidad' => $payload['cantidad'],
        ':monto_total' => $payload['monto_total'],
        ':monto_adelantado' => $payload['monto_adelantado'],
        ':monto_debe' => $payload['monto_debe'],
        ':estado' => $payload['estado'],
        ':asesor_id' => $payload['asesor_id'],
        ':notas' => $payload['notas'],
        ':nota_adicional' => $payload['nota_adicional'],
        ':observacion' => $payload['observacion'],
        ':descargo' => $payload['descargo'],
        ':seguimiento' => $payload['seguimiento'],
    ]);

    return [
        'pedido_id' => (int) $pdo->lastInsertId(),
        'action' => 'created',
    ];
}

$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
$estado = cc_test_normalize_state(trim((string) ($_POST['estado'] ?? 'POR LLAMAR')));
$validStates = cc_test_valid_states();
$subirALogistica = (string) ($_POST['subir_a_logistica'] ?? ($_POST['subir_a_ruta'] ?? '')) === '1';
$moverAPromoFinal = (string) ($_POST['mover_a_promo_final'] ?? '') === '1';

if ($sourceKey === '' || !preg_match('/^[a-f0-9]{40}$/', $sourceKey)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Pedido de prueba inválido']);
    exit;
}

if (!in_array($estado, $validStates, true)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Estado inválido']);
    exit;
}

$createdFiles = [];

try {
    $nota = cc_test_normalize_nullable_text('nota_seguimiento', 3000);
    $direccion = cc_test_normalize_nullable_text('direccion', 1000);
    $referencia = cc_test_normalize_nullable_text('referencia', 1000);
    $agencia = cc_test_normalize_nullable_text('agencia', 80);
    $sedeAgencia = cc_test_normalize_nullable_text('sede_agencia', 120);
    $sede = cc_test_normalize_nullable_text('sede', 120);
    $ciudad = cc_test_normalize_nullable_text('ciudad', 120);
    $distrito = cc_test_normalize_nullable_text('distrito', 120);
    $coordenadas = cc_test_normalize_nullable_text('coordenadas', 255);
    $dni = cc_test_normalize_nullable_text('dni', 40);
    $numeroCuentaSedeId = array_key_exists('numero_cuenta_sede_id', $_POST)
        ? cc_test_normalize_nullable_text('numero_cuenta_sede_id', 120)
        : null;
    $numeroCuentaDni = array_key_exists('numero_cuenta_dni', $_POST)
        ? cc_test_normalize_nullable_text('numero_cuenta_dni', 40)
        : null;
    $observaciones = cc_test_normalize_nullable_text('observaciones', 3000);
    $producto = cc_test_normalize_nullable_text('producto', 255);
    $cantidad = cc_test_normalize_nullable_text('cantidad', 50);
    $precio = cc_test_normalize_nullable_text('precio', 80);
    $montoAdelantadoRaw = cc_test_normalize_nullable_text('monto_adelantado', 80);
    $montoAdelantado = null;
    if ($montoAdelantadoRaw !== null) {
        $montoAdelantado = cc_test_parse_amount($montoAdelantadoRaw);
        if ($montoAdelantado === null) {
            throw new RuntimeException('Ingresa un monto de adelanto válido.');
        }
    }
    if ($agencia !== null) {
        $agencia = cc_test_normalize_shipping_agency($agencia) ?? $agencia;
    }
    $confirmacionProducto = cc_test_normalize_nullable_text('confirmacion_producto', 255);
    $confirmacionCantidad = cc_test_normalize_nullable_text('confirmacion_cantidad', 50);
    $confirmacionPrecio = cc_test_normalize_nullable_text('confirmacion_precio', 80);
    $confirmacionProductoExtra = cc_test_normalize_nullable_text('confirmacion_producto_extra', 255);
    $confirmacionCantidadExtra = cc_test_normalize_nullable_text('confirmacion_cantidad_extra', 50);
    $confirmacionPrecioExtra = cc_test_normalize_nullable_text('confirmacion_precio_extra', 80);
    $promoFinalEvidenceFile = cc_test_normalize_optional_image_upload('promo_final_evidencia');
    $canceladoEvidenceFile = cc_test_normalize_optional_image_upload('cancelado_evidencia');

    $pdo = db();
    cc_test_ensure_tracking_table($pdo);

    $stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at, numero_cuenta_sede_id, numero_cuenta_dni, user_id, promo_final_evidencia_path, promo_final_evidencia_subido_at, promo_final_evidencia_subido_por, cancelado_evidencia_path, cancelado_evidencia_subido_at, cancelado_evidencia_subido_por, ruta_contraentrega_pedido_id, pedido_rotulado_pedido_id FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
    $stmtCurrent->execute([$sourceKey]);
    $currentTracking = $stmtCurrent->fetch(PDO::FETCH_ASSOC) ?: null;

    if (!array_key_exists('numero_cuenta_sede_id', $_POST)) {
        $numeroCuentaSedeIdCurrent = trim((string) ($currentTracking['numero_cuenta_sede_id'] ?? ''));
        $numeroCuentaSedeId = $numeroCuentaSedeIdCurrent !== '' ? $numeroCuentaSedeIdCurrent : null;
    }

    if (!array_key_exists('numero_cuenta_dni', $_POST)) {
        $numeroCuentaDniCurrent = trim((string) ($currentTracking['numero_cuenta_dni'] ?? ''));
        $numeroCuentaDni = $numeroCuentaDniCurrent !== '' ? $numeroCuentaDniCurrent : null;
    }

    $promoFinalEvidencePath = trim((string) ($currentTracking['promo_final_evidencia_path'] ?? ''));
    $promoFinalEvidencePath = $promoFinalEvidencePath !== '' ? $promoFinalEvidencePath : null;
    $promoFinalEvidenceUploadedAt = $currentTracking['promo_final_evidencia_subido_at'] ?? null;
    $promoFinalEvidenceUploadedBy = isset($currentTracking['promo_final_evidencia_subido_por']) && (int) $currentTracking['promo_final_evidencia_subido_por'] > 0
        ? (int) $currentTracking['promo_final_evidencia_subido_por']
        : null;
    $canceladoEvidencePath = trim((string) ($currentTracking['cancelado_evidencia_path'] ?? ''));
    $canceladoEvidencePath = $canceladoEvidencePath !== '' ? $canceladoEvidencePath : null;
    $canceladoEvidenceUploadedAt = $currentTracking['cancelado_evidencia_subido_at'] ?? null;
    $canceladoEvidenceUploadedBy = isset($currentTracking['cancelado_evidencia_subido_por']) && (int) $currentTracking['cancelado_evidencia_subido_por'] > 0
        ? (int) $currentTracking['cancelado_evidencia_subido_por']
        : null;

    $role = (string) ($_SESSION['user_role'] ?? '');
    $isAdmin = in_array($role, ['Administrador', 'admin'], true);
    if (!$isAdmin) {
        $currentUserId = (int) ($_SESSION['user_id'] ?? 0);
        $trackingUserId = $currentTracking ? (int) ($currentTracking['user_id'] ?? 0) : null;
        if (!$currentTracking || $trackingUserId !== $currentUserId) {
            http_response_code(403);
            echo json_encode(['success' => false, 'message' => 'No autorizado para gestionar este pedido.']);
            exit;
        }
    }

    $userIdToSet = $isAdmin
        ? ($currentTracking ? ((int) ($currentTracking['user_id'] ?? 0) > 0 ? (int) $currentTracking['user_id'] : null) : null)
        : (int) $_SESSION['user_id'];

    $proximaRaw = trim((string) ($_POST['proxima_llamada_at'] ?? ''));
    $proximaLlamada = null;
    if ($proximaRaw !== '') {
        $proximaLlamada = DateTimeImmutable::createFromFormat('Y-m-d\TH:i', $proximaRaw);
        if (!$proximaLlamada) {
            throw new RuntimeException('La fecha de próxima llamada no es válida.');
        }
        $proximaLlamada = $proximaLlamada->format('Y-m-d H:i:s');
    }

    $fechaEntregaRaw = trim((string) ($_POST['fecha_entrega_programada'] ?? ''));
    $fechaEntrega = null;
    if ($fechaEntregaRaw !== '') {
        $fechaEntregaDate = DateTimeImmutable::createFromFormat('Y-m-d', $fechaEntregaRaw);
        if (!$fechaEntregaDate) {
            throw new RuntimeException('La fecha de entrega no es válida.');
        }
        $fechaEntrega = $fechaEntregaDate->format('Y-m-d');
    }

    if (cc_test_requires_delivery_date($estado) && $fechaEntrega === null) {
        throw new RuntimeException('Debes seleccionar la fecha de entrega para CONFIRMADO CONTRAENTREGA.');
    }

    if (!in_array($estado, cc_test_open_states(), true)) {
        $proximaLlamada = null;
    }

    if (!cc_test_requires_delivery_date($estado)) {
        $fechaEntrega = null;
    }

    $numeroCuentaEnviadoAt = $currentTracking['numero_cuenta_enviado_at'] ?? null;
    $currentState = cc_test_normalize_state((string) ($currentTracking['estado'] ?? ''));
    if ($estado === 'SE ENVIO NUMERO DE CUENTA') {
        if ($currentState !== 'SE ENVIO NUMERO DE CUENTA' || trim((string) $numeroCuentaEnviadoAt) === '') {
            $numeroCuentaEnviadoAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');
        }
    }

    if (cc_test_requires_shipping_details($estado)) {
        if ($dni === null || trim($dni) === '') {
            throw new RuntimeException('Debes completar el DNI para CONFIRMADO ENVIO.');
        }

        if ($agencia === null || !in_array($agencia, cc_test_shipping_agency_options(), true)) {
            throw new RuntimeException('Selecciona una agencia válida para CONFIRMADO ENVIO.');
        }

        if ($sedeAgencia === null || trim($sedeAgencia) === '') {
            throw new RuntimeException('Debes completar la sede de envío para CONFIRMADO ENVIO.');
        }

        if ($montoAdelantado === null) {
            throw new RuntimeException('Debes ingresar el monto de adelanto para CONFIRMADO ENVIO.');
        }
    }

    if ($subirALogistica && !in_array($estado, ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO'], true)) {
        throw new RuntimeException('Para subir el pedido, el estado debe ser CONFIRMADO CONTRAENTREGA o CONFIRMADO ENVIO.');
    }

    if ($moverAPromoFinal) {
        if (!in_array($estado, cc_test_followup_tracking_states(), true)) {
            throw new RuntimeException('Solo puedes mover a Promo Final pedidos que sigan en seguimiento.');
        }

        $sourceOrderForPromo = cc_test_fetch_source_order($pdo, $sourceKey);
        if (!$sourceOrderForPromo) {
            throw new RuntimeException('No encontré el pedido base para moverlo a Promo Final.');
        }

        $promoFinalDayInfo = cc_test_followup_day_info([
            'estado' => $estado,
            'drive_imported_at' => $sourceOrderForPromo['drive_imported_at'] ?? null,
            'first_seen_at' => $sourceOrderForPromo['first_seen_at'] ?? null,
            'import_id' => $sourceOrderForPromo['import_id'] ?? null,
        ]);
        if (empty($promoFinalDayInfo['is_promo_final'])) {
            throw new RuntimeException('Este pedido aún no puede pasar a Promo Final. Recién se habilita desde el Día 4.');
        }

        if ($promoFinalEvidenceFile === null && $promoFinalEvidencePath === null) {
            throw new RuntimeException('Debes subir una imagen de sustento para mover el pedido a Promo Final.');
        }
    }

    if ($estado === 'CANCELADO' && $canceladoEvidenceFile === null && $canceladoEvidencePath === null) {
        throw new RuntimeException('Debes subir una imagen de sustento para guardar el pedido en estado Cancelado.');
    }

    $actorUserId = (int) ($_SESSION['user_id'] ?? 0);
    if ($moverAPromoFinal && $promoFinalEvidenceFile !== null) {
        $storedPromoFinalEvidence = cc_test_store_tracking_evidence_image($promoFinalEvidenceFile, 'promo_final', $sourceKey, $actorUserId);
        $createdFiles[] = $storedPromoFinalEvidence['absolute_path'];
        $promoFinalEvidencePath = $storedPromoFinalEvidence['relative_path'];
        $promoFinalEvidenceUploadedAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');
        $promoFinalEvidenceUploadedBy = $actorUserId > 0 ? $actorUserId : null;
    }

    if ($estado === 'CANCELADO' && $canceladoEvidenceFile !== null) {
        $storedCanceladoEvidence = cc_test_store_tracking_evidence_image($canceladoEvidenceFile, 'cancelado', $sourceKey, $actorUserId);
        $createdFiles[] = $storedCanceladoEvidence['absolute_path'];
        $canceladoEvidencePath = $storedCanceladoEvidence['relative_path'];
        $canceladoEvidenceUploadedAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');
        $canceladoEvidenceUploadedBy = $actorUserId > 0 ? $actorUserId : null;
    }

    $formData = [
        'nota_seguimiento' => $nota,
        'direccion' => $direccion,
        'referencia' => $referencia,
        'agencia' => $agencia,
        'sede_agencia' => $sedeAgencia,
        'sede' => $sede,
        'ciudad' => $ciudad,
        'distrito' => $distrito,
        'coordenadas' => $coordenadas,
        'dni' => $dni,
        'numero_cuenta_sede_id' => $numeroCuentaSedeId,
        'numero_cuenta_dni' => $numeroCuentaDni,
        'observaciones' => $observaciones,
        'producto' => $producto,
        'cantidad' => $cantidad,
        'precio' => $precio,
        'monto_adelantado' => $montoAdelantado,
        'confirmacion_producto' => $confirmacionProducto,
        'confirmacion_cantidad' => $confirmacionCantidad,
        'confirmacion_precio' => $confirmacionPrecio,
        'confirmacion_producto_extra' => $confirmacionProductoExtra,
        'confirmacion_cantidad_extra' => $confirmacionCantidadExtra,
        'confirmacion_precio_extra' => $confirmacionPrecioExtra,
        'fecha_entrega_programada' => $fechaEntrega,
    ];

    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        'INSERT INTO callcenter_test_tracking (
            source_key,
            estado,
            nota_seguimiento,
            user_id,
            direccion,
            referencia,
            agencia,
            sede_agencia,
            sede,
            ciudad,
            distrito,
            coordenadas,
            dni,
            numero_cuenta_sede_id,
            numero_cuenta_dni,
            observaciones,
            producto,
            cantidad,
            precio,
            monto_adelantado,
            confirmacion_producto,
            confirmacion_cantidad,
            confirmacion_precio,
            confirmacion_producto_extra,
            confirmacion_cantidad_extra,
            confirmacion_precio_extra,
            proxima_llamada_at,
            fecha_entrega_programada,
            numero_cuenta_enviado_at,
            promo_final_evidencia_path,
            promo_final_evidencia_subido_at,
            promo_final_evidencia_subido_por,
            cancelado_evidencia_path,
            cancelado_evidencia_subido_at,
            cancelado_evidencia_subido_por,
            ultima_gestion_at
        ) VALUES (
            :source_key,
            :estado,
            :nota,
            :user_id,
            :direccion,
            :referencia,
            :agencia,
            :sede_agencia,
            :sede,
            :ciudad,
            :distrito,
            :coordenadas,
            :dni,
            :numero_cuenta_sede_id,
            :numero_cuenta_dni,
            :observaciones,
            :producto,
            :cantidad,
            :precio,
            :monto_adelantado,
            :confirmacion_producto,
            :confirmacion_cantidad,
            :confirmacion_precio,
            :confirmacion_producto_extra,
            :confirmacion_cantidad_extra,
            :confirmacion_precio_extra,
            :proxima_llamada_at,
            :fecha_entrega_programada,
            :numero_cuenta_enviado_at,
            :promo_final_evidencia_path,
            :promo_final_evidencia_subido_at,
            :promo_final_evidencia_subido_por,
            :cancelado_evidencia_path,
            :cancelado_evidencia_subido_at,
            :cancelado_evidencia_subido_por,
            CURRENT_TIMESTAMP
        )
        ON DUPLICATE KEY UPDATE
            estado = VALUES(estado),
            nota_seguimiento = VALUES(nota_seguimiento),
            user_id = VALUES(user_id),
            direccion = VALUES(direccion),
            referencia = VALUES(referencia),
            agencia = VALUES(agencia),
            sede_agencia = VALUES(sede_agencia),
            sede = VALUES(sede),
            ciudad = VALUES(ciudad),
            distrito = VALUES(distrito),
            coordenadas = VALUES(coordenadas),
            dni = VALUES(dni),
            numero_cuenta_sede_id = VALUES(numero_cuenta_sede_id),
            numero_cuenta_dni = VALUES(numero_cuenta_dni),
            observaciones = VALUES(observaciones),
            producto = VALUES(producto),
            cantidad = VALUES(cantidad),
            precio = VALUES(precio),
            monto_adelantado = VALUES(monto_adelantado),
            confirmacion_producto = VALUES(confirmacion_producto),
            confirmacion_cantidad = VALUES(confirmacion_cantidad),
            confirmacion_precio = VALUES(confirmacion_precio),
            confirmacion_producto_extra = VALUES(confirmacion_producto_extra),
            confirmacion_cantidad_extra = VALUES(confirmacion_cantidad_extra),
            confirmacion_precio_extra = VALUES(confirmacion_precio_extra),
            proxima_llamada_at = VALUES(proxima_llamada_at),
            fecha_entrega_programada = VALUES(fecha_entrega_programada),
            numero_cuenta_enviado_at = VALUES(numero_cuenta_enviado_at),
            promo_final_evidencia_path = VALUES(promo_final_evidencia_path),
            promo_final_evidencia_subido_at = VALUES(promo_final_evidencia_subido_at),
            promo_final_evidencia_subido_por = VALUES(promo_final_evidencia_subido_por),
            cancelado_evidencia_path = VALUES(cancelado_evidencia_path),
            cancelado_evidencia_subido_at = VALUES(cancelado_evidencia_subido_at),
            cancelado_evidencia_subido_por = VALUES(cancelado_evidencia_subido_por),
            ultima_gestion_at = CURRENT_TIMESTAMP,
            updated_at = CURRENT_TIMESTAMP'
    );

    $stmt->execute([
        ':source_key' => $sourceKey,
        ':estado' => $estado,
        ':nota' => $nota,
        ':user_id' => $userIdToSet,
        ':direccion' => $direccion,
        ':referencia' => $referencia,
        ':agencia' => $agencia,
        ':sede_agencia' => $sedeAgencia,
        ':sede' => $sede,
        ':ciudad' => $ciudad,
        ':distrito' => $distrito,
        ':coordenadas' => $coordenadas,
        ':dni' => $dni,
        ':numero_cuenta_sede_id' => $numeroCuentaSedeId,
        ':numero_cuenta_dni' => $numeroCuentaDni,
        ':observaciones' => $observaciones,
        ':producto' => $producto,
        ':cantidad' => $cantidad,
        ':precio' => $precio,
        ':monto_adelantado' => $montoAdelantado,
        ':confirmacion_producto' => $confirmacionProducto,
        ':confirmacion_cantidad' => $confirmacionCantidad,
        ':confirmacion_precio' => $confirmacionPrecio,
        ':confirmacion_producto_extra' => $confirmacionProductoExtra,
        ':confirmacion_cantidad_extra' => $confirmacionCantidadExtra,
        ':confirmacion_precio_extra' => $confirmacionPrecioExtra,
        ':proxima_llamada_at' => $proximaLlamada,
        ':fecha_entrega_programada' => $fechaEntrega,
        ':numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
        ':promo_final_evidencia_path' => $promoFinalEvidencePath,
        ':promo_final_evidencia_subido_at' => $promoFinalEvidenceUploadedAt,
        ':promo_final_evidencia_subido_por' => $promoFinalEvidenceUploadedBy,
        ':cancelado_evidencia_path' => $canceladoEvidencePath,
        ':cancelado_evidencia_subido_at' => $canceladoEvidenceUploadedAt,
        ':cancelado_evidencia_subido_por' => $canceladoEvidenceUploadedBy,
    ]);

    $rutaPedidoId = isset($currentTracking['ruta_contraentrega_pedido_id']) && (int) $currentTracking['ruta_contraentrega_pedido_id'] > 0
        ? (int) $currentTracking['ruta_contraentrega_pedido_id']
        : null;
    $rutaSubidoAt = null;
    $rutaAction = null;
    $pedidoRotuladoId = isset($currentTracking['pedido_rotulado_pedido_id']) && (int) $currentTracking['pedido_rotulado_pedido_id'] > 0
        ? (int) $currentTracking['pedido_rotulado_pedido_id']
        : null;
    $pedidoRotuladoSubidoAt = null;
    $pedidoRotuladoAction = null;

    if ($subirALogistica) {
        $sourceOrder = cc_test_fetch_source_order($pdo, $sourceKey);
        if (!$sourceOrder) {
            throw new RuntimeException('No encontré el pedido base para enviarlo a logística.');
        }

        if ($estado === 'CONFIRMADO CONTRAENTREGA') {
            $routePayload = cc_test_prepare_route_order_payload(
                $sourceOrder,
                $formData,
                (int) ($userIdToSet ?: ($_SESSION['user_id'] ?? 0))
            );

            $routeSync = cc_test_sync_route_order($pdo, $rutaPedidoId, $routePayload);
            $rutaPedidoId = (int) $routeSync['pedido_id'];
            $rutaAction = $routeSync['action'];
            $rutaSubidoAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');

            $stmtRuta = $pdo->prepare(
                'UPDATE callcenter_test_tracking
                 SET ruta_contraentrega_pedido_id = :pedido_id,
                     ruta_contraentrega_subido_at = :subido_at,
                     ruta_contraentrega_subido_por = :subido_por,
                     updated_at = CURRENT_TIMESTAMP
                 WHERE source_key = :source_key'
            );
            $stmtRuta->execute([
                ':pedido_id' => $rutaPedidoId,
                ':subido_at' => $rutaSubidoAt,
                ':subido_por' => (int) ($_SESSION['user_id'] ?? 0),
                ':source_key' => $sourceKey,
            ]);
        }

        if ($estado === 'CONFIRMADO ENVIO') {
            $rotuladoPayload = cc_test_prepare_rotulado_order_payload(
                $sourceOrder,
                $formData,
                (int) ($userIdToSet ?: ($_SESSION['user_id'] ?? 0))
            );

            $rotuladoSync = cc_test_sync_rotulado_order($pdo, $pedidoRotuladoId, $rotuladoPayload);
            $pedidoRotuladoId = (int) $rotuladoSync['pedido_id'];
            $pedidoRotuladoAction = $rotuladoSync['action'];
            $pedidoRotuladoSubidoAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');

            $stmtRotulado = $pdo->prepare(
                'UPDATE callcenter_test_tracking
                 SET pedido_rotulado_pedido_id = :pedido_id,
                     pedido_rotulado_subido_at = :subido_at,
                     pedido_rotulado_subido_por = :subido_por,
                     updated_at = CURRENT_TIMESTAMP
                 WHERE source_key = :source_key'
            );
            $stmtRotulado->execute([
                ':pedido_id' => $pedidoRotuladoId,
                ':subido_at' => $pedidoRotuladoSubidoAt,
                ':subido_por' => (int) ($_SESSION['user_id'] ?? 0),
                ':source_key' => $sourceKey,
            ]);
        }
    }

    $pdo->commit();

    $message = 'Gestión actualizada correctamente.';
    if ($moverAPromoFinal && $promoFinalEvidencePath !== null) {
        $message = 'Pedido movido a Promo Final correctamente.';
    }
    if ($subirALogistica && $estado === 'CONFIRMADO CONTRAENTREGA' && $rutaPedidoId !== null) {
        $message = $rutaAction === 'updated'
            ? 'Pedido actualizado en Ruta Contraentrega #' . $rutaPedidoId . '.'
            : 'Pedido subido a Ruta Contraentrega #' . $rutaPedidoId . '.';
    }
    if ($subirALogistica && $estado === 'CONFIRMADO ENVIO' && $pedidoRotuladoId !== null) {
        $message = $pedidoRotuladoAction === 'updated'
            ? 'Pedido actualizado en Pedidos Rotulados #' . $pedidoRotuladoId . '.'
            : 'Pedido subido a Pedidos Rotulados #' . $pedidoRotuladoId . '.';
    }

    echo json_encode([
        'success' => true,
        'message' => $message,
        'estado' => $estado,
        'proxima_llamada_at' => $proximaLlamada,
        'fecha_entrega_programada' => $fechaEntrega,
        'numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
        'numero_cuenta_sede_id' => $numeroCuentaSedeId,
        'numero_cuenta_dni' => $numeroCuentaDni,
        'promo_final_evidencia_path' => $promoFinalEvidencePath,
        'promo_final_evidencia_subido_at' => $promoFinalEvidenceUploadedAt,
        'cancelado_evidencia_path' => $canceladoEvidencePath,
        'cancelado_evidencia_subido_at' => $canceladoEvidenceUploadedAt,
        'ruta_contraentrega_pedido_id' => $rutaPedidoId,
        'ruta_contraentrega_subido_at' => $rutaSubidoAt,
        'pedido_rotulado_pedido_id' => $pedidoRotuladoId,
        'pedido_rotulado_subido_at' => $pedidoRotuladoSubidoAt,
    ]);
} catch (Throwable $exception) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    foreach ($createdFiles as $createdFile) {
        if (is_string($createdFile) && $createdFile !== '' && file_exists($createdFile)) {
            @unlink($createdFile);
        }
    }

    http_response_code(500);
    error_log('update_callcenter_test_tracking.php: ' . $exception->getMessage());
    echo json_encode([
        'success' => false,
        'message' => $exception instanceof RuntimeException ? $exception->getMessage() : 'No se pudo guardar la gestión.',
    ]);
}
