<?php

declare(strict_types=1);

namespace App\Application\Admin;

use App\Framework\Attributes\Route;
use App\Framework\Deployment\Pipeline\Services\PipelineHistoryService;
use App\Framework\Deployment\Pipeline\ValueObjects\DeploymentEnvironment;
use App\Framework\Deployment\Pipeline\ValueObjects\PipelineStatus;
use App\Framework\Http\Method;
use App\Framework\Meta\MetaData;
use App\Framework\Router\Result\ViewResult;
use App\Framework\Core\ValueObjects\Duration;

/**
 * Deployment Pipeline Dashboard Controller
 *
 * Provides comprehensive deployment pipeline monitoring:
 * - Pipeline execution history
 * - Deployment statistics and success rates
 * - Environment-specific metrics
 * - Recent deployments overview
 */
final readonly class DeploymentDashboardController
{
    public function __construct(
        private PipelineHistoryService $historyService
    ) {}

    #[Route(path: '/admin/deployment/dashboard', method: Method::GET)]
    public function dashboard(): ViewResult
    {
        // Get overall statistics
        $stats = $this->historyService->getStatistics();

        // Get recent deployments (last 20)
        $recentDeployments = $this->historyService->getRecent(limit: 20);

        // Get failed deployments (last 10)
        $failedDeployments = $this->historyService->getByStatus(
            status: PipelineStatus::FAILED,
            limit: 10
        );

        // Get environment-specific stats
        $productionStats = $this->historyService->getStatistics(
            environment: DeploymentEnvironment::PRODUCTION
        );
        $stagingStats = $this->historyService->getStatistics(
            environment: DeploymentEnvironment::STAGING
        );

        return new ViewResult(
            template: 'deployment-dashboard',
            metaData: MetaData::create('Deployment Pipeline Dashboard'),
            data: [
                'pageTitle' => 'Deployment Pipeline Dashboard',
                'pageDescription' => 'Monitor deployment pipeline executions and statistics',

                // Overall statistics
                'totalDeployments' => $stats['total_deployments'],
                'successfulDeployments' => $stats['successful'],
                'failedDeployments' => $stats['failed'],
                'rolledBackDeployments' => $stats['rolled_back'],
                'successRate' => $stats['success_rate'],
                'averageDurationFormatted' => Duration::fromMilliseconds($stats['average_duration_ms'])->toHumanReadable(),

                // Environment-specific statistics
                'productionStats' => $productionStats,
                'stagingStats' => $stagingStats,

                // Recent deployments list
                'recentDeployments' => array_map(
                    fn($entry) => $this->formatDeploymentEntry($entry),
                    $recentDeployments
                ),

                // Failed deployments list
                'failedDeployments' => array_map(
                    fn($entry) => $this->formatDeploymentEntry($entry),
                    $failedDeployments
                ),
            ]
        );
    }

    /**
     * Format deployment entry for display
     */
    private function formatDeploymentEntry($entry): array
    {
        return [
            'pipelineId' => $entry->pipelineId->value,
            'environment' => $entry->environment->value,
            'status' => $entry->status->value,
            'statusBadgeClass' => $this->getStatusBadgeClass($entry->status),
            'durationFormatted' => $entry->totalDuration->toHumanReadable(),
            'stageCount' => $entry->getStageCount(),
            'successRate' => round($entry->getSuccessRate(), 1),
            'startedAt' => $entry->startedAt?->format('Y-m-d H:i:s'),
            'completedAt' => $entry->completedAt?->format('Y-m-d H:i:s'),
            'error' => $entry->error,
            'wasRolledBack' => $entry->wasRolledBack,
            'failedStage' => $entry->failedStage?->value,
        ];
    }

    /**
     * Get CSS class for status badge
     */
    private function getStatusBadgeClass(PipelineStatus $status): string
    {
        return match ($status) {
            PipelineStatus::SUCCESS => 'admin-badge--success',
            PipelineStatus::FAILED => 'admin-badge--danger',
            PipelineStatus::ROLLED_BACK => 'admin-badge--warning',
            PipelineStatus::RUNNING => 'admin-badge--info',
        };
    }
}
