<?php
/**
 * Classe Router - Gestion des routes
 * mySupport - Plateforme de Service Client Intelligent
 */

namespace Core;

class Router
{
    private array $routes = [];
    private array $middlewares = [];

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

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

    public function put(string $path, array $handler): self
    {
        return $this->addRoute('PUT', $path, $handler);
    }

    public function delete(string $path, array $handler): self
    {
        return $this->addRoute('DELETE', $path, $handler);
    }

    private function addRoute(string $method, string $path, array $handler): self
    {
        $this->routes[] = [
            'method' => $method,
            'path' => $path,
            'handler' => $handler,
            'pattern' => $this->convertToRegex($path)
        ];
        return $this;
    }

    private function convertToRegex(string $path): string
    {
        $pattern = preg_replace('/\{([a-zA-Z_]+)\}/', '(?P<$1>[^/]+)', $path);
        return '#^' . $pattern . '$#';
    }

    public function middleware(string $name, callable $callback): self
    {
        $this->middlewares[$name] = $callback;
        return $this;
    }

    public function dispatch(): void
    {
        $method = $_SERVER['REQUEST_METHOD'];
        $uri = $this->getUri();

        foreach ($this->routes as $route) {
            if ($route['method'] !== $method) {
                continue;
            }

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

        $this->notFound();
    }

    private function getUri(): string
    {
        $requestUri = $_SERVER['REQUEST_URI'] ?? '/';

        $path = parse_url($requestUri, PHP_URL_PATH);
        $path = is_string($path) ? $path : '/';

        // Retirer dynamiquement le "base path" (ex: /support/public) en se basant sur SCRIPT_NAME
        $scriptName = (string)($_SERVER['SCRIPT_NAME'] ?? '');
        $basePath = str_replace('\\', '/', dirname($scriptName));
        $basePath = rtrim($basePath, '/');
        if ($basePath === '/' || $basePath === '.') {
            $basePath = '';
        }

        if ($basePath !== '' && str_starts_with($path, $basePath)) {
            $path = substr($path, strlen($basePath));
        }

        // Retirer /index.php si présent dans l'URL
        if (str_starts_with($path, '/index.php')) {
            $path = substr($path, strlen('/index.php'));
        }

        $path = $path ?: '/';

        // S'assurer que l'URI commence par /
        if ($path[0] !== '/') {
            $path = '/' . $path;
        }

        return $path;
    }

    private function callHandler(array $handler, array $params): void
    {
        [$controllerClass, $method] = $handler;
        
        $controllerFile = APP_PATH . '/Controllers/' . $controllerClass . '.php';
        
        if (!file_exists($controllerFile)) {
            die("Contrôleur non trouvé: {$controllerClass}");
        }
        
        require_once $controllerFile;
        
        $fullClassName = "App\\Controllers\\{$controllerClass}";
        
        if (!class_exists($fullClassName)) {
            die("Classe contrôleur non trouvée: {$fullClassName}");
        }
        
        $controller = new $fullClassName();
        
        if (!method_exists($controller, $method)) {
            die("Méthode non trouvée: {$method}");
        }
        
        call_user_func_array([$controller, $method], $params);
    }

    private function notFound(): void
    {
        http_response_code(404);
        require_once VIEWS_PATH . '/errors/404.php';
        exit;
    }
}
