<?php

declare(strict_types=1);

namespace CloudXM\SDK\Templates;

use CloudXM\WooSDK\Support\HasLogger;

/**
 * Very small PHP template renderer. Supports global shared data & existence checks.
 */
class PhpTemplateRenderer implements TemplateRendererInterface
{
    use HasLogger;

    public function __construct(
        private string $basePath,
        private string $extension = '.php'
    ) {}

    public function render(string $template, array $data = []): void
    {
        echo $this->fetch($template, $data);
    }

    public function fetch(string $template, array $data = []): string
    {
        $file = $this->resolvePath($template);
        if (!file_exists($file)) {
            $this->log()->error('Template not found', ['template' => $template, 'file' => $file]);
            throw new \RuntimeException("Template not found: {$template}");
        }
        $allData = array_merge($this->globals, $data);
        $sanitizedData = $this->sanitizeTemplateData($allData);
        extract($sanitizedData, EXTR_SKIP);
        ob_start();
        include $file;
        return ob_get_clean();
    }

    public function exists(string $template): bool
    {
        return file_exists($this->resolvePath($template));
    }

    public function share(string $key, mixed $value): self
    {
        $this->globals[$key] = $value;
        return $this;
    }

    /* ------------------ */

    /**
     * Sanitize template data to prevent XSS attacks
     */
    protected function sanitizeTemplateData(array $data): array
    {
        $sanitized = [];

        foreach ($data as $key => $value) {
            $sanitized[$key] = $this->sanitizeValue($value);
        }

        return $sanitized;
    }

    /**
     * Recursively sanitize a value
     */
    private function sanitizeValue(mixed $value): mixed
    {
        if (is_string($value)) {
            // Escape HTML entities to prevent XSS
            return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        }

        if (is_array($value)) {
            $sanitizedArray = [];
            foreach ($value as $k => $v) {
                $sanitizedArray[$this->sanitizeValue($k)] = $this->sanitizeValue($v);
            }
            return $sanitizedArray;
        }

        // For non-string values (int, float, bool, null, objects), return as-is
        return $value;
    }

    private array $globals = [];

    private function resolvePath(string $template): string
    {
        $template = ltrim($template, '/');
        return rtrim($this->basePath, '/').'/'.$template.$this->extension;
    }
}
