<?php

/**
 * SimpleTemplate - Lightweight template rendering engine
 * 
 * Features:
 * - Variable replacement with {{variable}} syntax
 * - Unescaped HTML content with {{{variable}}} syntax
 * - Conditional blocks with {{#variable}}...{{/variable}}
 * - Negative conditionals with {{^variable}}...{{/variable}}
 * - Partial includes with {{>partial}}
 * - Simple string-based rendering (no external dependencies)
 */
class SimpleTemplate {
    private $data;
    
    /**
     * Render template with data
     * 
     * @param string $template Template content with placeholders
     * @param array $data Data to populate template
     * @return string Rendered template
     */
    public static function render($template, $data) {
        $instance = new self();
        $instance->data = $data;
        return $instance->renderTemplate($template);
    }
    
    /**
     * Process template and replace placeholders
     * 
     * @param string $template Template content
     * @return string Processed template
     */
    private function renderTemplate($template) {
        // Handle partial includes first ({{>partial}})
        $template = preg_replace_callback('/{{>([^}]+)}}/', [$this, 'replacePartial'], $template);
        
        // Handle equal conditionals first
        $template = preg_replace_callback('/{{#equal\s+(\w+)\s+["\']([^"\']+)["\']}}(.*?){{\/equal}}/s', function($matches) {
            $key = $matches[1];
            $expectedValue = $matches[2];
            $content = $matches[3];
            
            $actualValue = $this->data[$key] ?? '';
            return ($actualValue === $expectedValue) ? $content : '';
        }, $template);
        
        // Handle conditional blocks
        foreach ($this->data as $key => $value) {
            if (is_array($value)) {
                // Handle {{#key}}...{{/key}} blocks for arrays (iteration)
                $pattern = '/{{#' . preg_quote($key, '/') . '}}(.*?){{\/' . preg_quote($key, '/') . '}}/s';
                if (preg_match($pattern, $template, $matches)) {
                    $blockTemplate = $matches[1];
                    $replacement = '';
                    
                    foreach ($value as $item) {
                        if (is_array($item)) {
                            // Create a temporary template instance for nested data
                            $tempTemplate = new self();
                            $tempTemplate->data = $item;
                            $replacement .= $tempTemplate->renderTemplate($blockTemplate);
                        } else {
                            // Simple array, replace {{.}} with the item value
                            $itemBlock = str_replace('{{.}}', htmlspecialchars($item, ENT_QUOTES, 'UTF-8'), $blockTemplate);
                            $replacement .= $itemBlock;
                        }
                    }
                    
                    $template = preg_replace($pattern, $replacement, $template);
                }
                
                // Handle {{^key}}...{{/key}} blocks (negative condition for empty arrays)
                $pattern = '/{{\^' . preg_quote($key, '/') . '}}(.*?){{\/' . preg_quote($key, '/') . '}}/s';
                if (empty($value)) {
                    // Show the content if array is empty
                    if (preg_match($pattern, $template, $matches)) {
                        $template = preg_replace($pattern, $matches[1], $template);
                    }
                } else {
                    // Remove the content if array is not empty
                    $template = preg_replace($pattern, '', $template);
                }
            } elseif ((is_string($value) && !empty($value)) || (is_bool($value) && $value === true)) {
                // Handle {{#key}}...{{/key}} blocks for truthy values
                $pattern = '/{{#' . preg_quote($key, '/') . '}}(.*?){{\/' . preg_quote($key, '/') . '}}/s';
                if (preg_match($pattern, $template, $matches)) {
                    $replacement = $matches[1];
                    $template = preg_replace($pattern, $replacement, $template);
                }
                
                // Handle {{^key}}...{{/key}} blocks (negative condition)
                $pattern = '/{{\^' . preg_quote($key, '/') . '}}(.*?){{\/' . preg_quote($key, '/') . '}}/s';
                $template = preg_replace($pattern, '', $template);
            } else {
                // Handle empty blocks
                $pattern = '/{{#' . preg_quote($key, '/') . '}}.*?{{\/' . preg_quote($key, '/') . '}}/s';
                $template = preg_replace($pattern, '', $template);
                
                // Handle {{^key}}...{{/key}} blocks (show when empty)
                $pattern = '/{{\^' . preg_quote($key, '/') . '}}(.*?){{\/' . preg_quote($key, '/') . '}}/s';
                if (preg_match_all($pattern, $template, $matches)) {
                    foreach ($matches[1] as $match) {
                        $template = preg_replace('/{{\^' . preg_quote($key, '/') . '}}.*?{{\/' . preg_quote($key, '/') . '}}/s', $match, $template, 1);
                    }
                }
            }
        }
        
        // Handle variable replacements
        foreach ($this->data as $key => $value) {
            // Handle triple braces for unescaped HTML content
            if (strpos($template, '{{{' . $key . '}}}') !== false) {
                $template = str_replace('{{{' . $key . '}}}', is_string($value) ? $value : print_r($value, true), $template);
            }
            // Handle double braces for escaped content
            elseif (strpos($template, '{{' . $key . '}}') !== false) {
                if (is_string($value)) {
                    $template = str_replace('{{' . $key . '}}', htmlspecialchars($value, ENT_QUOTES, 'UTF-8'), $template);
                } elseif (is_array($value)) {
                    // For arrays, convert to JSON string for display
                    $template = str_replace('{{' . $key . '}}', htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8'), $template);
                } else {
                    // Convert other types to string
                    $template = str_replace('{{' . $key . '}}', htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'), $template);
                }
            }
        }
        return $template;
    }
    
    /**
     * Replace partial includes with data values
     * 
     * @param array $matches Regex matches from preg_replace_callback
     * @return string Replacement content
     */
    private function replacePartial($matches) {
        $partialName = $matches[1];
        return isset($this->data[$partialName]) ? $this->data[$partialName] : $matches[0];
    }
}