<?php
@ini_set('display_errors', '0');
error_reporting(E_ALL);
ob_start();
register_shutdown_function(function () {
    $error = error_get_last();
    if (!$error || !in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR], true)) return;
    while (ob_get_level() > 0) ob_end_clean();
    $root = dirname(__DIR__);
    $logDir = $root . '/data/upgrade_tmp';
    if (!is_dir($logDir)) @mkdir($logDir, 0755, true);
    $detail = date('Y-m-d H:i:s') . ' | ' . $error['message'] . ' | ' . $error['file'] . ':' . $error['line'] . PHP_EOL;
    @file_put_contents($logDir . '/last_error.log', $detail, FILE_APPEND | LOCK_EX);
    if (!headers_sent()) {
        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        header('Cache-Control: no-store');
    }
    echo json_encode([
        'code' => 500,
        'msg' => '升级接口发生致命错误：' . $error['message'],
        'debug' => basename($error['file']) . ':' . $error['line'],
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
});

require_once dirname(__DIR__) . '/core/lib/session.php';
cmsStartSession();
if (!cmsValidateAdminSession() || empty($_SESSION['admin_id'])) {
    http_response_code(401);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['code' => 401, 'msg' => '后台登录已失效，请重新登录'], JSON_UNESCAPED_UNICODE);
    exit;
}

define('ROOT_PATH', dirname(__DIR__) . '/');
if (!defined('LICENSE_CENTER_URL')) define('LICENSE_CENTER_URL', 'http://yutou.wtbidc.cn/license-center');
require_once ROOT_PATH . 'core/db/db.php';
require_once ROOT_PATH . 'core/lib/common.php';
require_once ROOT_PATH . 'core/lib/rbac.php';
require_once ROOT_PATH . 'core/lib/license.php';
$upgradeServiceFile = ROOT_PATH . 'core/lib/upgrade_service.php';
if (!is_file($upgradeServiceFile)) {
    http_response_code(500);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['code' => 500, 'msg' => '升级组件不完整：缺少 core/lib/upgrade_service.php，请重新覆盖新版升级包'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}
require_once $upgradeServiceFile;

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['code' => 405, 'msg' => '仅支持 POST 请求'], JSON_UNESCAPED_UNICODE);
    exit;
}

$db = \Core\Db\DB::getInstance();
cmsRequireAdminPermission(cmsLoadCurrentAdminAccess($db), 'version', true, 'manage');
requireAdminCsrfToken(true);
$license = new \Core\Lib\License();
if (!$license->canOnlineUpgrade()) {
    http_response_code(403);
    echo json_encode(['code' => 403, 'msg' => '当前授权不支持在线升级'], JSON_UNESCAPED_UNICODE);
    exit;
}

ignore_user_abort(true);
@set_time_limit(0);
@ini_set('max_execution_time', '0');
$phase = trim((string) ($_POST['phase'] ?? ''));
$targetVersion = trim((string) ($_POST['target_version'] ?? ''));
if ($targetVersion !== '' && version_compare($targetVersion, \Core\Lib\License::VERSION, '<')) {
    http_response_code(400);
    echo json_encode(['code' => 400, 'msg' => '不允许通过在线升级降级到旧版本'], JSON_UNESCAPED_UNICODE);
    exit;
}
session_write_close();

try {
    if ($phase === 'download') {
        $licenseStatus = $license->getStatus();
        $result = cmsUpgradeDownload(
            ROOT_PATH,
            LICENSE_CENTER_URL,
            $targetVersion,
            \Core\Lib\License::VERSION,
            $licenseStatus['license_key'] ?? ($licenseStatus['code'] ?? ''),
            $licenseStatus['domain'] ?? ($_SERVER['HTTP_HOST'] ?? '')
        );
    } elseif ($phase === 'extract') {
        $result = cmsUpgradeExtract(ROOT_PATH, $targetVersion);
    } elseif ($phase === 'copy') {
        $result = cmsUpgradeCopyBatch(ROOT_PATH, $targetVersion, intval($_POST['batch_size'] ?? 120));
    } elseif ($phase === 'finalize') {
        $result = cmsUpgradeFinalize(ROOT_PATH, $targetVersion);
    } else {
        throw new RuntimeException('未知升级阶段');
    }
    echo json_encode(['code' => 200, 'data' => $result], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} catch (Throwable $e) {
    http_response_code(500);
    echo json_encode(['code' => 500, 'msg' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
