<?php

function cmsHealthStatus($ok, $warning = false)
{
    return $ok ? 'ok' : ($warning ? 'warning' : 'error');
}

function cmsFormatBytes($bytes)
{
    $bytes = max(0, (float) $bytes);
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $index = 0;
    while ($bytes >= 1024 && $index < count($units) - 1) { $bytes /= 1024; $index++; }
    return number_format($bytes, $index > 1 ? 1 : 0) . ' ' . $units[$index];
}

function cmsSchedulerStatusFile()
{
    return dirname(__DIR__, 2) . '/data/cache/scheduled-publisher-status.json';
}

function cmsWriteSchedulerStatus($status, $published = 0, $message = '')
{
    $file = cmsSchedulerStatusFile();
    $directory = dirname($file);
    if (!is_dir($directory) && !@mkdir($directory, 0755, true) && !is_dir($directory)) { return false; }
    $data = ['status' => $status === 'error' ? 'error' : 'ok', 'run_at' => time(), 'published' => max(0, intval($published)), 'message' => trim((string) $message)];
    return @file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), LOCK_EX) !== false;
}

function cmsReadSchedulerStatus($now = null)
{
    $now = $now === null ? time() : intval($now);
    $file = cmsSchedulerStatusFile();
    $data = is_file($file) ? json_decode((string) @file_get_contents($file), true) : null;
    if (!is_array($data) || empty($data['run_at'])) {
        return ['status' => 'warning', 'run_at' => 0, 'published' => 0, 'message' => '尚无运行记录'];
    }
    $age = max(0, $now - intval($data['run_at']));
    $status = ($data['status'] ?? '') === 'error' ? 'error' : ($age > 600 ? 'warning' : 'ok');
    $data['status'] = $status;
    $data['age'] = $age;
    return $data;
}

function cmsCollectSystemHealth($db, $rootPath = null)
{
    $root = rtrim((string) ($rootPath ?: dirname(__DIR__, 2)), '/\\');
    $checks = [];
    $checks[] = ['name' => 'PHP 版本', 'value' => PHP_VERSION, 'status' => version_compare(PHP_VERSION, '7.4.0', '>=') ? 'ok' : 'error', 'detail' => '建议 PHP 7.4 或更高版本'];
    foreach (['pdo_mysql', 'mbstring', 'json', 'openssl', 'fileinfo'] as $extension) {
        $loaded = extension_loaded($extension);
        $checks[] = ['name' => '扩展 ' . $extension, 'value' => $loaded ? '已加载' : '未加载', 'status' => $loaded ? 'ok' : 'error', 'detail' => $loaded ? '运行正常' : '部分功能可能不可用'];
    }
    try {
        $version = $db->fetch('SELECT VERSION() AS version');
        $checks[] = ['name' => 'MySQL 连接', 'value' => (string) ($version['version'] ?? '已连接'), 'status' => 'ok', 'detail' => '数据库响应正常'];
    } catch (Throwable $e) {
        $checks[] = ['name' => 'MySQL 连接', 'value' => '连接异常', 'status' => 'error', 'detail' => '请检查数据库服务与配置'];
    }
    foreach (['data/cache', 'uploads', 'template'] as $relative) {
        $path = $root . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relative);
        $exists = is_dir($path);
        $writable = $exists && is_writable($path);
        $checks[] = ['name' => $relative, 'value' => !$exists ? '目录不存在' : ($writable ? '可写' : '不可写'), 'status' => $writable ? 'ok' : 'error', 'detail' => '路径：' . $relative];
    }
    $free = @disk_free_space($root);
    $total = @disk_total_space($root);
    $ratio = $total > 0 ? $free / $total : 1;
    $checks[] = ['name' => '磁盘空间', 'value' => $free === false ? '无法读取' : cmsFormatBytes($free) . ' 可用', 'status' => $free === false ? 'warning' : ($ratio < .05 ? 'error' : ($ratio < .15 ? 'warning' : 'ok')), 'detail' => $total ? '总容量 ' . cmsFormatBytes($total) : '未取得总容量'];
    return $checks;
}

function cmsSystemHealthSummary(array $checks)
{
    $summary = ['ok' => 0, 'warning' => 0, 'error' => 0];
    foreach ($checks as $check) { $status = $check['status'] ?? 'warning'; $summary[isset($summary[$status]) ? $status : 'warning']++; }
    return $summary;
}
