<?php

namespace App\Core;

class Router {
    private $routes = [];

    public function get($path, $handler) {
        $this->add('GET', $path, $handler);
    }

    public function post($path, $handler) {
        $this->add('POST', $path, $handler);
    }

    private function add($method, $path, $handler) {
        $path = preg_replace('/:([^\/]+)/', '(?P<$1>[^/]+)', $path);
        $path = '#^' . $path . '$#';
        $this->routes[] = [
            'method' => $method,
            'path' => $path,
            'handler' => $handler
        ];
    }

    public function dispatch() {
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        $method = $_SERVER['REQUEST_METHOD'];

        foreach ($this->routes as $route) {
            if ($route['method'] === $method && preg_match($route['path'], $uri, $matches)) {
                $handler = $route['handler'];
                $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);

                if (is_string($handler) && strpos($handler, '@') !== false) {
                    [$controllerName, $methodName] = explode('@', $handler);
                    $controllerClass = "App\\Controllers\\" . $controllerName;
                    $controller = new $controllerClass();
                    return $controller->$methodName($params);
                }

                if (is_callable($handler)) {
                    return call_user_func_array($handler, [$params]);
                }
            }
        }

        // Handle 404
        if (ob_get_level() > 0) {
            ob_clean();
        }
        header("HTTP/1.0 404 Not Found");
        require __DIR__ . "/../../views/404.php";
    }
}
