<?php

namespace Core;

class Router {
    protected array $routes = [];
    protected array $groupMiddlewares = [];

    public function get(string $route, string $controllerAction, array $middlewares = []) {
        $this->routes['GET'][$route] = [
            'controller' => $controllerAction,
            'middlewares' => array_merge($this->groupMiddlewares, $middlewares)
        ];
    }

    public function post(string $route, string $controllerAction, array $middlewares = []) {
        $this->routes['POST'][$route] = [
            'controller' => $controllerAction,
            'middlewares' => array_merge($this->groupMiddlewares, $middlewares)
        ];
    }

    public function put(string $route, string $controllerAction, array $middlewares = []) {
        $this->routes['PUT'][$route] = [
            'controller' => $controllerAction,
            'middlewares' => array_merge($this->groupMiddlewares, $middlewares)
        ];
    }

    public function delete(string $route, string $controllerAction, array $middlewares = []) {
        $this->routes['DELETE'][$route] = [
            'controller' => $controllerAction,
            'middlewares' => array_merge($this->groupMiddlewares, $middlewares)
        ];
    }

    public function group(array $middlewares, callable $callback) {
        $previousMiddlewares = $this->groupMiddlewares;
        $this->groupMiddlewares = array_merge($this->groupMiddlewares, $middlewares);

        $callback($this);

        $this->groupMiddlewares = $previousMiddlewares;
    }

    public function dispatch(string $url) {
        $method = $_SERVER['REQUEST_METHOD'];

        if ($method === 'POST' && isset($_POST['_method'])) {
            $method = strtoupper($_POST['_method']);
        }

        $url = trim(parse_url($url, PHP_URL_PATH), '/');

        foreach ($this->routes[$method] as $route => $routeData) {

            $routePattern = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '([0-9]+)', $route);
            $routePattern = str_replace('/', '\/', $routePattern);
            
            if (preg_match("/^$routePattern$/", $url, $matches)) {
                array_shift($matches);

                foreach ($routeData['middlewares'] as $middleware) {
                    if (class_exists($middleware)) {
                        (new $middleware())->handle();
                    }
                }

                list($controller, $action) = explode('@', $routeData['controller']);
                $controller = "App\\Controllers\\$controller";

                if (class_exists($controller)) {
                    $controllerInstance = new $controller();
                    if (method_exists($controllerInstance, $action)) {
                        $controllerInstance->$action(...$matches);
                        return;
                    } else {
                        die("Error: Método $action no encontrado en $controller");
                    }
                } else {
                    die("Error: Controlador $controller no encontrado");
                }
            }
        }

        http_response_code(404);
        echo "404 - Página no encontrada";
    }
}

