<?php
// CoreFlux/core/Router.php

namespace Core;

use Core\Middleware\MiddlewareInterface;

class Router
{
    public $routes = [];
    protected $globalMiddlewares = [];
    protected $groupStack = []; // <-- track active groups

    public function get(string $pattern, string $action, array $middleware = [])
    {
        $this->addRoute('GET', $pattern, $action, $middleware);
    }

    public function post(string $pattern, string $action, array $middleware = [])
    {
        $this->addRoute('POST', $pattern, $action, $middleware);
    }

    public function put(string $pattern, string $action, array $middleware = [])
    {
        $this->addRoute('PUT', $pattern, $action, $middleware);
    }

    public function delete(string $pattern, string $action, array $middleware = [])
    {
        $this->addRoute('DELETE', $pattern, $action, $middleware);
    }

    protected function addRoute(string $method, string $pattern, string $action, array $middleware = [])
    {
        $prefix = '';
        $groupMiddlewares = [];

        foreach ($this->groupStack as $group) {
            $prefix .= $group['prefix'] ?? '';
            $groupMiddlewares = array_merge($groupMiddlewares, $group['middleware'] ?? []);
        }

        // Normalize slashes
        $fullPattern = rtrim($prefix, '/') . '/' . ltrim($pattern, '/');
        if ($fullPattern !== '/' && substr($fullPattern, -1) === '/') {
            $fullPattern = rtrim($fullPattern, '/');
        }

        $fullMiddleware = array_merge($groupMiddlewares, $middleware);

        $this->routes[$method][$fullPattern] = [
            'action' => $action,
            'middleware' => $fullMiddleware
        ];
    }


    public function middleware(MiddlewareInterface $middleware)
    {
        $this->globalMiddlewares[] = $middleware;
    }

    public function group(array $attributes, callable $callback)
    {
        $this->groupStack[] = $attributes;

        $callback($this); // Add routes inside the group

        array_pop($this->groupStack); // Remove group after finished
    }

    public function loadRoutes(string $routesFile)
    {
        if (file_exists($routesFile)) {
            $router = $this;
            require_once $routesFile;
        } else {
            error_log("Route file not found: " . $routesFile);
        }
    }

    public function dispatch(string $uri, string $method): ?array
    {
        $uri = parse_url($uri, PHP_URL_PATH); // remove query strings
        $uri = rtrim($uri, '/');              // remove trailing slash
        if ($uri === '') $uri = '/';          // root fix

        $method = strtoupper($method);

        if (!isset($this->routes[$method])) {
            return null;
        }

        foreach ($this->routes[$method] as $routePattern => $data) {
            $action = $data['action'];
            $middlewares = $data['middleware'];

            $regexPattern = '#^' . preg_replace_callback(
                '#\{([a-zA-Z0-9_]+)(?::([^}]+))?\}#',
                function ($matches) {
                    $param = $matches[1];
                    // If custom regex provided, use it as-is (don't escape)
                    if (isset($matches[2])) {
                        return "(?P<{$param}>{$matches[2]})";
                    }
                    // Default regex (no slash) 
                    return "(?P<{$param}>[a-zA-Z0-9_\-]+)";
                },
                $routePattern
            ) . '$#';



            if (preg_match($regexPattern, $uri, $matches)) {
                list($controllerName, $methodName) = explode('@', $action);

                $params = [];
                foreach ($matches as $key => $value) {
                    if (is_string($key)) {
                        $params[$key] = $value;
                    }
                }

                $fullControllerClass = 'App\\Controllers\\' . $controllerName;
                if (strpos($controllerName, 'Api\\') === 0) {
                    $fullControllerClass = 'App\\Controllers\\' . $controllerName;
                }

                // --- Run global middlewares ---
                foreach ($this->globalMiddlewares as $middleware) {
                    $middleware->handle($uri, $method, $params);
                }

                // --- Run route-specific middlewares ---
                foreach ($middlewares as $middleware) {
                    if ($middleware instanceof MiddlewareInterface) {
                        $middleware->handle($uri, $method, $params);
                    }
                }

                return [$fullControllerClass, $methodName, $params];
            }
        }

        return null;
    }
}
