<?php

namespace App\Console\Commands;

use App\Services\Artworks\ArtworkPublicationService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

/**
 * PublishScheduledArtworksCommand
 *
 * Runs every minute (via Kernel schedule).
 * Finds artworks with:
 *   - artwork_status = 'scheduled'
 *   - publish_at <= now() (UTC)
 *   - is_approved = true (respect moderation gate)
 *
 * Publishes each one:
 *   - sets is_public = true
 *   - sets published_at = now()
 *   - sets artwork_status = 'published'
 *   - dispatches Meilisearch reindex (via Scout)
 *   - records activity event
 *
 * Safe to run concurrently (DB row lock prevents double-publish).
 */
class PublishScheduledArtworksCommand extends Command
{
    protected $signature = 'artworks:publish-scheduled
                            {--dry-run : List candidate artworks without publishing}
                            {--limit=100 : Max artworks to process per run}';

    protected $description = 'Publish scheduled artworks whose publish_at datetime has passed.';

    public function __construct(
        private readonly ArtworkPublicationService $publicationService,
    ) {
        parent::__construct();
    }

    public function handle(): int
    {
        $dryRun = (bool) $this->option('dry-run');
        $limit  = (int) $this->option('limit');

        $now = now()->utc();

        $result = $this->publicationService->publishDueScheduled($limit, $now);
        $candidates = $result['candidates'];

        if ($candidates->isEmpty()) {
            $this->line('No scheduled artworks due for publishing.');
            return self::SUCCESS;
        }

        $this->info("Found {$candidates->count()} artwork(s) to publish." . ($dryRun ? ' [DRY RUN]' : ''));

        $published = 0;
        $errors    = 0;

        foreach ($candidates as $candidate) {
            if ($dryRun) {
                $this->line("  [dry-run] Would publish artwork #{$candidate->id}: \"{$candidate->title}\"");
                continue;
            }

            try {
                $artwork = $this->publicationService->publishIfDue($candidate, $now);

                if ($artwork->artwork_status === 'published') {
                    $published++;
                    $this->line("  Published artwork #{$artwork->id}: \"{$artwork->title}\"");
                }
            } catch (\Throwable $e) {
                $errors++;
                Log::error("PublishScheduledArtworksCommand: failed to publish artwork #{$candidate->id}: {$e->getMessage()}");
                $this->error("  Failed to publish #{$candidate->id}: {$e->getMessage()}");
            }
        }

        if (! $dryRun) {
            $this->info("Done. Published: {$published}, Errors: {$errors}.");
        }

        return $errors > 0 ? self::FAILURE : self::SUCCESS;
    }
}
