<?php

namespace App\Services;

use App\Core\App;

/**
 * Pseudo-cron content scheduler.
 *
 * Runs at most once every $debounceSeconds (default 60) per request cycle.
 * Transitions content between scheduled → published and published → draft
 * based on publish_at / unpublish_at timestamps.
 */
class ContentScheduler
{
    private string $lockFile;
    private int $debounceSeconds;

    public function __construct(string $storagePath, int $debounceSeconds = 60)
    {
        $this->lockFile = $storagePath . '/cache/.scheduling_lock';
        $this->debounceSeconds = $debounceSeconds;
    }

    /**
     * Run the scheduler if enough time has passed since the last run.
     */
    public function runIfDue(): void
    {
        if (file_exists($this->lockFile)) {
            $lastRun = (int) @file_get_contents($this->lockFile);
            if (time() - $lastRun < $this->debounceSeconds) {
                return;
            }
        }

        // Write lock timestamp
        $cacheDir = dirname($this->lockFile);
        if (!is_dir($cacheDir)) {
            @mkdir($cacheDir, 0755, true);
        }
        @file_put_contents($this->lockFile, (string) time());

        $this->processScheduledContent();
    }

    /**
     * Transition content statuses based on scheduling timestamps.
     */
    private function processScheduledContent(): void
    {
        $app = App::getInstance();
        if (!$app || !$app->hasService('database')) {
            return;
        }

        $db  = $app->db();
        $now = date('Y-m-d H:i:s');

        try {
            // ── Publish scheduled pages ──────────────────────────────────
            $db->query(
                "UPDATE iw_pages
                 SET status = 'published'
                 WHERE status = 'scheduled'
                   AND publish_at IS NOT NULL
                   AND publish_at <= :now",
                ['now' => $now]
            );

            // ── Unpublish expired pages ──────────────────────────────────
            $db->query(
                "UPDATE iw_pages
                 SET status = 'draft'
                 WHERE status = 'published'
                   AND unpublish_at IS NOT NULL
                   AND unpublish_at <= :now",
                ['now' => $now]
            );

            // ── Publish scheduled blog posts ─────────────────────────────
            // Also set published_at to the scheduled time for correct ordering
            $db->query(
                "UPDATE iw_blog_posts
                 SET status = 'published',
                     published_at = COALESCE(published_at, publish_at)
                 WHERE status = 'scheduled'
                   AND publish_at IS NOT NULL
                   AND publish_at <= :now",
                ['now' => $now]
            );

            // ── Unpublish expired blog posts ─────────────────────────────
            $db->query(
                "UPDATE iw_blog_posts
                 SET status = 'draft'
                 WHERE status = 'published'
                   AND unpublish_at IS NOT NULL
                   AND unpublish_at <= :now",
                ['now' => $now]
            );
            // Clear page cache if any content was transitioned
            $cache = new PageCache($app->basePath());
            $cache->clear();
        } catch (\Exception $e) {
            // Table columns may not exist yet (pre-migration) – skip silently
            error_log('ContentScheduler: ' . $e->getMessage());
        }
    }
}
