<?php
declare(strict_types=1);

namespace App\Core\View;

use App\Core\I18n\Translator;
use RuntimeException;

final class Template
{
    public function __construct(
        private readonly string $viewPath,
        private readonly Translator $translator
    )
    {
    }

    /**
     * @param array<string, mixed> $data
     */
    public function render(string $view, array $data = [], ?string $layout = null): string
    {
        $content = $this->renderFile($view, $data);

        if ($layout === null) {
            return $content;
        }

        return $this->renderFile($layout, array_merge($data, ['content' => $content]));
    }

    /**
     * @param array<string, mixed> $data
     */
    private function renderFile(string $view, array $data): string
    {
        $file = $this->resolve($view);
        $e = static fn (mixed $value): string => htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
        $translator = $this->translator;
        $t = static fn (string $key, array $replace = []): string => $translator->get($key, $replace);

        ob_start();
        extract($data, EXTR_SKIP);
        require $file;
        $output = ob_get_clean();

        if ($output === false) {
            throw new RuntimeException('Cannot render view: ' . $view);
        }

        return $output;
    }

    private function resolve(string $view): string
    {
        $relative = str_replace(['\\', '.'], '/', $view);
        $fullPath = rtrim($this->viewPath, '/\\') . '/' . trim($relative, '/\\') . '.php';

        if (!is_file($fullPath)) {
            throw new RuntimeException('View not found: ' . $view);
        }

        return $fullPath;
    }
}
