<?php
namespace App\Core;

class Router {
    protected $routes = [];
    protected $params = [];
    
    public function add($route, $controller, $action, $method = 'GET') {
        // Store the route as-is
        $this->routes[] = [
            'route' => $route,
            'controller' => $controller,
            'action' => $action,
            'method' => strtoupper($method)
        ];
    }
    
    public function dispatch($method, $urlParts) {
        // Build the request string
        if (empty($urlParts) || (is_array($urlParts) && empty($urlParts[0]))) {
            $request = '';
        } else {
            $request = implode('/', $urlParts);
        }
        
        error_log("Dispatching: Method=$method, Request='$request'");
        
        // First, try to find an exact match
        foreach ($this->routes as $route) {
            if ($route['method'] !== strtoupper($method)) {
                continue;
            }
            
            // Check for exact match
            if ($route['route'] === $request) {
                error_log("Exact match found: " . $route['route']);
                return $this->executeRoute($route, []);
            }
        }
        
        // If no exact match, try pattern matching with parameters
        foreach ($this->routes as $route) {
            if ($route['method'] !== strtoupper($method)) {
                continue;
            }
            
            // Skip empty route in pattern matching (already handled as exact match)
            if ($route['route'] === '') {
                continue;
            }
            
            // Convert route to regex pattern
            $pattern = $this->convertToPattern($route['route']);
            $path = '/' . $request;
            
            if (preg_match($pattern, $path, $matches)) {
                error_log("Pattern match found: " . $route['route']);
                
                // Extract named params
                $params = [];
                foreach ($matches as $key => $value) {
                    if (is_string($key)) {
                        $params[$key] = $value;
                    }
                }
                
                return $this->executeRoute($route, $params);
            }
        }
        
        // No route found
        $this->show404($request);
    }
    
    private function executeRoute($route, $params) {
        $controllerClass = 'App\\Controllers\\' . $route['controller'];
        
        if (!class_exists($controllerClass)) {
            die("Controller not found: $controllerClass");
        }
        
        $controller = new $controllerClass();
        $action = $route['action'];
        
        if (!method_exists($controller, $action)) {
            die("Method $action not found in controller $controllerClass");
        }
        
        return $controller->$action($params);
    }
    
    private function convertToPattern($route) {
        // Escape slashes
        $pattern = str_replace('/', '\/', $route);
        
        // Replace parameters with regex
        $pattern = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[^\/]+)', $pattern);
        
        return '/^\/' . $pattern . '$/';
    }
    
    private function show404($request) {
        header("HTTP/1.0 404 Not Found");
        echo "<h1>404 - Page Not Found</h1>";
        echo "<p>The page you requested could not be found.</p>";
        echo "<p>Request: '" . htmlspecialchars($request) . "'</p>";
        echo "<p>Method: " . $_SERVER['REQUEST_METHOD'] . "</p>";
        echo "<h3>Available routes:</h3>";
        echo "<ul>";
        foreach ($this->routes as $route) {
            $displayRoute = $route['route'] === '' ? '/' : $route['route'];
            echo "<li>" . $route['method'] . " : '" . $displayRoute . "' → " . $route['controller'] . "@" . $route['action'] . "</li>";
        }
        echo "</ul>";
        echo "<p><a href='" . APP_URL . "/'>Go to Home</a></p>";
        exit;
    }
    
    /**
     * Get all registered routes
     */
    public function getRoutes() {
        return $this->routes;
    }
}