<?php

declare(strict_types=1);

namespace App\Framework\View\Dom\Transformer;

use App\Framework\Template\Processing\AstTransformer;
use App\Framework\View\Dom\DocumentNode;
use App\Framework\View\Dom\ElementNode;
use App\Framework\View\Dom\Node;
use App\Framework\View\Dom\TextNode;
use App\Framework\View\RenderContext;

/**
 * WhitespaceCleanupTransformer - Removes empty text nodes from AST
 *
 * Recursively removes TextNode instances that contain only whitespace.
 * This includes empty lines, spaces-only nodes, etc.
 *
 * Before:  <div>   \n   <p>text</p>   \n   </div>
 * After:   <div><p>text</p></div>
 *
 * Framework Pattern: readonly class, AST-based transformation
 */
final readonly class WhitespaceCleanupTransformer implements AstTransformer
{
    public function transform(DocumentNode $document, RenderContext $context): DocumentNode
    {
        // Process all children recursively
        $this->removeEmptyTextNodes($document);

        return $document;
    }

    /**
     * Recursively remove text nodes containing only whitespace
     */
    private function removeEmptyTextNodes(Node $node): void
    {
        if (! $node instanceof ElementNode && ! $node instanceof DocumentNode) {
            return;
        }

        // Get children via public API
        $children = $node->getChildren();

        // Remove empty TextNode children
        foreach ($children as $child) {
            if ($this->isEmptyTextNode($child)) {
                $node->removeChild($child);
            }
        }

        // Recurse into remaining children
        foreach ($node->getChildren() as $child) {
            $this->removeEmptyTextNodes($child);
        }
    }

    /**
     * Check if node is a TextNode containing only whitespace
     */
    private function isEmptyTextNode(Node $node): bool
    {
        if (! $node instanceof TextNode) {
            return false;
        }

        // Check if content is only whitespace via public API
        return preg_match('/^\s*$/', $node->getTextContent()) === 1;
    }
}
