<?php

declare(strict_types=1);

namespace App\Framework\Queue\Services;

use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\Logging\Logger;
use App\Framework\Queue\ValueObjects\JobMetrics;
use App\Framework\Queue\ValueObjects\QueueMetrics;

/**
 * Mock implementation of JobMetricsManager for demonstration purposes
 */
final readonly class MockJobMetricsManager implements JobMetricsManagerInterface
{
    public function __construct(
        private Logger $logger
    ) {
    }

    public function recordJobMetrics(JobMetrics $metrics): void
    {
        $this->logger->debug('Job metrics recorded (mock)', [
            'job_id' => $metrics->jobId,
            'queue_name' => $metrics->queueName,
            'status' => $metrics->status,
        ]);
    }

    public function getSystemOverview(): array
    {
        return [
            'system_health_score' => 85,
            'total_queues' => 3,
            'healthy_queues' => 2,
            'total_jobs' => 1250,
            'completed_jobs' => 1200,
            'failed_jobs' => 35,
            'pending_jobs' => 10,
            'running_jobs' => 5,
            'overall_success_rate' => 96.0,
            'average_execution_time_ms' => 245,
            'average_memory_usage_mb' => 12.5,
            'queue_metrics' => [
                'emails' => $this->createMockQueueMetrics('emails', 850, 95.2),
                'notifications' => $this->createMockQueueMetrics('notifications', 300, 98.0),
                'reports' => $this->createMockQueueMetrics('reports', 100, 85.0),
            ],
        ];
    }

    public function getQueueMetrics(string $queueName, string $timeWindow): QueueMetrics
    {
        return $this->createMockQueueMetrics($queueName, 500, 94.5);
    }

    public function getJobMetrics(string $jobId): ?JobMetrics
    {
        if ($jobId === 'nonexistent') {
            return null;
        }

        return new JobMetrics(
            jobId: $jobId,
            queueName: 'emails',
            status: 'completed',
            attempts: 1,
            maxAttempts: 3,
            executionTimeMs: 150,
            memoryUsageBytes: 2048000,
            createdAt: '2024-01-15 10:30:00',
            startedAt: '2024-01-15 10:30:01',
            completedAt: '2024-01-15 10:30:02',
            failedAt: null,
            errorMessage: null,
            metadata: ['user_id' => 123, 'template' => 'welcome']
        );
    }

    public function getTopSlowJobs(?string $queueName, int $limit): array
    {
        $jobs = [];
        for ($i = 1; $i <= min($limit, 5); $i++) {
            $jobs[] = new JobMetrics(
                jobId: "slow-job-{$i}",
                queueName: $queueName ?? 'emails',
                status: 'completed',
                attempts: 1,
                maxAttempts: 3,
                executionTimeMs: 1000 + ($i * 200),
                memoryUsageBytes: 1024000 * $i,
                createdAt: '2024-01-15 10:30:00',
                startedAt: '2024-01-15 10:30:01',
                completedAt: '2024-01-15 10:30:02',
                failedAt: null,
                errorMessage: null,
                metadata: []
            );
        }

        return $jobs;
    }

    public function getTopMemoryConsumers(?string $queueName, int $limit): array
    {
        $jobs = [];
        for ($i = 1; $i <= min($limit, 5); $i++) {
            $jobs[] = new JobMetrics(
                jobId: "memory-job-{$i}",
                queueName: $queueName ?? 'reports',
                status: 'completed',
                attempts: 1,
                maxAttempts: 3,
                executionTimeMs: 300,
                memoryUsageBytes: 10485760 * $i, // 10MB, 20MB, etc.
                createdAt: '2024-01-15 10:30:00',
                startedAt: '2024-01-15 10:30:01',
                completedAt: '2024-01-15 10:30:02',
                failedAt: null,
                errorMessage: null,
                metadata: []
            );
        }

        return $jobs;
    }

    public function getFailedJobs(?string $queueName, string $timeWindow): array
    {
        $jobs = [];
        for ($i = 1; $i <= 3; $i++) {
            $jobs[] = new JobMetrics(
                jobId: "failed-job-{$i}",
                queueName: $queueName ?? 'notifications',
                status: 'failed',
                attempts: 3,
                maxAttempts: 3,
                executionTimeMs: 500,
                memoryUsageBytes: 1024000,
                createdAt: '2024-01-15 10:30:00',
                startedAt: '2024-01-15 10:30:01',
                completedAt: null,
                failedAt: '2024-01-15 10:30:10',
                errorMessage: "Connection timeout to external API",
                metadata: []
            );
        }

        return $jobs;
    }

    public function getPerformanceStats(?string $queueName, string $timeWindow): array
    {
        return [
            'total_jobs' => 1000,
            'completed_jobs' => 950,
            'failed_jobs' => 50,
            'success_rate' => 95.0,
            'failure_rate' => 5.0,
            'average_execution_time_ms' => 250.5,
            'min_execution_time_ms' => 50.0,
            'max_execution_time_ms' => 2500.0,
            'average_memory_usage_mb' => 15.2,
            'min_memory_usage_bytes' => 512000,
            'max_memory_usage_bytes' => 52428800,
            'average_attempts' => 1.1,
        ];
    }

    public function getThroughputStats(?string $queueName, string $timeWindow): array
    {
        $hourlyData = [];
        for ($hour = 0; $hour < 24; $hour++) {
            $hourlyData[] = [
                'hour' => sprintf('2024-01-15 %02d:00:00', $hour),
                'jobs_completed' => rand(10, 50),
            ];
        }

        return [
            'total_completed' => 800,
            'average_throughput_per_hour' => 33.3,
            'hourly_breakdown' => $hourlyData,
        ];
    }

    public function cleanupOldMetrics(int $olderThanDays): int
    {
        // Simulate cleanup
        return rand(50, 200);
    }

    private function createMockQueueMetrics(string $queueName, int $totalJobs, float $successRate): QueueMetrics
    {
        $completedJobs = (int) ($totalJobs * ($successRate / 100));
        $failedJobs = $totalJobs - $completedJobs;

        return new QueueMetrics(
            queueName: $queueName,
            totalJobs: $totalJobs,
            completedJobs: $completedJobs,
            failedJobs: $failedJobs,
            pendingJobs: rand(5, 20),
            runningJobs: rand(0, 5),
            deadLetterJobs: rand(0, 3),
            successRate: new Percentage($successRate),
            averageExecutionTimeMs: rand(100, 500),
            averageMemoryUsageMB: rand(5, 25),
            throughputJobsPerHour: rand(50, 200),
            measuredAt: date('Y-m-d H:i:s')
        );
    }
}
