<?php
// =============================================================
//  POST /api/v1/system_settings/update
//
//  Batch-saves one or more settings, mirroring app/system_settings.php's
//  own save_settings AJAX action exactly: only known setting_keys are
//  accepted (unknown keys are silently ignored, matching the desktop),
//  values are validated/cast per their stored data_type, and the same
//  cross-field sanity check (grade thresholds should descend) runs
//  afterwards as a non-blocking warning rather than a hard failure —
//  it was already advisory-only on the desktop.
//
//  Body: { "settings": { "hospital_name": "...", "pass_mark_percentage": "55", ... } }
// =============================================================

require_once __DIR__ . '/../_bootstrap.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    Api::error(405, 'MethodNotAllowed', 'Use POST');
}

$account = api_authenticate();
api_require_permission('system_settings');

if (!settingsTableExists($conn)) {
    Api::error(409, 'SettingsTableMissing', 'Settings table not found.');
}

$body    = Api::body();
$updates = $body['settings'] ?? null;
if (!is_array($updates) || empty($updates)) {
    Api::error(422, 'ValidationError', 'No settings provided.');
}

// Fetch valid keys + their data types so we validate/cast correctly —
// same guard the desktop applies before accepting any value.
$valid = [];
$r = $conn->query("SELECT setting_key, data_type FROM settings");
while ($row = $r->fetch_assoc()) {
    $valid[$row['setting_key']] = $row['data_type'];
}

$savedCount = 0;
$warnings   = [];

foreach ($updates as $key => $rawValue) {
    $key = trim((string)$key);
    if (!isset($valid[$key])) continue; // ignore unknown keys, same as desktop

    $type = $valid[$key];

    if ($type === 'integer') {
        if (!ctype_digit((string)$rawValue) && !(is_numeric($rawValue) && (int)$rawValue >= 0)) {
            $warnings[] = "$key must be a positive number.";
            continue;
        }
        $value = (string)(int)$rawValue;
    } elseif ($type === 'boolean') {
        $value = ($rawValue === '1' || $rawValue === 'on' || $rawValue === 'true' || $rawValue === true) ? '1' : '0';
    } else {
        $value = trim((string)$rawValue);
    }

    if (setSetting($key, $value, $conn, $account->getId())) {
        $savedCount++;
    }
}

// Cross-field sanity check: grade thresholds should be descending.
$g = [];
$r2 = $conn->query("SELECT setting_key, value FROM settings WHERE setting_key IN ('grade_excellent_min','grade_verygood_min','grade_good_min','grade_fair_min')");
while ($row = $r2->fetch_assoc()) $g[$row['setting_key']] = (int)$row['value'];

if (isset($g['grade_excellent_min'], $g['grade_verygood_min'], $g['grade_good_min'], $g['grade_fair_min'])) {
    if (!($g['grade_excellent_min'] > $g['grade_verygood_min']
        && $g['grade_verygood_min'] > $g['grade_good_min']
        && $g['grade_good_min'] > $g['grade_fair_min'])) {
        $warnings[] = 'Grade thresholds should descend (Excellent > Very Good > Good > Fair) — please review.';
    }
}

if ($savedCount === 0) {
    Api::error(422, 'ValidationError', 'Nothing was saved.' . ($warnings ? ' ' . implode(' ', $warnings) : ''));
}

$permManager = new PermissionManager($conn);
$permManager->logAudit($account->getId(), 'update_settings', 'settings', 0, null, json_encode(['keys' => array_keys($updates)]));

Api::success(['saved_count' => $savedCount, 'warnings' => $warnings]);
