<?php

namespace App\core;

class Router
{
    private array $routes = [];

    public function get(string $path, array $handler): self
    {
        $this->routes['GET'][$path] = $handler;
        return $this;
    }

    public function post(string $path, array $handler): self
    {
        $this->routes['POST'][$path] = $handler;
        return $this;
    }

    public function dispatch(string $method, string $uri): void
    {
        $uri = parse_url($uri, PHP_URL_PATH);
        $uri = rtrim($uri, '/') ?: '/';

        // Ruta exacta
        if (isset($this->routes[$method][$uri])) {
            [$controllerClass, $action] = $this->routes[$method][$uri];
            $this->callAction($controllerClass, $action, []);
            return;
        }

        // Rutas con parametros: /noticia/{slug}
        foreach ($this->routes[$method] ?? [] as $route => $handler) {
            $pattern = preg_replace('#\{(\w+)\}#', '(?P<$1>[^/]+)', $route);
            $pattern = '#^' . $pattern . '$#';

            if (preg_match($pattern, $uri, $matches)) {
                $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
                [$controllerClass, $action] = $handler;
                $this->callAction($controllerClass, $action, array_values($params));
                return;
            }
        }

        http_response_code(404);
        require __DIR__ . '/../Views/errors/404.php';
    }

    private function callAction(string $controllerClass, string $action, array $params): void
    {
        if (!class_exists($controllerClass)) {
            throw new \RuntimeException("Controller {$controllerClass} no encontrado.");
        }

        $controller = new $controllerClass();
        if (!method_exists($controller, $action)) {
            throw new \RuntimeException("Metodo {$action} no encontrado en {$controllerClass}.");
        }

        call_user_func_array([$controller, $action], $params);
    }
}
