<?php
declare(strict_types=1);

namespace Core;

final class View
{
    private string $layout = 'main';
    private array $sections = [];
    private string $currentSection = '';

    public function setLayout(string $layout): void { $this->layout = $layout; }

    /**
     * All framework-owned locals in render() / capture() use a `$__ov_*` prefix
     * so caller vars are guaranteed to win extract(). Previously the parameter
     * was called `$template`, so a caller passing a var named `template` (very
     * common — see PmTemplatesController::show) would silently drop it because
     * EXTR_SKIP protected the parameter.
     */
    public function render(string $__ov_view, array $__ov_vars = []): void
    {
        $__ov_body = $this->capture($__ov_view, $__ov_vars);

        if ($this->layout === '' || $this->layout === 'none') {
            echo $__ov_body;
            return;
        }

        $__ov_layoutFile = ROOT . "/app/Views/layouts/{$this->layout}.php";
        if (!is_file($__ov_layoutFile)) {
            throw new \RuntimeException("Layout not found: {$this->layout}");
        }
        $sections = $this->sections;
        $content  = $__ov_body;
        extract($__ov_vars, EXTR_SKIP);
        require $__ov_layoutFile;
    }

    public function json(mixed $data, int $code = 200): void
    {
        json_response($data, $code);
    }

    /** Used inside view templates: $this->start('head'); ... $this->end(); */
    public function start(string $name): void
    {
        $this->currentSection = $name;
        ob_start();
    }

    public function end(): void
    {
        $this->sections[$this->currentSection] = ob_get_clean();
        $this->currentSection = '';
    }

    public function section(string $name, string $default = ''): string
    {
        return $this->sections[$name] ?? $default;
    }

    /** Include (render) a partial view from any view template. */
    public function include(string $__ov_view, array $__ov_vars = []): string
    {
        return $this->capture($__ov_view, $__ov_vars);
    }

    private function capture(string $__ov_view, array $__ov_vars): string
    {
        $__ov_file = ROOT . "/app/Views/{$__ov_view}.php";
        if (!is_file($__ov_file)) {
            throw new \RuntimeException("View not found: {$__ov_view}");
        }
        extract($__ov_vars, EXTR_SKIP);
        ob_start();
        require $__ov_file;
        return (string) ob_get_clean();
    }
}
