<?php

declare(strict_types=1);

namespace App\Console\Commands\Enhance;

use App\Models\EnhanceJob;
use Illuminate\Console\Command;

final class EnhanceHealthCommand extends Command
{
    protected $signature = 'enhance:health {--json : Output machine-readable JSON}';

    protected $description = 'Report operational health and lifecycle metrics for Enhance jobs.';

    public function handle(): int
    {
        $payload = $this->payload();

        if ((bool) $this->option('json')) {
            $this->line(json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

            return self::SUCCESS;
        }

        $this->info('Enhance health');
        $this->newLine();

        $this->table(['Metric', 'Value'], [
            ['Configured engine', $payload['engine']],
            ['Configured queue', $payload['queue']],
            ['Worker URL configured', $payload['worker_configured'] ? 'yes' : 'no'],
            ['Storage disk', $payload['storage_disk']],
            ['Total jobs', $payload['counts']['total']],
            ['Pending jobs', $payload['counts']['pending']],
            ['Queued jobs', $payload['counts']['queued']],
            ['Processing jobs', $payload['counts']['processing']],
            ['Completed jobs', $payload['counts']['completed']],
            ['Failed jobs', $payload['counts']['failed']],
            ['Cancelled jobs', $payload['counts']['cancelled']],
            ['Expired jobs', $payload['counts']['expired']],
            ['Stuck queued jobs', $payload['health']['stuck_queued']],
            ['Stuck processing jobs', $payload['health']['stuck_processing']],
            ['Jobs created today', $payload['today']['created']],
            ['Jobs completed today', $payload['today']['completed']],
            ['Jobs failed today', $payload['today']['failed']],
            ['Average processing time today', $payload['today']['average_processing_seconds'] ?? '—'],
        ]);

        return self::SUCCESS;
    }

    private function payload(): array
    {
        $todayStart = now()->startOfDay();
        $todayEnd = now()->endOfDay();
        $stuckQueuedCutoff = now()->subMinutes((int) config('enhance.health.stuck_queued_after_minutes', 60));
        $stuckProcessingCutoff = now()->subMinutes((int) config('enhance.health.stuck_processing_after_minutes', 30));

        $counts = [
            'total' => EnhanceJob::query()->count(),
            'pending' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_PENDING)->count(),
            'queued' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_QUEUED)->count(),
            'processing' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_PROCESSING)->count(),
            'completed' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_COMPLETED)->count(),
            'failed' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_FAILED)->count(),
            'cancelled' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_CANCELLED)->count(),
            'expired' => EnhanceJob::query()->where('status', EnhanceJob::STATUS_EXPIRED)->count(),
        ];

        return [
            'engine' => (string) config('enhance.default_engine', EnhanceJob::ENGINE_STUB),
            'queue' => (string) config('enhance.queue', 'default'),
            'worker_configured' => trim((string) config('enhance.external_worker.url', '')) !== '',
            'storage_disk' => (string) config('enhance.disk', 'public'),
            'counts' => $counts,
            'health' => [
                'stuck_queued' => EnhanceJob::query()
                    ->where('status', EnhanceJob::STATUS_QUEUED)
                    ->whereNotNull('queued_at')
                    ->where('queued_at', '<=', $stuckQueuedCutoff)
                    ->count(),
                'stuck_processing' => EnhanceJob::query()
                    ->where('status', EnhanceJob::STATUS_PROCESSING)
                    ->whereNotNull('started_at')
                    ->where('started_at', '<=', $stuckProcessingCutoff)
                    ->count(),
            ],
            'today' => [
                'created' => EnhanceJob::query()->whereBetween('created_at', [$todayStart, $todayEnd])->count(),
                'completed' => EnhanceJob::query()
                    ->where('status', EnhanceJob::STATUS_COMPLETED)
                    ->whereBetween('finished_at', [$todayStart, $todayEnd])
                    ->count(),
                'failed' => EnhanceJob::query()
                    ->where('status', EnhanceJob::STATUS_FAILED)
                    ->whereBetween('finished_at', [$todayStart, $todayEnd])
                    ->count(),
                'average_processing_seconds' => ($average = EnhanceJob::query()
                    ->whereNotNull('processing_seconds')
                    ->whereBetween('finished_at', [$todayStart, $todayEnd])
                    ->avg('processing_seconds')) !== null
                    ? round((float) $average, 2)
                    : null,
            ],
        ];
    }
}