<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Jobs\Sitemaps\PublishSitemapReleaseJob;
use App\Services\Sitemaps\SitemapPublishService;
use Illuminate\Console\Command;

final class PublishSitemapsCommand extends Command
{
    protected $signature = 'skinbase:sitemaps:publish
        {--release= : Publish an existing built release}
        {--queue : Dispatch publish flow to the queue}
        {--sync : Run publish synchronously (default)}';

    protected $description = 'Build, validate, and atomically publish a sitemap release.';

    public function handle(SitemapPublishService $publish): int
    {
        $releaseId = $this->option('release');

        if ((bool) $this->option('queue')) {
            PublishSitemapReleaseJob::dispatch(is_string($releaseId) && $releaseId !== '' ? $releaseId : null);
            $this->info('Queued sitemap publish flow' . (is_string($releaseId) && $releaseId !== '' ? ' for release [' . $releaseId . '].' : '.'));

            return self::SUCCESS;
        }

        $startedAt = microtime(true);
        $this->line('<fg=cyan>Building sitemap release...</>');

        try {
            $manifest = $publish->publish(is_string($releaseId) && $releaseId !== '' ? $releaseId : null);
        } catch (\Throwable $exception) {
            $this->error($exception->getMessage());

            return self::FAILURE;
        }

        $elapsed = microtime(true) - $startedAt;

        // Per-family table (shown with -v or higher)
        if ($this->output->isVerbose()) {
            $rows = [];
            foreach ((array) data_get($manifest, 'families', []) as $family => $info) {
                $rows[] = [
                    $family,
                    (int) data_get($info, 'url_count', 0),
                    (int) data_get($info, 'shard_count', 0),
                    count((array) data_get($info, 'documents', [])),
                    (string) data_get($info, 'type', 'urlset'),
                ];
            }
            $this->table(['Family', 'URLs', 'Shards', 'Docs', 'Type'], $rows);
        }

        // Validation detail (shown with -vv or higher)
        if ($this->output->isVeryVerbose()) {
            $validation = (array) data_get($manifest, 'validation', []);
            $checks = (array) data_get($validation, 'checks', []);
            if ($checks !== []) {
                $this->line('<fg=yellow>Validation checks:</>');
                $checkRows = [];
                foreach ($checks as $check => $result) {
                    $ok = (bool) data_get($result, 'ok', true);
                    $checkRows[] = [
                        $check,
                        $ok ? '<fg=green>OK</>' : '<fg=red>FAIL</>',
                        (string) data_get($result, 'message', ''),
                    ];
                }
                $this->table(['Check', 'Status', 'Message'], $checkRows);
            }
        }

        // Static publish result
        $staticResult = (array) data_get($manifest, 'static_published', []);
        if ($staticResult !== [] && $this->output->isVerbose()) {
            $this->line(sprintf(
                '<fg=cyan>Static files written to public/:</>  written=%d  skipped=%d',
                (int) data_get($staticResult, 'written', 0),
                (int) data_get($staticResult, 'skipped', 0),
            ));
        }

        $this->info(sprintf(
            'Published sitemap release [%s] — %d families, %d documents, %d URLs  (%.2fs)',
            (string) $manifest['release_id'],
            (int) data_get($manifest, 'totals.families', 0),
            (int) data_get($manifest, 'totals.documents', 0),
            (int) data_get($manifest, 'totals.urls', 0),
            $elapsed,
        ));

        return self::SUCCESS;
    }
}