<?php

namespace App\Support;

use DOMDocument;
use DOMElement;
use App\Support\Traits\BlockLayoutDetectorTrait;
use App\Support\Traits\BlockLayoutBuilderTrait;
use App\Support\Traits\BlockLayoutHelpersTrait;

/*
 * BlockLayoutParser — разбирает произвольный HTML-фрагмент и автоматически:
 *   1. Определяет поля блока (плоские или repeater-группу).
 *   2. Генерирует черновик Blade-шаблона с {{ $data[...] }} / {{ $item[...] }}.
 *
 * Логика разбита по трейтам (app/Support/Traits/):
 *   BlockLayoutDetectorTrait — detectRepeater, allSimilar
 *   BlockLayoutBuilderTrait  — buildFlat, buildRepeater
 *   BlockLayoutHelpersTrait  — extractFields, mkField, applyTokens, replaceTokens,
 *                              serializeChildren, publicFields, elementChildren
 */
class BlockLayoutParser
{
    use BlockLayoutDetectorTrait;
    use BlockLayoutBuilderTrait;
    use BlockLayoutHelpersTrait;

    private DOMDocument $dom;
    private array $usedNames = [];
    private array $tokens    = []; // token => bladeExpr

    /**
     * Разбирает HTML и возвращает:
     *   fields       — определения полей для BlockLayoutRegistry
     *   blade        — черновик Blade-шаблона
     *   is_repeater  — обнаружена ли repeater-структура
     */
    public function parse(string $html): array
    {
        $this->usedNames = [];
        $this->tokens    = [];

        $this->dom = new DOMDocument('1.0', 'UTF-8');
        libxml_use_internal_errors(true);

        // charset-мета нужна чтобы DOMDocument корректно читал UTF-8 (emoji, кириллица)
        $this->dom->loadHTML(
            '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
            . '<div id="BLPARSER">' . $html . '</div>'
        );
        libxml_clear_errors();

        $wrapper = $this->dom->getElementById('BLPARSER');

        if (!$wrapper) {
            return ['fields' => [], 'blade' => $html, 'is_repeater' => false];
        }

        // Ищем repeater-группу
        $repeater = $this->detectRepeater($wrapper);

        if ($repeater) {
            [$container, $items] = $repeater;
            return $this->buildRepeater($wrapper, $container, $items);
        }

        return $this->buildFlat($wrapper);
    }
}
