<?php
session_start();
require_once 'db/config.php';
require_once 'includes/callcenter_test_helpers.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;
}

$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
$estado = cc_test_normalize_state(trim((string) ($_POST['estado'] ?? 'POR LLAMAR')));
$validStates = cc_test_valid_states();

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;
}

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);
    $dni = cc_test_normalize_nullable_text('dni', 40);
    $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);
    $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);

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

    $stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
    $stmtCurrent->execute([$sourceKey]);
    $currentTracking = $stmtCurrent->fetch(PDO::FETCH_ASSOC) ?: null;

    $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');
        }
    }

    $stmt = $pdo->prepare(
        'INSERT INTO callcenter_test_tracking (
            source_key,
            estado,
            nota_seguimiento,
            user_id,
            direccion,
            referencia,
            agencia,
            sede_agencia,
            sede,
            ciudad,
            distrito,
            dni,
            observaciones,
            producto,
            cantidad,
            precio,
            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,
            ultima_gestion_at
        ) VALUES (
            :source_key,
            :estado,
            :nota,
            :user_id,
            :direccion,
            :referencia,
            :agencia,
            :sede_agencia,
            :sede,
            :ciudad,
            :distrito,
            :dni,
            :observaciones,
            :producto,
            :cantidad,
            :precio,
            :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,
            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),
            dni = VALUES(dni),
            observaciones = VALUES(observaciones),
            producto = VALUES(producto),
            cantidad = VALUES(cantidad),
            precio = VALUES(precio),
            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),
            ultima_gestion_at = CURRENT_TIMESTAMP,
            updated_at = CURRENT_TIMESTAMP'
    );

    $stmt->execute([
        ':source_key' => $sourceKey,
        ':estado' => $estado,
        ':nota' => $nota,
        ':user_id' => (int) $_SESSION['user_id'],
        ':direccion' => $direccion,
        ':referencia' => $referencia,
        ':agencia' => $agencia,
        ':sede_agencia' => $sedeAgencia,
        ':sede' => $sede,
        ':ciudad' => $ciudad,
        ':distrito' => $distrito,
        ':dni' => $dni,
        ':observaciones' => $observaciones,
        ':producto' => $producto,
        ':cantidad' => $cantidad,
        ':precio' => $precio,
        ':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,
    ]);

    echo json_encode([
        'success' => true,
        'message' => 'Gestión actualizada correctamente.',
        'estado' => $estado,
        'proxima_llamada_at' => $proximaLlamada,
        'fecha_entrega_programada' => $fechaEntrega,
        'numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
    ]);
} catch (Throwable $exception) {
    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.',
    ]);
}
