<?php

declare(strict_types=1);

namespace App\Application\Admin\Development;

use App\Application\Admin\Service\AdminLayoutProcessor;
use App\Framework\Attributes\Route;
use App\Framework\Auth\Auth;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Meta\MetaData;
use App\Framework\Router\Result\ViewResult;

final readonly class RoutesController
{
    public function __construct(
        private DiscoveryRegistry $processedResults,
        private AdminLayoutProcessor $layoutProcessor,
    ) {
    }

    #[Auth]
    #[Route('/admin/dev/routes', name: 'admin.dev.routes')]
    public function show(): ViewResult
    {
        // Get routes from the AttributeRegistry (Routes are stored as Route::class attributes)
        $routeMappings = $this->processedResults->attributes->get(Route::class);

        // Convert DiscoveredAttribute objects to display format
        $routes = [];
        $routeStats = [
            'admin_routes' => 0,
            'api_routes' => 0,
            'get_routes' => 0,
            'post_routes' => 0,
            'put_routes' => 0,
            'delete_routes' => 0,
            'protected_routes' => 0,
            'public_routes' => 0,
        ];

        foreach ($routeMappings as $discoveredAttribute) {
            $routeData = $discoveredAttribute->additionalData;
            $path = $routeData['path'] ?? '';
            $method = $routeData['method'] ?? 'GET';


            // Convert Method enum to string if needed
            if (is_object($method) && method_exists($method, 'value')) {
                $method = $method->value; // For PHP enums
            } elseif (is_object($method) && isset($method->name)) {
                $method = $method->name; // For older enum implementations
            }

            // Count route statistics
            if (str_starts_with($path, '/admin')) {
                $routeStats['admin_routes']++;
            }
            if (str_starts_with($path, '/api')) {
                $routeStats['api_routes']++;
            }

            $methodLower = strtolower($method);
            if ($methodLower === 'get') {
                $routeStats['get_routes']++;
            } elseif ($methodLower === 'post') {
                $routeStats['post_routes']++;
            } elseif (in_array($methodLower, ['put', 'patch'])) {
                $routeStats['put_routes']++;
            } elseif ($methodLower === 'delete') {
                $routeStats['delete_routes']++;
            }

            // Check if route has Auth attribute (simplified check)
            $hasAuth = str_contains($discoveredAttribute->className->getFullyQualified(), 'Admin') ||
                      str_contains($path, '/admin');

            if ($hasAuth) {
                $routeStats['protected_routes']++;
            } else {
                $routeStats['public_routes']++;
            }

            $routes[] = [
                'path' => $path,
                'method' => $method,
                'controller' => $discoveredAttribute->className->getShortName(),
                'handler' => $discoveredAttribute->methodName?->toString() ?? '',
                'name' => $routeData['name'] ?? '',
                'is_protected' => $hasAuth,
            ];
        }

        // Sort routes by path for a better overview
        usort($routes, fn ($a, $b) => strcmp($a['path'], $b['path']));

        $data = [
            'title' => 'Routes Overview',
            'total_routes' => count($routes),
            'admin_routes_count' => $routeStats['admin_routes'],
            'api_routes_count' => $routeStats['api_routes'],
            'get_routes_count' => $routeStats['get_routes'],
            'post_routes_count' => $routeStats['post_routes'],
            'put_routes_count' => $routeStats['put_routes'],
            'delete_routes_count' => $routeStats['delete_routes'],
            'protected_routes_count' => $routeStats['protected_routes'],
            'public_routes_count' => $routeStats['public_routes'],
            'routes' => $routes,
        ];

        $finalData = $this->layoutProcessor->processLayoutFromArray($data);

        return new ViewResult(
            template: 'routes-overview',
            metaData: new MetaData('Routes Overview', 'System Routes Overview'),
            data: $finalData
        );
    }
}
