<?php
namespace App\Core;

class Router {
    protected $routes = [];
    protected $basePath = '';

    public function __construct() {
        $this->detectBasePath();
    }

    protected function detectBasePath() {
        // Detects subdirectory dynamically if running from subfolder
        $scriptName = $_SERVER['SCRIPT_NAME']; // e.g. /everest/public/index.php
        $requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
        $dir = dirname($scriptName); // e.g. /everest/public or /everest
        
        // If Apache rewrote the URL to hide "/public", strip it from base path
        if (strpos($requestUri, '/public') === false && strpos($dir, '/public') !== false) {
            $dir = str_replace('/public', '', $dir);
        }
        
        $this->basePath = rtrim($dir, '/');
    }

    public function getBasePath() {
        return $this->basePath;
    }

    public function getBaseUrl() {
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) ? "https://" : "http://";
        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
        return rtrim($protocol . $host . $this->basePath, '/');
    }

    public function add($methods, $route, $handler) {
        $methods = (array)$methods;
        $this->routes[] = [
            'methods' => array_map('strtoupper', $methods),
            'route' => $this->prepareRoute($route),
            'handler' => $handler
        ];
    }

    protected function prepareRoute($route) {
        // Replace dynamic parameters like {slug} with regex
        $route = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?P<$1>[a-zA-Z0-9_\-\%]+)', $route);
        return '#^' . $route . '$#s';
    }

    public function dispatch() {
        $requestMethod = $_SERVER['REQUEST_METHOD'];
        $requestUri = $_SERVER['REQUEST_URI'];
        
        // Strip query string
        if (($pos = strpos($requestUri, '?')) !== false) {
            $requestUri = substr($requestUri, 0, $pos);
        }
        
        // Remove basePath from requestUri to get routePath
        $routePath = $requestUri;
        if ($this->basePath !== '' && strpos($requestUri, $this->basePath) === 0) {
            $routePath = substr($requestUri, strlen($this->basePath));
        } else {
            // Fallback: also try without trailing basePath segment
            $normalized = rtrim($this->basePath, '/');
            if ($normalized !== '' && strpos($requestUri, $normalized) === 0) {
                $routePath = substr($requestUri, strlen($normalized));
            }
        }
        
        $routePath = '/' . trim($routePath, '/');
        
        // Try to match explicit routes
        foreach ($this->routes as $route) {
            if (in_array($requestMethod, $route['methods'])) {
                if (preg_match($route['route'], $routePath, $matches)) {
                    $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
                    return $this->executeHandler($route['handler'], $params);
                }
            }
        }
        
        // Fallback: Dynamic URL routing (DB Slugs for categories/products)
        return $this->executeFallbackRoute($routePath);
    }

    protected function executeHandler($handler, $params = []) {
        if (is_callable($handler)) {
            return call_user_func_array($handler, $params);
        }
        
        if (is_string($handler)) {
            list($controllerName, $action) = explode('@', $handler);
            $controllerClass = "App\\Controllers\\" . $controllerName;
            
            if (class_exists($controllerClass)) {
                $controller = new $controllerClass();
                if (method_exists($controller, $action)) {
                    return call_user_func_array([$controller, $action], $params);
                }
            }
        }
        
        $this->send404();
    }

    protected function executeFallbackRoute($routePath) {
        // Clean routePath
        $path = trim($routePath, '/');
        if ($path === '') {
            return $this->executeHandler('ClientController@home');
        }
        
        // Extract the last segment which is usually the product or category slug
        $segments = explode('/', $path);
        $slug = end($segments);
        
        // Url decode for Turkish characters
        $slug = urldecode($slug);
        
        // We will dispatch to ClientController's resolveSlug method, which queries JSON db
        return $this->executeHandler('ClientController@resolveSlug', ['slug' => $slug, 'fullPath' => $path]);
    }

    public function send404() {
        header("HTTP/1.0 404 Not Found");
        echo "<h1>404 Not Found</h1>";
        echo "<p>Aradığınız sayfa bulunamadı.</p>";
        exit;
    }
}
