<?php
namespace App\Core;

/** Perender template PHP dengan layout dan escaping otomatis. */
class View
{
    private static array $shared = [];
    private static string $layout = 'layouts/app';
    private static array $sections = [];
    private static array $stack = [];

    public static function share(string $k, $v): void { self::$shared[$k] = $v; }
    public static function setLayout(string $l): void { self::$layout = $l; }

    public static function path(string $view): string
    {
        return dirname(__DIR__) . '/Views/' . str_replace('.', '/', $view) . '.php';
    }

    public static function exists(string $view): bool { return is_file(self::path($view)); }

    /** Merender view lengkap dengan layout. */
    public static function render(string $view, array $data = [], ?string $layout = null): void
    {
        echo self::capture($view, $data, $layout);
    }

    public static function capture(string $view, array $data = [], ?string $layout = null): string
    {
        $file = self::path($view);
        if (!is_file($file)) {
            throw new \RuntimeException("Template tidak ditemukan: $view");
        }
        $vars = array_merge(self::$shared, $data);
        $content = self::renderFile($file, $vars);

        $layout = $layout ?? self::$layout;
        if ($layout === '' || $layout === null) return $content;

        $layoutFile = self::path($layout);
        if (!is_file($layoutFile)) return $content;
        $vars['content'] = $content;
        $vars['sections'] = self::$sections;
        return self::renderFile($layoutFile, $vars);
    }

    /** Merender partial tanpa layout. */
    public static function partial(string $view, array $data = []): string
    {
        $file = self::path($view);
        if (!is_file($file)) return '';
        return self::renderFile($file, array_merge(self::$shared, $data));
    }

    private static function renderFile(string $file, array $vars): string
    {
        extract($vars, EXTR_SKIP);
        ob_start();
        try {
            include $file;
        } catch (\Throwable $e) {
            ob_end_clean();
            throw $e;
        }
        return (string)ob_get_clean();
    }

    // ------------------------- Section helper -------------------------
    public static function start(string $name): void
    {
        self::$stack[] = $name;
        ob_start();
    }

    public static function stop(): void
    {
        $name = array_pop(self::$stack);
        if ($name === null) { ob_end_clean(); return; }
        self::$sections[$name] = (string)ob_get_clean();
    }

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

    public static function hasSection(string $name): bool { return isset(self::$sections[$name]); }
}
