<?php

namespace App\Core;

use App\Helpers\Url;

class Router
{
    private static $routes = [];

    public static function get($uri, $action)
    {
        self::$routes['GET'][$uri] = $action;
    }

    public static function post($uri, $action)
    {
        self::$routes['POST'][$uri] = $action;
    }

    public static function dispatch($uri, $method)
    {
        $uri = '/' . trim(parse_url($uri, PHP_URL_PATH), '/');
        $uri = $uri ?: '/';

        if (isset(self::$routes[$method])) {
            foreach (self::$routes[$method] as $route => $action) {
                $pattern = preg_replace('/\{(\w+)\}/', '(?P<$1>[^/]+)', $route);
                $pattern = '#^' . $pattern . '$#';

                if (preg_match($pattern, $uri, $matches)) {
                    $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);

                    if (is_array($action)) {
                        list($controller, $method) = $action;
                        $controllerFile = __DIR__ . '/../Controllers/' . $controller . '.php';
                        $controllerClass = "App\\Controllers\\{$controller}";

                        if (file_exists($controllerFile)) {
                            require_once $controllerFile;
                            $instance = new $controllerClass();
                            return call_user_func_array([$instance, $method], [$params]);
                        }
                    } elseif (is_callable($action)) {
                        return call_user_func_array($action, [$params]);
                    }
                }
            }
        }

        http_response_code(404);
        self::loadView('errors/404');
    }

    public static function loadView($view, $data = [])
    {
        extract($data);
        $viewPath = __DIR__ . '/../../resources/views/' . str_replace('.', '/', $view) . '.php';
        if (file_exists($viewPath)) {
            require $viewPath;
        } else {
            echo "View not found: " . $viewPath;
        }
    }

    public static function redirect($url)
    {
        Url::redirect($url);
    }

    public static function url($path = '')
    {
        return Url::to($path);
    }
}
