<?php

declare(strict_types=1);

namespace System\Routing;

use RuntimeException;
use System\Application\Container;
use System\Http\Request;
use System\Http\Response;

final class Dispatcher
{
    public function __construct(
        private readonly Container $container
    ) {
    }

    public function dispatch(
        Router $router,
        Request $request,
        Response $response
    ): void {

        $route = $router->match(
            $request->method(),
            $request->uri()
        );

        if ($route === null) {
            $response->notFound();
        }

        [$controller, $method] = explode('@', $route->action);

        $class = $this->resolveController($controller);

        $instance = $this->container->make($class);

        if (!method_exists($instance, $method)) {
            throw new RuntimeException(
                "Method {$method} not found."
            );
        }

        $instance->$method();
    }

    private function resolveController(
        string $controller
    ): string {

        $locations = [

            "App\\Modules\\Administration\\Controllers\\{$controller}",

            "App\\Controllers\\{$controller}",

        ];

        foreach ($locations as $class) {

            if (class_exists($class)) {

                return $class;

            }

        }

        throw new RuntimeException(
            "Controller {$controller} not found."
        );
    }
}