<?php

namespace App\Framework\View;

use App\Framework\Core\ValueObjects\Hash;

/**
 * Compiled Template Value Object
 *
 * Repräsentiert ein vorverarbeitetes Template mit strukturierten Daten
 * für schnelleres Re-Rendering.
 */
final readonly class CompiledTemplate
{
    /**
     * @param string $templatePath Original template path
     * @param array<string> $placeholders Extracted placeholders
     * @param array<string> $components Referenced components
     * @param array<ProcessorInstruction> $instructions Processor instructions
     * @param int $compiledAt Unix timestamp when compiled
     * @param Hash $contentHash Hash of original content
     */
    public function __construct(
        public string $templatePath,
        public array  $placeholders,
        public array  $components,
        public array  $instructions,
        public int    $compiledAt,
        public Hash   $contentHash
    ) {}

    /**
     * Konvertiert zu Array für Caching
     */
    public function toArray(): array
    {
        return [
            'template_path' => $this->templatePath,
            'placeholders' => $this->placeholders,
            'components' => $this->components,
            'instructions' => array_map(
                fn(ProcessorInstruction $i) => $i->toArray(),
                $this->instructions
            ),
            'compiled_at' => $this->compiledAt,
            'content_hash' => $this->contentHash->toString(),
        ];
    }

    /**
     * Rekonstruiert aus Array
     */
    public static function fromArray(array $data): self
    {
        return new self(
            templatePath: $data['template_path'],
            placeholders: $data['placeholders'],
            components  : $data['components'],
            instructions: array_map(
                fn(array $i) => ProcessorInstruction::fromArray($i),
                $data['instructions']
            ),
            compiledAt  : $data['compiled_at'],
            contentHash : Hash::fromString($data['content_hash'])
        );
    }

    /**
     * Prüft ob Template bestimmte Features verwendet
     */
    public function hasPlaceholders(): bool
    {
        return !empty($this->placeholders);
    }

    public function hasComponents(): bool
    {
        return !empty($this->components);
    }

    public function getInstructionCount(): int
    {
        return count($this->instructions);
    }
}
