<?php
declare(strict_types=1);

/**
 * 视图类
 * 原生 PHP 模板，直接 require 渲染，不做危险函数扫描，以性能为先
 */
final class View
{
    /** @var array 待传递给模板的变量 */
    private static array $__viewVars = [];

    /**
     * 给模板赋值
     * @param string|array $key 变量名，或 [name => value, ...] 多个一起设
     * @param mixed $value 变量值，$key 为数组时忽略
     */
    public static function set(string|array $key, mixed $value = null): void
    {
        if (is_array($key)) {
            self::$__viewVars = array_merge(self::$__viewVars, $key);
        } else {
            self::$__viewVars[$key] = $value;
        }
    }

    /**
     * 输出视图
     * @param string $view 模板名，如 'demo/list'；为空时取当前路由对应的默认模板
     */
    public static function put(string $view = ''): void
    {
        self::render(self::resolveFile($view));
    }

    /**
     * 加载子视图（在模板内调用）
     * @param string $view 模板名，如 'public/header'
     */
    public static function load(string $view): void
    {
        self::render(self::resolveFile($view, true));
    }

    /**
     * 解析模板名为绝对文件路径
     */
    private static function resolveFile(string $view, bool $isPartial = false): string
    {
        if ($view === '' && !$isPartial) {
            $classBase = substr(Mvc::$class, 0, -6); // 去掉 'Action' 后缀
            $view = Mvc::$cfg['routeDir'] . $classBase . '/' . Mvc::$method;
        } else {
            $view = str_replace('.', '/', $view);
        }

        return rtrim((string) Mvc::$cfg['viewDir'], '/') . '/' . $view . '.view.php';
    }

    /**
     * 渲染模板：extract 变量后直接 require，交给 PHP 引擎原生执行
     */
    private static function render(string $__viewFile): void
    {
        if (!is_file($__viewFile)) {
            throw new MvcException("找不到视图文件: {$__viewFile}");
        }
        extract(self::$__viewVars, EXTR_SKIP);
        require $__viewFile;
    }
}
