<?php
// =============================================================================
// /api/qr_settings.php — QR Login Page Editor save/load.
//
// All fields live as individual rows in webview_settings under qr_* keys, so
// the rendered mobile QR page can read them via webview_settings WHERE key LIKE 'qr_%'.
//
// GET                          → { qr: {...all qr_* keys, defaults filled} }
// POST action=save  body={qr:{...}}  → upsert each
// =============================================================================
require_once __DIR__ . '/_common.php';
require_csrf_unless_get();

$DEFAULTS = [
    // Logo
    'qr_logo_mode'           => 'text',
    'qr_logo_text'           => 'Master Panel',
    'qr_logo_image_url'      => '',
    // Colors
    'qr_color_bg'            => '#282929',
    'qr_color_card_bg'       => '#16161f',
    'qr_color_card_border'   => '#078850',
    'qr_color_accent_start'  => '#565452',
    'qr_color_accent_end'    => '#05a82e',
    'qr_color_text'          => '#09e13f',
    'qr_color_muted'         => '#666666',
    'qr_color_input_bg'      => '#1e1e2a',
    'qr_color_input_border'  => '#06cb48',
    // Sizing
    'qr_radius_card'         => '14',
    'qr_radius_button'       => '25',
    // Text
    'qr_text_title'          => 'Login to Your Device',
    'qr_text_subtitle'       => 'Enter your credentials',
    'qr_text_button'         => 'Login to Device',
    // Success
    'qr_success_title'       => 'Connected!',
    'qr_success_message'     => 'Your TV will login automatically. You can close this page.',
];

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $rows = db_all("SELECT key, value FROM webview_settings WHERE key LIKE 'qr_%'");
    $out  = $DEFAULTS;
    foreach ($rows as $r) $out[$r['key']] = $r['value'];
    json_response(['qr' => $out]);
}

require_method('POST');
list($action, $body) = read_action();
if ($action !== 'save') json_error('unknown action', 400);

$qr = $body['qr'] ?? [];
if (!is_array($qr)) json_error('qr object required', 400);

// Validation: every qr_color_* must be a 3- or 6-digit hex literal so it's safe
// to splice into inline CSS (style="background:<value>"). Reject CSS injection
// attempts like "#fff; background:url(...)" or invalid colors that would either
// silently break the page or open a CSS exfil channel.
$color_keys = [
    'qr_color_bg', 'qr_color_card_bg', 'qr_color_card_border',
    'qr_color_accent_start', 'qr_color_accent_end',
    'qr_color_text', 'qr_color_muted',
    'qr_color_input_bg', 'qr_color_input_border',
];
foreach ($color_keys as $k) {
    if (!array_key_exists($k, $qr)) continue;
    $v = trim((string)$qr[$k]);
    if (!preg_match('/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $v)) {
        json_error('"' . $k . '" must be a hex color like #fff or #aabbcc.', 400);
    }
}
// Sizing must be plain integers.
foreach (['qr_radius_card', 'qr_radius_button'] as $k) {
    if (!array_key_exists($k, $qr)) continue;
    if (!ctype_digit(trim((string)$qr[$k]))) {
        json_error('"' . $k . '" must be a whole number.', 400);
    }
}
// Logo mode is text|image only.
if (array_key_exists('qr_logo_mode', $qr)
    && !in_array((string)$qr['qr_logo_mode'], ['text', 'image'], true)) {
    json_error('"qr_logo_mode" must be either "text" or "image".', 400);
}

$now = time();
$saved = 0;
foreach ($DEFAULTS as $key => $_) {
    if (!array_key_exists($key, $qr)) continue;
    $value = (string)$qr[$key];
    db_exec(
        'INSERT INTO webview_settings (key, value, updated_at) VALUES (?, ?, ?)
         ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at',
        [$key, $value, $now]
    );
    $saved++;
}
json_response(['ok' => true, 'saved' => $saved]);
