<?php
namespace App\Core;

class Router
{
    private array $routes = [];

    public function get(string $path, callable|array $handler): void
    {
        $this->addRoute('GET', $path, $handler);
    }

    public function post(string $path, callable|array $handler): void
    {
        $this->addRoute('POST', $path, $handler);
    }

    public function any(string $path, callable|array $handler): void
    {
        $this->addRoute('GET', $path, $handler);
        $this->addRoute('POST', $path, $handler);
    }

    private function addRoute(string $method, string $path, callable|array $handler): void
    {
        $this->routes[$method][$this->normalize($path)] = $handler;
    }

    public function dispatch(): void
    {
        $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
        $requestUri = $_SERVER['REQUEST_URI'] ?? '/';

        $requestPath = parse_url($requestUri, PHP_URL_PATH) ?: '/';

        if (strpos($requestPath, '/index.php') !== false) {
            $path = substr($requestPath, strpos($requestPath, '/index.php') + 10);
        } else {
            $path = $requestPath;

            $baseCandidates = [
                dirname($_SERVER['SCRIPT_NAME'] ?? ''),
                dirname($_SERVER['PHP_SELF'] ?? ''),
                dirname($_SERVER['ORIG_SCRIPT_NAME'] ?? ''),
            ];

            foreach ($baseCandidates as $candidate) {
                $candidate = rtrim(str_replace('\\', '/', (string)$candidate), '/');
                if ($candidate === '' || $candidate === '.' || $candidate === '/') {
                    continue;
                }

                if (strpos($path, $candidate) === 0) {
                    $path = substr($path, strlen($candidate));
                    break;
                }
            }

            if (strpos($path, '/public/') !== false) {
                $path = preg_replace('#^.*?/public(?=/|$)#', '', $path) ?: $path;
            }
        }

        $path = $path ?: '/';
        $path = $this->normalize($path);

        $handler = $this->routes[$method][$path] ?? null;
        if (!$handler) {
            http_response_code(404);
            echo '<h1>404 Not Found</h1>';
            echo '<p>Route non trouvée : ' . htmlspecialchars($path) . '</p>';
            echo '<p>Méthode : ' . htmlspecialchars($method) . '</p>';
            echo '<p><a href="/">Retour à l\'accueil</a></p>';
            return;
        }

        if (is_array($handler)) {
            [$class, $action] = $handler;
            $controller = new $class;
            $controller->$action();
            return;
        }

        call_user_func($handler);
    }

    private function normalize(string $path): string
    {
        $clean = rtrim($path, '/');
        return $clean === '' ? '/' : $clean;
    }
}
