<?php

declare(strict_types=1);

namespace App\Framework\Router;

use App\Framework\Core\DynamicRoute;
use App\Framework\DI\DefaultContainer;
use App\Framework\Http\Response;
use App\Framework\Http\Responses\NotFound;
use App\Framework\Router\Result\ContentNegotiationResult;

final readonly class RouteDispatcher
{
    public function __construct(
        private DefaultContainer   $container,
        private ParameterProcessor $parameterProcessor
    ) {}

    /**
     * Verarbeitet eine Route und führt den entsprechenden Controller-Action aus
     */
    public function dispatch(RouteContext $routeContext): ActionResult|Response
    {
        $routeMatch = $routeContext->match;

        if ($routeMatch->isMatch()) {
            return $this->executeController($routeMatch);
        }

        return new NotFound();
    }

    /**
     * Führt die Controller-Action mit den aufbereiteten Parametern aus
     */
    private function executeController(RouteMatch $routeMatch): ActionResult|Response
    {
        $controller = $routeMatch->route->controller;
        $action = $routeMatch->route->action;
        $params = $routeMatch->route->parameters;

        $queryParams = [];

        if($routeMatch->route instanceof DynamicRoute) {
            $queryParams = $routeMatch->route->paramValues;
        }

        $preparedParams = $this->parameterProcessor->prepareParameters($params, $queryParams);

        $controllerInstance = $this->container->get($controller);
        $result = $controllerInstance->$action(...$preparedParams);

        if ($result instanceof Response || $result instanceof ActionResult) {
            return $result;
        }

        // Wenn kein gültiges Result zurückgegeben wird
        return new NotFound('Ungültige Antwort vom Controller');
    }
}
