<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\Dashboard;

use App\Framework\LiveComponents\Attributes\Action;
use App\Framework\LiveComponents\Attributes\LiveComponent;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\LiveComponents\Contracts\Pollable;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\ComponentRenderData;
use App\Framework\Queue\Queue;
use App\Framework\Queue\Services\JobMetricsManagerInterface;

/**
 * Queue Statistics LiveComponent
 *
 * Displays real-time queue metrics:
 * - Current queue size
 * - Total jobs processed
 * - Success/failure counts
 * - Success rate percentage
 * - Average execution time
 *
 * Polls every 5 seconds for frequent updates.
 */
#[LiveComponent('queue-stats')]
final readonly class QueueStatsComponent implements LiveComponentContract, Pollable
{
    public function __construct(
        public ComponentId $id,
        public QueueStatsState $state,
        private Queue $queue,
        private JobMetricsManagerInterface $metricsManager
    ) {}

    public function getRenderData(): ComponentRenderData
    {
        // Initial poll if state is empty (lastUpdated is empty string)
        $state = $this->state->lastUpdated === ''
            ? $this->poll()
            : $this->state;

        return new ComponentRenderData(
            templatePath: 'livecomponent-queue-stats',
            data: [
                // LiveComponent integration
                'componentId' => $this->id->toString(),
                'stateJson' => json_encode($state->toArray()),
                'pollInterval' => $this->getPollInterval(),

                // Component data
                'currentQueueSize' => $state->currentQueueSize,
                'totalJobs' => $state->totalJobs,
                'successfulJobs' => $state->successfulJobs,
                'failedJobs' => $state->failedJobs,
                'successRate' => $state->successRate,
                'avgExecutionTimeMs' => $state->avgExecutionTimeMs,
                'lastUpdated' => $state->lastUpdated,
            ]
        );
    }

    #[Action]
    public function poll(): QueueStatsState
    {
        // Get current queue stats
        $stats = $this->queue->getStats();
        $queueSize = $stats['total_size'] ?? 0;

        // Get metrics from last hour
        $metrics = $this->metricsManager->getAllQueueMetrics('1 hour');

        $totalJobs = 0;
        $successfulJobs = 0;
        $failedJobs = 0;
        $totalExecutionTime = 0;

        foreach ($metrics as $queueMetrics) {
            $totalJobs += $queueMetrics->totalJobs;
            $successfulJobs += $queueMetrics->successfulJobs;
            $failedJobs += $queueMetrics->failedJobs;
            $totalExecutionTime += $queueMetrics->totalExecutionTime;
        }

        $avgExecutionTime = $totalJobs > 0
            ? $totalExecutionTime / $totalJobs
            : 0.0;

        return $this->state->withStats(
            queueSize: $queueSize,
            total: $totalJobs,
            successful: $successfulJobs,
            failed: $failedJobs,
            avgExecutionTime: $avgExecutionTime
        );
    }

    public function getPollInterval(): int
    {
        return 5000; // Poll every 5 seconds for real-time updates
    }
}
