yazrkisvs3vvvsv33svrhetrjsvyvsvvyjsvsvs
tavsuysvssvvjvvyjyjkvsvqd
qfogsvvsvsegjdgdfgdskhgdksvqsvshdqsd
<?php
// api/onboarding-progress.php — FASE 8.4: persistencia del wizard de onboarding
// Antes: estado en _obSelected/_obStatus solo en memoria JS → se perdía al recargar.
// Ahora: tabla dm_onboarding_progress por (user_id, client_id).
header('Content-Type: application/json');
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/../auth.php';
require_once __DIR__ . '/../helpers/json.php';
dm_require_login();

$user      = dm_user();
$action    = $_GET['action'] ?? ($_POST['action'] ?? '');
$client_id = (int)($_GET['client_id'] ?? ($_POST['client_id'] ?? 0));

if (!$pdo) { echo json_encode(['ok'=>false,'error'=>'Sin BD']); exit; }
if (!$client_id || $client_id > 999999) { echo json_encode(['ok'=>false,'error'=>'client_id inválido']); exit; }
if (function_exists('dm_require_client_access')) dm_require_client_access($client_id);

// Crear tabla si no existe (idempotente)
try {
    $pdo->exec("CREATE TABLE IF NOT EXISTS dm_onboarding_progress (
        user_id     INT UNSIGNED NOT NULL,
        client_id   INT UNSIGNED NOT NULL,
        step        TINYINT      NOT NULL DEFAULT 1,
        selected    VARCHAR(255) NOT NULL DEFAULT '',
        updated_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        completed   TINYINT(1)   NOT NULL DEFAULT 0,
        PRIMARY KEY (user_id, client_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
} catch (\Throwable $e) {
    echo json_encode(['ok'=>false,'error'=>'No se pudo preparar la tabla de progreso']); exit;
}

if ($action === 'load') {
    try {
        $st = $pdo->prepare('SELECT step, selected, completed, updated_at FROM dm_onboarding_progress WHERE user_id=? AND client_id=? LIMIT 1');
        $st->execute([$user['id'], $client_id]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        if (!$row) { echo json_encode(['ok'=>true, 'has_progress'=>false]); exit; }
        $selected = array_values(array_filter(explode(',', $row['selected']), 'strlen'));
        echo json_encode([
            'ok'         => true,
            'has_progress'=> true,
            'step'       => (int)$row['step'],
            'selected'   => $selected,
            'completed'  => (bool)(int)$row['completed'],
            'updated_at' => $row['updated_at'],
        ]);
    } catch (\Throwable $e) {
        echo json_encode(['ok'=>false,'error'=>'Error leyendo progreso']);
    }
    exit;
}

if ($action === 'save') {
    dm_csrf_verify();
    $input = dm_json_decode_or(file_get_contents('php://input'), [], ['context'=>'onboarding-progress.save']);
    $step      = max(1, min(10, (int)($input['step'] ?? 1)));
    $selected  = $input['selected'] ?? [];
    $completed = !empty($input['completed']) ? 1 : 0;

    // Whitelist de servicios válidos (evita ensuciar BD con strings arbitrarios)
    $allowed_svcs = ['meta','google','gsc','tiktok','wordpress','shopify','mailchimp'];
    $clean_svcs = [];
    if (is_array($selected)) {
        foreach ($selected as $s) {
            if (is_string($s) && in_array($s, $allowed_svcs, true)) $clean_svcs[] = $s;
        }
    }
    $selected_csv = implode(',', array_unique($clean_svcs));
    if (mb_strlen($selected_csv) > 255) { $selected_csv = mb_substr($selected_csv, 0, 255); }

    try {
        $pdo->prepare('INSERT INTO dm_onboarding_progress (user_id, client_id, step, selected, completed)
                       VALUES (?,?,?,?,?)
                       ON DUPLICATE KEY UPDATE step=VALUES(step), selected=VALUES(selected), completed=VALUES(completed)')
            ->execute([$user['id'], $client_id, $step, $selected_csv, $completed]);
        echo json_encode(['ok'=>true, 'step'=>$step, 'selected'=>$clean_svcs, 'completed'=>(bool)$completed]);
    } catch (\Throwable $e) {
        echo json_encode(['ok'=>false,'error'=>'Error guardando progreso']);
    }
    exit;
}

if ($action === 'reset') {
    dm_csrf_verify();
    try {
        $pdo->prepare('DELETE FROM dm_onboarding_progress WHERE user_id=? AND client_id=?')->execute([$user['id'], $client_id]);
        echo json_encode(['ok'=>true]);
    } catch (\Throwable $e) {
        echo json_encode(['ok'=>false,'error'=>'Error reseteando progreso']);
    }
    exit;
}

echo json_encode(['ok'=>false,'error'=>'action inválida']);
