<?php
namespace Gestoreasy\Core\Routing;

use Gestoreasy\Core\Http\Request;
use Gestoreasy\Core\Http\Response;

class Router {
    private array $routes = [];

    public function add(string $method, string $path, callable $handler, array $middlewares = []): void {
        $this->routes[strtoupper($method)][] = [$path, $handler, $middlewares];
    }
    public function get(string $path, callable $handler, array $middlewares = []): void { $this->add('GET', $path, $handler, $middlewares); }
    public function post(string $path, callable $handler, array $middlewares = []): void { $this->add('POST', $path, $handler, $middlewares); }
    public function put(string $path, callable $handler, array $middlewares = []): void { $this->add('PUT', $path, $handler, $middlewares); }
    public function patch(string $path, callable $handler, array $middlewares = []): void { $this->add('PATCH', $path, $handler, $middlewares); }
    public function delete(string $path, callable $handler, array $middlewares = []): void { $this->add('DELETE', $path, $handler, $middlewares); }

    public function dispatch(Request $req): Response {
        $method = strtoupper($req->method);
        foreach ($this->routes[$method] ?? [] as [$path, $handler, $middlewares]) {
            // Match exact path
            if ($path === $req->uri) {
                foreach ($middlewares as $mw) {
                    $res = $mw($req);
                    if ($res instanceof Response) { return $res; }
                }
                return $handler($req);
            }
            // Match dynamic placeholders like /api/clientes/{id}
            if (str_contains($path, '{')) {
                // Extrair nomes dos placeholders
                preg_match_all('/\{([^\/]+)\}/', $path, $paramNames);
                $paramNames = $paramNames[1] ?? [];
                
                // Criar regex de match
                $regex = '#^' . preg_replace('/\{[^\/]+\}/', '([^/]+)', $path) . '$#';
                if (preg_match($regex, $req->uri, $m)) {
                    array_shift($m); // Remover match completo
                    
                    // Criar array associativo com nomes dos parâmetros
                    $params = [];
                    foreach ($paramNames as $index => $name) {
                        if (isset($m[$index])) {
                            $params[$name] = $m[$index];
                        }
                    }
                    // Também manter array numérico para compatibilidade
                    $paramsArray = array_values($m);
                    
                    // Armazenar ambos: associativo (como propriedade) e numérico (como atributo)
                    $req->params = $params;
                    $req->set('params', $paramsArray);
                    
                    foreach ($middlewares as $mw) {
                        $res = $mw($req);
                        if ($res instanceof Response) { return $res; }
                    }
                    return $handler($req);
                }
            }
        }
        return new Response(404, ['error' => 'Not Found']);
    }

    // Debug helper: list registered routes
    public function list(): array {
        return $this->routes;
    }
}