<?php
namespace Tshen;

/**
 * Minimal fallback router with improved handler resolution and diagnostics.
 */
class Router
{
    protected $routes = ['GET' => [], 'POST' => []];

    public function get(string $path, $handler) { $this->routes['GET'][$this->normalize($path)] = $handler; }
    public function post(string $path, $handler) { $this->routes['POST'][$this->normalize($path)] = $handler; }

    protected function normalize(string $path): string {
        $p = '/' . trim($path, '/');
        return $p === '/' ? '/' : rtrim($p, '/');
    }

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

        $routes = $this->routes[$method] ?? [];
        $handler = $routes[$uri] ?? null;

        // try relaxed matching (with/without trailing slash)
        if (!$handler) {
            foreach ($routes as $route => $h) {
                if ($route === $uri || rtrim($route, '/') === rtrim($uri, '/')) {
                    $handler = $h;
                    break;
                }
            }
        }

        if (!$handler) {
            http_response_code(404);
            $notFound = dirname(__DIR__) . '/views/404.php';
            if (file_exists($notFound)) include $notFound; else echo '404 Not Found';
            return;
        }

        // Resolve & execute handler
        try {
            // 1) callable (closure / function)
            if (is_callable($handler)) {
                call_user_func($handler);
                return;
            }

            // 2) array [Class, method]
            if (is_array($handler) && count($handler) === 2 && is_string($handler[0]) && is_string($handler[1])) {
                $class = $handler[0]; $method = $handler[1];
                if (class_exists($class)) {
                    $inst = new $class();
                    if (method_exists($inst, $method)) { $inst->{$method}(); return; }
                }
            }

            // 3) "Controller@method" style string
            if (is_string($handler) && strpos($handler, '@') !== false) {
                list($class, $method) = explode('@', $handler, 2);
                if (class_exists($class)) {
                    $inst = new $class();
                    if (method_exists($inst, $method)) { $inst->{$method}(); return; }
                }
            }

            // 4) string => treat as file path relative to project root
            if (is_string($handler)) {
                $root = dirname(__DIR__); // project root (one level up from src/)
                $file = $handler;
                // absolute path?
                if (!file_exists($file)) {
                    // try relative to project root
                    $file = $root . '/' . ltrim($handler, '/');
                }
                if (file_exists($file)) {
                    include $file;
                    return;
                }
            }

            // If we reached here, handler couldn't be resolved -> log + friendly message
            error_log('[RouterFallback] Unresolvable route handler for ' . $uri . ' — handler type: ' . gettype($handler) . ' — ' . print_r($handler, true));
            http_response_code(500);
            echo 'Route handler error';
        } catch (\Throwable $ex) {
            error_log('[RouterFallback] Exception while dispatching ' . $uri . ' : ' . $ex->getMessage());
            http_response_code(500);
            echo 'Server error';
        }
    }
}