<?php
class View {
    protected $_head, $_body, $_section_js;
    protected $_siteTitle = SITE_TITLE;
    protected $_outputBuffer;
    protected $_layout = DEFAULT_LAYOUT;
    protected array $data = [];
    public string $_controller = '';
    public string $_action     = '';

    public function __construct() {}

    public function render($view_name, $vars = []) {
        $parts = explode('/', $view_name);
        $this->_controller = strtolower($parts[0] ?? '');
        $this->_action     = strtolower($parts[1] ?? 'index');
        $view_string = implode(DS, explode("/", $view_name));
        $this->data = is_array($vars) ? $vars : [];
        $e = fn($key, $default = '') => htmlspecialchars((string)($this->data[$key] ?? $default), ENT_QUOTES, 'UTF-8');
        extract($vars);
        $view_path = ROOT . DS . 'app' . DS . 'views' . DS . $view_string . '.php';
        if (file_exists($view_path)) {
            include($view_path);
            include(ROOT . DS . 'app' . DS . 'views' . DS . 'layouts' . DS . $this->_layout . '.php');
        } else {
            die("View not found: " . $view_name);
        }
    }

    public function set($key, $value): void         { $this->data[$key] = $value; }
    public function setAll(array $vars): void        { $this->data = array_merge($this->data, $vars); }
    public function v($key, $default = ''): string   { return htmlspecialchars($this->data[$key] ?? $default, ENT_QUOTES, 'UTF-8'); }
    public function raw($key, $default = ''): string { return (string)($this->data[$key] ?? $default); }

    public function js($key, $default = null): string {
        return json_encode(
            $this->data[$key] ?? $default,
            JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
        );
    }

    public function content($type) {
        if ($type === 'head')       return $this->_head;
        if ($type === 'body')       return $this->_body;
        if ($type === 'section_js') return $this->_section_js;
        return false;
    }

    private array $_bufferStack = [];

    public function start($type) {
        $this->_bufferStack[] = $type;
        ob_start();
    }

    public function end() {
        $type    = array_pop($this->_bufferStack);
        $content = ob_get_clean();
        if ($type === 'head')           $this->_head       = $content;
        elseif ($type === 'body')       $this->_body       = $content;
        elseif ($type === 'section_js') $this->_section_js = $content;
        else die("Unknown section type: {$type}");
    }

    public function setSiteTitle($title)  { $this->_siteTitle = $title; }
    public function siteTitle()           { return $this->_siteTitle; }
    public function setLayout($path)      { $this->_layout = $path; }

    public function insert($path) {
        include ROOT . DS . 'app' . DS . 'views' . DS . $path . '.php';
    }

    public function partial($group, $partial) {
        include ROOT . DS . 'app' . DS . 'views' . DS . $group . DS . 'partials' . DS . $partial . '.php';
    }

    public function partialWithVars($group, $partial, $vars = []) {
        extract($vars);
        include ROOT . DS . 'app' . DS . 'views' . DS . $group . DS . 'partials' . DS . $partial . '.php';
    }
}
