<?php
namespace Core;

class View {
    public static function render(string $viewPath, array $data = []): string {
        $file = static::resolveViewPath($viewPath);
        if (!$file || !file_exists($file)) {
            return "<div class='alert alert-danger'>View not found: " . static::e($viewPath) . "</div>";
        }

        $context = new class {
            public ?string $layoutName = null;
            public array $layoutData = [];

            public function layout(string $name, array $data = []): void {
                $name = str_replace('layouts/', '', $name);
                $this->layoutName = $name;
                $this->layoutData = $data;
            }

            public function e(mixed $value): string {
                return View::e($value);
            }

            public function url(string $path): string {
                return View::url($path);
            }
        };

        $render = function($__file__, $__data__) use ($context) {
            extract($__data__);
            ob_start();
            require $__file__;
            return ob_get_clean();
        };

        $content = $render->call($context, $file, $data);

        if ($context->layoutName !== null) {
            $layoutData = array_merge($data, $context->layoutData);
            return static::layout($context->layoutName, $content, $layoutData);
        }

        return $content;
    }
    
    public static function layout(string $layoutName, string $content, array $data = []): string {
        extract($data);
        ob_start();
        
        $file = ROOT_PATH . '/modules/shared/views/layouts/' . $layoutName . '.php';
        if (!file_exists($file)) {
            $file = ROOT_PATH . '/app/Views/layouts/' . $layoutName . '.php';
        }
        
        if (file_exists($file)) {
            require $file;
        } else {
            echo $content;
        }
        return ob_get_clean();
    }
    
    public static function partial(string $partialPath, array $data = []): string {
        return self::render('shared/views/partials/' . $partialPath, $data);
    }
    
    public static function e(mixed $value): string {
        return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
    }
    
    public static function asset(string $path): string {
        return APP_URL . '/assets/' . ltrim($path, '/');
    }
    
    public static function url(string $path): string {
        return APP_URL . '/' . ltrim($path, '/');
    }
    
    public static function flash(): array {
        $flash = $_SESSION['flash'] ?? [];
        unset($_SESSION['flash']);
        return $flash;
    }

    private static function resolveViewPath(string $viewPath): ?string {
        // 1. Direct path from ROOT_PATH
        $candidate = ROOT_PATH . '/' . ltrim($viewPath, '/');
        if (!str_ends_with($candidate, '.php')) $candidate .= '.php';
        if (file_exists($candidate)) return $candidate;

        // 2. Check modules directory
        $modulesDir = ROOT_PATH . '/modules';
        if (is_dir($modulesDir)) {
            $parts = explode('/', trim($viewPath, '/'));
            if (count($parts) > 1) {
                $module = $parts[0];
                $relView = implode('/', array_slice($parts, 1));
                $candidate = $modulesDir . '/' . $module . '/views/' . $relView . '.php';
                if (file_exists($candidate)) return $candidate;
            }

            // 3. Search all modules for views/$viewPath.php
            foreach (scandir($modulesDir) as $module) {
                if ($module === '.' || $module === '..') continue;
                $candidate = $modulesDir . '/' . $module . '/views/' . $viewPath . '.php';
                if (file_exists($candidate)) return $candidate;
            }
        }

        return null;
    }
}
