<?php

use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;
use App\Uploads\Services\CleanupService;

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');

Artisan::command('uploads:cleanup {--limit=100 : Maximum drafts to clean in one run}', function (): void {
    $limit = (int) $this->option('limit');
    $deleted = app(CleanupService::class)->cleanupStaleDrafts($limit);

    $this->info("Uploads cleanup deleted {$deleted} draft(s).");
})->purpose('Delete stale draft uploads and temporary files');

// ── Scheduled tasks ────────────────────────────────────────────────────────────

// Recalculate trending scores every 30 minutes, staggered away from other hot paths.
Schedule::command('skinbase:recalculate-trending --period=24h')
    ->cron('6,36 * * * *')
    ->name('trending-24h')
    ->withoutOverlapping();

Schedule::command('skinbase:recalculate-trending --period=7d --skip-index')
    ->cron('19,49 * * * *')
    ->name('trending-7d')
    ->runInBackground()
    ->withoutOverlapping();

// Reset windowed view/download counters so trending uses recent-activity data.
// Downloads are recomputed from the artwork_downloads log (accurate).
// Views are zeroed (no per-view event log) and re-accumulate from midnight.
Schedule::command('skinbase:reset-windowed-stats --period=24h')
    ->dailyAt('03:30')
    ->name('reset-windowed-stats-24h')
    ->withoutOverlapping();

Schedule::command('skinbase:reset-windowed-stats --period=7d')
    ->weeklyOn(1, '03:50') // Monday 03:50
    ->name('reset-windowed-stats-7d')
    ->withoutOverlapping();

// Daily maintenance
Schedule::command('uploads:cleanup')->dailyAt('03:00');
Schedule::command('enhance:cleanup --force')
    ->dailyAt('03:30')
    ->name('enhance-cleanup')
    ->withoutOverlapping()
    ->runInBackground();
Schedule::command('analytics:aggregate-similar-artworks')->dailyAt('03:10');
Schedule::command('analytics:aggregate-feed')->dailyAt('03:20');
Schedule::command('analytics:aggregate-discovery-feedback')->dailyAt('03:25');
Schedule::command('analytics:aggregate-tag-interactions')->dailyAt('03:35');
Schedule::command('academy:analytics-rollup')
    ->hourlyAt(12)
    ->name('academy-analytics-rollup')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('academy:analytics-recalculate-popularity --days=30')
    ->dailyAt('03:45')
    ->name('academy-analytics-popularity')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('academy:analytics-prune-events --days=180')
    ->dailyAt('04:20')
    ->name('academy-analytics-prune')
    ->withoutOverlapping()
    ->runInBackground();

// Drain Redis artwork-stat delta queue so MySQL counters stay fresh.
// Offset this off the :00/:10 boundaries so it does not pile onto publish jobs.
Schedule::command('skinbase:flush-redis-stats')
    ->cron('1,11,21,31,41,51 * * * *')
    ->name('flush-redis-stats')
    ->withoutOverlapping();

// Prune artwork_view_events rows older than 90 days.
// Runs Sunday at 04:00, after all other weekly maintenance.
Schedule::command('skinbase:prune-view-events --days=90')
    ->weekly()
    ->sundays()
    ->at('04:00')
    ->name('prune-view-events')
    ->withoutOverlapping();

// ── Similar Artworks (Hybrid Recommender) ──────────────────────────────────────
// Build co-occurrence pairs from favourites every 4 hours.
Schedule::job(new \App\Jobs\RecBuildItemPairsFromFavouritesJob())
    ->everyFourHours()
    ->name('rec-build-item-pairs')
    ->withoutOverlapping();

// Nightly: recompute tag, behavior, and hybrid similarity lists.
Schedule::job(new \App\Jobs\RecComputeSimilarByTagsJob())
    ->dailyAt('02:00')
    ->name('rec-compute-tags')
    ->withoutOverlapping();

Schedule::job(new \App\Jobs\RecComputeSimilarByBehaviorJob())
    ->dailyAt('02:15')
    ->name('rec-compute-behavior')
    ->withoutOverlapping();

Schedule::job(new \App\Jobs\RecComputeSimilarHybridJob())
    ->dailyAt('02:30')
    ->name('rec-compute-hybrid')
    ->withoutOverlapping();

// ── Feed 2.0: Scheduled Posts ─────────────────────────────────────────────────
// Publish queued posts every minute.
Schedule::command('posts:publish-scheduled')
    ->everyMinute()
    ->name('publish-scheduled-posts')
    ->withoutOverlapping();

// ── Scheduled content publishing ──────────────────────────────────────────────
// These must live in routes/console.php for Laravel 11's active scheduler.
Schedule::command('artworks:publish-scheduled')
    ->everyMinute()
    ->name('publish-scheduled-artworks')
    ->withoutOverlapping(2)
    ->runInBackground();

Schedule::command('news:publish-scheduled')
    ->everyMinute()
    ->name('publish-scheduled-news')
    ->withoutOverlapping(2)
    ->runInBackground();

