<?php
// tests/test-saas-admin.php — Admin panel auth protection
require_once __DIR__ . '/run.php';

$base = TEST_BASE_URL;

function _sadm_fetch(string $url, array $extra = []): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, $extra + [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => false,
        CURLOPT_TIMEOUT        => 6,
        CURLOPT_SSL_VERIFYPEER => false,
    ]);
    $raw  = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return [$code, (string)$raw];
}

// ══════════════════════════════════════════════════════════════
// 1. ADMIN PROTECTED PAGES — must not return 200 without session
//    Expected: 302 (redirect to login) or 403 (IP not whitelisted)
// ══════════════════════════════════════════════════════════════

$admin_pages = [
    'admin/growth.php',
    'admin/revenue.php',
    'admin/users.php',
    'admin/implementations.php',
    'admin/system.php',
    'admin/config_admin.php',
    'admin/apis.php',
    'admin/gdpr.php',
];

foreach ($admin_pages as $page) {
    [$code] = _sadm_fetch("{$base}/{$page}");
    $blocked = in_array($code, [302, 403, 401]);
    dm_assert("Admin protected: {$page}", $blocked, "Expected 302/403, got HTTP {$code}");
}

// ══════════════════════════════════════════════════════════════
// 2. ADMIN LOGIN PAGE — must be accessible (HTTP 200)
// ══════════════════════════════════════════════════════════════

[$code, $body] = _sadm_fetch("{$base}/admin/index.php");
dm_assert('Admin login: HTTP 200',          $code === 200,                      "Got HTTP {$code}");
dm_assert('Admin login: has password input', str_contains($body, 'password'),   'No password field in login page');

// ══════════════════════════════════════════════════════════════
// 3. ADMIN LOGIN — wrong credentials must not redirect to dashboard
// ══════════════════════════════════════════════════════════════

[$code, $body] = _sadm_fetch("{$base}/admin/index.php", [
    CURLOPT_POST       => true,
    CURLOPT_POSTFIELDS => 'email=hacker@test.com&password=wrongpassword123',
]);
// A successful login would redirect (302) to growth.php; wrong creds must stay on login (200) or also 302 to login
$body_lc = strtolower($body);
$no_bypass = !str_contains($body_lc, 'growth') && !str_contains($body_lc, 'revenue')
          && !str_contains($body_lc, 'mrr') && !str_contains($body_lc, 'usuarios');
dm_assert('Admin login: wrong credentials blocked', $no_bypass,
    'Response contains dashboard content after failed login');

// ══════════════════════════════════════════════════════════════
// 4. SAAS ENDPOINTS — must require auth (no session)
// ══════════════════════════════════════════════════════════════

$saas_eps = [
    'api/billing.php?action=get_status',
    'api/billing.php?action=portal',
    'api/my-clients.php',
];

foreach ($saas_eps as $ep) {
    [$code, $raw] = _sadm_fetch("{$base}/{$ep}");
    $json    = json_decode($raw, true);
    $blocked = in_array($code, [401, 302, 403])
            || ($json && isset($json['ok']) && $json['ok'] === false);
    dm_assert("SaaS auth: {$ep}", $blocked, "Got HTTP {$code}");
}

// ══════════════════════════════════════════════════════════════
// 5. WEBHOOK — must reject unsigned payload with HTTP 400
// ══════════════════════════════════════════════════════════════

[$code] = _sadm_fetch("{$base}/api/billing.php?webhook=1", [
    CURLOPT_POST       => true,
    CURLOPT_POSTFIELDS => '{"type":"test.event","id":"evt_unsigned"}',
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
dm_assert('Webhook: unsigned payload rejected (HTTP 400)', $code === 400,
    "Got HTTP {$code} — expected 400 (invalid Stripe signature)");

// ══════════════════════════════════════════════════════════════
// 6. PUBLIC REPORT — invalid token must not expose data
// ══════════════════════════════════════════════════════════════

[$code, $body] = _sadm_fetch("{$base}/public-report.php?token=INVALID_TOKEN_000");
$body_lc = strtolower($body);
$safe = !str_contains($body_lc, 'meta ads')
     && !str_contains($body_lc, 'google ads')
     && !str_contains($body_lc, 'impresiones')
     && !str_contains($body_lc, 'conversion');
dm_assert('Public report: invalid token exposes no client data', $safe,
    "Response contains report data for an invalid token");
