<?php
require __DIR__ . '/../../app/bootstrap.php';
require __DIR__ . '/../../app/database.php';
require_task_runner_access();
session_write_close();
ignore_user_abort(true);
@set_time_limit(0);

header('Content-Type: application/json; charset=utf-8');

$limit = 3;
if (isset($_POST['limit'])) {
    $limit = (int)$_POST['limit'];
} elseif (isset($_GET['limit'])) {
    $limit = (int)$_GET['limit'];
}

$debug = isset($_REQUEST['debug']) && $_REQUEST['debug'] === '1';

$runtimeDir = __DIR__ . '/../../runtime';
if (!is_dir($runtimeDir)) {
    @mkdir($runtimeDir, 0755, true);
}
$logFile = $runtimeDir . '/article-task-runner.log';
$lockFile = $runtimeDir . '/article-task-runner.lock';

function runner_log($msg) {
    global $logFile;
    $line = '[' . date('Y-m-d H:i:s') . '] ' . $msg . "\n";
    @file_put_contents($logFile, $line, FILE_APPEND | LOCK_EX);
}

// 检查并发锁：防止多个 runner 同时执行 AI 任务
$lockFp = @fopen($lockFile, 'c');
if ($lockFp && !flock($lockFp, LOCK_EX | LOCK_NB)) {
    runner_log('--- Runner skipped (another instance is running).');
    echo json_encode(array(
        'success' => true,
        'message' => '另一个任务正在执行中，本次跳过。',
        'executed_count' => 0,
        'skipped' => true
    ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    fclose($lockFp);
    exit;
}

runner_log('--- Runner called. Method=' . $_SERVER['REQUEST_METHOD'] . ' IP=' . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));

try {
    $pdo = db_connection();
    $allTaskRows = $pdo->query("SELECT id, task_name, status, next_run_at, last_run_at, interval_seconds FROM article_generation_tasks ORDER BY id DESC LIMIT 5")->fetchAll(PDO::FETCH_ASSOC);
    foreach ($allTaskRows as $tr) {
        runner_log('  Task #' . $tr['id'] . ' [' . $tr['task_name'] . '] status=' . $tr['status'] . ' next_run=' . ($tr['next_run_at'] ?: 'NULL') . ' last_run=' . ($tr['last_run_at'] ?: 'NULL') . ' interval=' . $tr['interval_seconds']);
    }
    runner_log('  Server now=' . date('Y-m-d H:i:s') . ' limit=' . $limit);

    $dueTasks = list_due_article_generation_tasks($limit);
    runner_log('  Due tasks found: ' . count($dueTasks));
    foreach ($dueTasks as $dt) {
        runner_log('    Due: #' . ($dt['id'] ?? 0) . ' [' . ($dt['task_name'] ?? '') . '] status=' . ($dt['status'] ?? '') . ' next_run=' . ($dt['next_run_at'] ?? 'NULL'));
    }

    $debugInfo = array();
    if ($debug) {
        $debugInfo['server_time'] = date('Y-m-d H:i:s');
        $debugInfo['due_task_count'] = count($dueTasks);
        foreach ($dueTasks as $dt) {
            $debugInfo['due_tasks'][] = array(
                'id' => isset($dt['id']) ? (int)$dt['id'] : 0,
                'task_name' => isset($dt['task_name']) ? $dt['task_name'] : '',
                'status' => isset($dt['status']) ? $dt['status'] : '',
                'next_run_at' => isset($dt['next_run_at']) ? $dt['next_run_at'] : null,
                'last_run_at' => isset($dt['last_run_at']) ? $dt['last_run_at'] : null,
                'interval_seconds' => isset($dt['interval_seconds']) ? (int)$dt['interval_seconds'] : 0,
                'pending_count' => isset($dt['pending_count']) ? (int)$dt['pending_count'] : 0,
            );
        }
        $debugInfo['all_tasks'] = $allTaskRows;
    }

    // 先发送 HTTP 响应，再在后台执行耗时的 AI 任务
    $dueCount = count($dueTasks);
    $response = array(
        'success' => true,
        'message' => $dueCount > 0 ? '已找到 ' . $dueCount . ' 个到期任务，后台执行中...' : '当前无到期任务。',
        'due_count' => $dueCount,
        'executed_count' => 0
    );
    if ($debug) {
        $response['debug'] = $debugInfo;
    }
    $responseJson = json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    // 关闭 HTTP 连接，PHP 继续后台执行
    if (function_exists('fastcgi_finish_request')) {
        header('Content-Length: ' . strlen($responseJson));
        echo $responseJson;
        fastcgi_finish_request();
        runner_log('  HTTP response sent via fastcgi_finish_request, continuing in background...');
    } else {
        header('Connection: close');
        header('Content-Length: ' . strlen($responseJson));
        ob_end_flush();
        echo $responseJson;
        flush();
        runner_log('  HTTP response sent via Connection:close, continuing in background...');
    }

    // 后台执行实际的 AI 任务（HTTP 连接已关闭，不会 502）
    if ($dueCount > 0) {
        $results = run_due_article_generation_tasks($limit);
        runner_log('  Executed: ' . count($results) . ' tasks');
        foreach ($results as $r) {
            runner_log('    Result: task#' . ($r['task_id'] ?? 0) . ' success=' . ($r['success'] ? 'Y' : 'N') . ' msg=' . ($r['message'] ?? ($r['data']['message'] ?? '')));
        }
    } else {
        runner_log('  No due tasks, nothing to execute.');
    }
} catch (Exception $e) {
    runner_log('  ERROR: ' . $e->getMessage());
    if (!headers_sent()) {
        http_response_code(500);
        echo json_encode(array(
            'success' => false,
            'message' => $e->getMessage()
        ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }
}

// 释放文件锁
if ($lockFp) {
    flock($lockFp, LOCK_UN);
    fclose($lockFp);
}
runner_log('--- Runner finished.');