Schedule::command('nova-cards:publish-scheduled')
    ->everyMinute()
    ->name('publish-scheduled-nova-cards')
    ->withoutOverlapping(2)
    ->runInBackground();

Schedule::command('collections:sync-lifecycle')
    ->cron('3,13,23,33,43,53 * * * *')
    ->name('sync-collection-lifecycle')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('homepage:warm-guest-cache')
    ->cron('5,15,25,35,45,55 * * * *')
    ->name('warm-homepage-guest-cache')
    ->withoutOverlapping()
    ->runInBackground();

// Safety-net audit for Meilisearch drift on recently touched artworks.
// Scans the last 65 minutes to cover the previous hour plus a small buffer.
Schedule::command('artworks:search-reconcile --repair --reverse --remove-unexpected --limit=1000 --recent-minutes=65')
    ->hourlyAt(28)
    ->name('artworks-search-reconcile-recent')
    ->withoutOverlapping()
    ->runInBackground();

// ── Feed 2.0: Trending Cache Warm-up ─────────────────────────────────────────
// Warm the post trending cache every 2 minutes on odd minutes to avoid :00/:10 pileups.
Schedule::command('posts:warm-trending')
    ->cron('1-59/2 * * * *')
    ->name('warm-post-trending')
    ->withoutOverlapping();

// ── Ranking Engine V2 ──────────────────────────────────────────────────────────
// Recalculate ranking_score + engagement_velocity every 30 minutes.
// Also syncs V2 scores to rank_artwork_scores so list builds benefit.
Schedule::command('nova:recalculate-rankings --sync-rank-scores')
    ->cron('7,37 * * * *')
    ->name('ranking-v2')
    ->withoutOverlapping()
    ->runInBackground();

// ── Rising Engine (Heat / Momentum) ───────────────────────────────────────────
// Snapshot current totals each hour, then recalculate heat every 15 minutes.
Schedule::command('nova:metrics-snapshot-hourly')
    ->hourlyAt(2)
    ->name('metrics-snapshot-hourly')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('nova:recalculate-heat')
    ->cron('9,24,39,54 * * * *')
    ->name('recalculate-heat')
    ->withoutOverlapping()
    ->runInBackground();

// Additional production schedules that must live here because Laravel 11's
// active scheduler in this app is defined in routes/console.php, not Kernel.

// Generate static sitemap XML files that nginx can serve directly without PHP.
// The generate command writes public/sitemap.xml + public/sitemaps/{name}.xml.
Schedule::command('skinbase:sitemaps:generate')
    ->cron('30 10,22 * * *')
    ->name('sitemaps-generate')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('skinbase:sitemaps:publish --sync')
    ->cron('8 */6 * * *')
    ->name('sitemaps-publish')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('skinbase:sitemaps:validate')
    ->dailyAt('04:45')
    ->name('sitemaps-validate')
    ->withoutOverlapping()
    ->runInBackground();

// Keep the old release-pipeline cleanup running so stale release artifacts are pruned.

Schedule::job(new \App\Jobs\Sitemaps\CleanupSitemapReleasesJob())
    ->dailyAt('05:00')
    ->name('sitemaps-cleanup')
    ->withoutOverlapping();

Schedule::command('collections:dispatch-maintenance')
    ->hourlyAt(43)
    ->name('dispatch-collection-maintenance')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::job(new \App\Jobs\RankBuildListsJob())
    ->hourlyAt(15)
    ->name('rank-build-lists')
    ->withoutOverlapping();

Schedule::command('leaderboards:refresh')
    ->hourlyAt(21)
    ->name('leaderboards-refresh')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::job(new \App\Jobs\RebuildTrendingNovaCardsJob())
    ->hourlyAt(25)
    ->name('nova-cards-trending-refresh')
    ->withoutOverlapping();

Schedule::job(new \App\Jobs\RecalculateRisingNovaCardsJob())
    ->cron('12,27,42,57 * * * *')
    ->name('nova-cards-rising-cache-refresh')
    ->withoutOverlapping();

Schedule::command('nova:prune-metric-snapshots --keep-days=7')
    ->dailyAt('04:00')
    ->name('prune-metric-snapshots')
    ->withoutOverlapping();

Schedule::command('skinbase:sync-countries')
    ->monthlyOn(1, '03:40')
    ->name('sync-countries')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('health:tick')
    ->everyMinute()
    ->name('health-scheduler-tick')
    ->withoutOverlapping();

Schedule::command('forum:ai-scan')
    ->hourlyAt(16)
    ->name('forum-ai-scan')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('forum:bot-scan')
    ->hourlyAt(22)
    ->name('forum-bot-scan')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('forum:scan-posts --limit=250')
    ->hourlyAt(17)
    ->name('forum-post-scan')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('forum:firewall-scan')
    ->hourlyAt(40)
    ->name('forum-firewall-scan')
    ->withoutOverlapping()
    ->runInBackground();

Schedule::command('horizon:snapshot')
    ->hourlyAt(45)
    ->name('horizon-snapshot')
    ->withoutOverlapping();
