<?php
class View
{
    private static array $pushStacks = [];
    private static ?string $currentPush = null;
    private static ?View $instance = null;

    public static function getInstance(): View
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Render a view inside a layout
     */
    public function render(string $viewPath, array $data = [], string $layout = 'app', ?string $moduleName = null): void
    {
        // Resolve view file
        $viewFile = $this->resolveViewFile($viewPath, $moduleName);
        if (!$viewFile || !file_exists($viewFile)) {
            throw new \RuntimeException("View not found: {$viewPath} (looked for: {$viewFile})");
        }

        // Render view content
        $content = $this->renderFile($viewFile, $data);

        // Render layout with content
        $layoutFile = ROOT_PATH . '/views/layouts/' . $layout . '.php';
        if (!file_exists($layoutFile)) {
            echo $content;
            return;
        }

        $data['content'] = $content;
        $data['_styles'] = self::getStack('styles');
        $data['_scripts'] = self::getStack('scripts');
        self::$pushStacks = []; // Clear for next render

        echo $this->renderFile($layoutFile, $data);
    }

    /**
     * Render a partial (no layout)
     */
    public function partial(string $path, array $data = []): string
    {
        $file = ROOT_PATH . '/views/' . $path . '.php';
        if (!file_exists($file)) {
            return '';
        }
        return $this->renderFile($file, $data);
    }

    /**
     * Push content to a named stack (for CSS/JS)
     */
    public function push(string $name): void
    {
        self::$currentPush = $name;
        ob_start();
    }

    /**
     * End push
     */
    public function endPush(): void
    {
        if (self::$currentPush !== null) {
            $content = ob_get_clean();
            if (!isset(self::$pushStacks[self::$currentPush])) {
                self::$pushStacks[self::$currentPush] = '';
            }
            self::$pushStacks[self::$currentPush] .= $content;
            self::$currentPush = null;
        }
    }

    public static function getStack(string $name): string
    {
        return self::$pushStacks[$name] ?? '';
    }

    private function resolveViewFile(string $viewPath, ?string $moduleName): string
    {
        if ($moduleName) {
            return ROOT_PATH . '/modules/' . $moduleName . '/views/' . $viewPath . '.php';
        }
        // Core views
        return ROOT_PATH . '/views/' . $viewPath . '.php';
    }

    private function renderFile(string $file, array $data): string
    {
        extract($data);
        $__view = $this;
        ob_start();
        include $file;
        return ob_get_clean();
    }
}