<?php

require_once __DIR__ . '/article_review.php';
require_once __DIR__ . '/system_health.php';

function cmsNormalizeScheduleTime($value)
{
    if (is_int($value) || ctype_digit((string) $value)) {
        return max(0, intval($value));
    }
    $timestamp = strtotime(trim((string) $value));
    return $timestamp === false ? 0 : $timestamp;
}

function cmsIsArticleDueForPublish(array $article, $now = null)
{
    $now = $now ?: time();
    return intval($article['status'] ?? 0) === 0
        && intval($article['deleted_at'] ?? 0) === 0
        && cmsNormalizeArticleReviewState($article['review_status'] ?? 'approved') === 'approved'
        && intval($article['scheduled_publish_at'] ?? 0) > 0
        && intval($article['scheduled_publish_at']) <= $now;
}

function cmsPublishScheduledArticles($db, $now = null, $limit = 100)
{
    $now = $now ?: time();
    $limit = max(1, min(500, intval($limit)));
    $table = $db->table('article');
    $lock = $db->fetch("SELECT GET_LOCK('enterprise_cms_scheduled_publisher', 0) AS acquired");
    if (intval($lock['acquired'] ?? 0) !== 1) { return []; }
    try {
        $rows = $db->fetchAll(
            "SELECT id, title FROM {$table} WHERE status=0 AND deleted_at=0 AND review_status='approved' AND scheduled_publish_at>0 AND scheduled_publish_at<=? ORDER BY scheduled_publish_at ASC, id ASC LIMIT {$limit}",
            [$now]
        );
        if (!$rows) { cmsWriteSchedulerStatus('ok', 0, '检查完成，没有到期文章'); return []; }
        $ids = array_map('intval', array_column($rows, 'id'));
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        $db->query(
            "UPDATE {$table} SET status=1, review_status='approved', release_time=scheduled_publish_at, scheduled_publish_at=0, published_at=?, published_by=0, update_time=? WHERE id IN ({$placeholders}) AND status=0 AND deleted_at=0 AND review_status='approved' AND scheduled_publish_at>0 AND scheduled_publish_at<=?",
            array_merge([$now, $now], $ids, [$now])
        );
        foreach ($rows as $row) {
            try {
                $db->insert('log', [
                    'user_id' => 0, 'username' => '系统任务', 'action' => '定时发布', 'module' => '文章管理',
                    'content' => '定时发布文章 ' . ($row['title'] ?? $row['id']), 'ip' => '', 'user_agent' => 'EnterpriseCMS Scheduler', 'create_time' => $now,
                ]);
            } catch (Throwable $e) {
                error_log('EnterpriseCMS scheduled publish log failed: ' . $e->getMessage());
            }
        }
        cmsWriteSchedulerStatus('ok', count($ids), '定时发布执行完成');
        return $ids;
    } catch (Throwable $e) {
        cmsWriteSchedulerStatus('error', 0, '定时发布执行失败');
        throw $e;
    } finally {
        $db->query("SELECT RELEASE_LOCK('enterprise_cms_scheduled_publisher')");
    }
}

function cmsMaybePublishScheduledArticles($db, $interval = 60)
{
    $directory = dirname(__DIR__, 2) . '/data/cache';
    if (!is_dir($directory) && !@mkdir($directory, 0755, true) && !is_dir($directory)) { return []; }
    $file = $directory . '/scheduled-publisher.lock';
    $handle = @fopen($file, 'c+');
    if (!$handle || !flock($handle, LOCK_EX | LOCK_NB)) { if ($handle) { fclose($handle); } return []; }
    $lastRun = intval(trim((string) stream_get_contents($handle)));
    $now = time();
    if ($lastRun > $now - max(10, intval($interval))) {
        flock($handle, LOCK_UN); fclose($handle); return [];
    }
    rewind($handle); ftruncate($handle, 0); fwrite($handle, (string) $now); fflush($handle);
    $published = cmsPublishScheduledArticles($db, $now);
    flock($handle, LOCK_UN); fclose($handle);
    return $published;
}
