<?php

namespace App\Router;
use App\Router\Request\IRequest;
/**
 * Router class to manage a collection of routes in the application.
 * It provides functionalities to add routes and check if a given URL matches any of the defined routes.
 */
class Router {

    /**
     * The base path for routing.
     *
     * @var string
     */
    private string $path;

    /**
     * Collection of routes.
     *
     * @var \AltoRouter
     */
    private \AltoRouter $routes;

    /**
     * Supported HTTP verbs.
     *
     * @var string[]
     */
    public static $verbs = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'];

    /**
     * Constructor for Router.
     *
     * @param string $path The base path for the router.
     */
    public function __construct(string $path = "/PHP/project/index.php") {
        $this->path = $path;
        $this->routes = new \AltoRouter();
    }
    
    /**
     * Adds a new Route to the collection.
     *
     * @param string $method The HTTP method.
     * @param Route $route The route object.
     * @throws \InvalidArgumentException If method is not supported.
     */
    public function add(string $method, Route $route) {
        if (!in_array($method, self::$verbs)) {
            throw new \InvalidArgumentException("Method not supported");
        }
        $this->routes->map($method, $route->getPath(), $route->getCallable(), $route->getName());
    }
    
    /**
     * Adds a route for a controller action.
     *
     * @param string $method The HTTP method.
     * @param string $path The path for the route.
     * @param mixed $controller The controller object.
     * @param string $action The action method in the controller.
     * @param string $name (Optional) The name of the route.
     * @throws \InvalidArgumentException If method is not supported.
     */
    public function addControllerRoute(string $method, string $path, $controller, string $action, string $name = '') {
        if (!in_array($method, self::$verbs)) {
            throw new \InvalidArgumentException("Method not supported");
        }
        $this->routes->map($method, $path, [$controller, $action], $name);
    }

    // TODO: Implement the extractParams method.
    // public function extractParams(string $path) {}

    /**
     * Adds a GET route.
     *
     * @param string $path The path for the route.
     * @param callable $callable The callback function.
     * @param string $name The name of the route.
     */
    public function get(string $path, callable $callable, $name) {
        $this->routes->map('GET', $path, $callable, $name);
    }

    // Similar methods for post, put, etc. can be added here.

    /**
     * Checks if the request can be processed.
     *
     * @param IRequest $request The request object.
     * @return array|null The matched route or null if no match.
     */
    public function match(IRequest $request): ?array {
        return $this->routes->match($request->getRequestUri(), $request->getMethod()) ?: null;
    }

    /**
     * Returns all routes.
     *
     * @return array The array of routes.
     */
    public function getRoutes() {
        return []; // TODO: Implement the actual logic to return routes.
    }


    public function generate (string $routeName, array $params = array()): string
    {
        return $this->routes->generate($routeName,$params);
    }

}

?>
