<?php

declare(strict_types=1);

/**
 * SysOp browser notifications (1.6.1): the console side of Web Push.
 * GET ?what=key hands the browser the board's VAPID public key (minting
 * the pair on first ask); POST subscribe/unsubscribe manage this
 * browser's registration; POST remove/test serve the Settings card.
 * Same guard as every console page: admin session + central CSRF.
 */

require __DIR__ . '/_lib.php';
$me = admin_require();
$db = atdt_db();
$settings = atdt_settings();

use Atdt\WebPush;

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'GET') {
    header('Content-Type: application/json; charset=utf-8');
    if ((string)($_GET['what'] ?? '') !== 'key') {
        echo json_encode(['error' => 'unknown']);
        exit;
    }
    if (!WebPush::supported()) {
        echo json_encode(['error' => 'This PHP build lacks openssl_pkey_derive / hash_hkdf; push needs PHP 8.1 with standard OpenSSL.']);
        exit;
    }
    $key = WebPush::publicKey($settings);
    echo json_encode($key === null
        ? ['error' => 'Could not mint VAPID keys (OpenSSL EC unavailable).']
        : ['key' => $key]);
    exit;
}

switch ((string)($_POST['action'] ?? '')) {
    case 'subscribe':
        header('Content-Type: application/json; charset=utf-8');
        $ok = WebPush::subscribe(
            $db,
            (string)($_POST['endpoint'] ?? ''),
            (string)($_POST['p256dh'] ?? ''),
            (string)($_POST['auth'] ?? ''),
            (string)($_POST['label'] ?? '')
        );
        if ($ok) {
            admin_log('Subscribed a browser to push notifications');
        }
        echo json_encode(['ok' => $ok]);
        exit;

    case 'unsubscribe':
        // This browser turned itself off; drop its row by endpoint.
        header('Content-Type: application/json; charset=utf-8');
        WebPush::removeByEndpoint($db, (string)($_POST['endpoint'] ?? ''));
        admin_log('Unsubscribed a browser from push notifications');
        echo json_encode(['ok' => true]);
        exit;

    case 'remove':
        WebPush::remove($db, (int)($_POST['id'] ?? 0));
        admin_log('Removed a push subscription');
        flash_set('ok', 'Subscription removed. That browser rings no more.');
        admin_redirect('settings.php#push');

    case 'test':
        [$sent, $dropped] = WebPush::notify(
            $db,
            $settings,
            (string)$settings->get('board_name', 'ATDT'),
            'Test ring from the console. This is what a page will feel like.',
            admin_base_url()
        );
        flash_set($sent > 0 ? 'ok' : 'err', $sent > 0
            ? "Test sent to $sent browser" . ($sent === 1 ? '' : 's') . ($dropped > 0 ? " ($dropped dead subscription" . ($dropped === 1 ? '' : 's') . ' pruned)' : '') . '. Give it a few seconds.'
            : ($dropped > 0
                ? "No live browsers - $dropped dead subscription" . ($dropped === 1 ? '' : 's') . ' pruned. Enable this browser and try again.'
                : 'Nothing was delivered. Is a browser enabled below, and is the board on HTTPS?'));
        admin_redirect('settings.php#push');
}

admin_redirect('settings.php#push');

/** The console URL a clicked notification opens (absolute when possible). */
function admin_base_url(): string
{
    $base = rtrim(trim((string)(atdt_settings()->get('base_url', '') ?? '')), '/');
    return $base !== '' ? $base . '/admin/index.php' : 'index.php';
}
