<?php
declare(strict_types=1);

namespace App\Framework\View\Processors;

use App\Framework\Http\Session\Session;
use App\Framework\View\DomFormService;
use App\Framework\View\DomProcessor;
use App\Framework\View\DomWrapper;
use App\Framework\View\RenderContext;
use Dom\HTMLElement;

final readonly class FormProcessor implements DomProcessor
{
    public function __construct(
        private DomFormService $formService,
        #private Session $session,
    ) {}

    public function process(DomWrapper $dom, RenderContext $context): DomWrapper
    {
        $forms = $dom->document->querySelectorAll('form');

        /** @var HTMLElement $form */
        foreach($forms as $form) {

            $formId = $this->generateFormId($form, $context);

            $csrf = $dom->document->createElement('input');
            $csrf->setAttribute('name', '_token');
            $csrf->setAttribute('type', 'hidden');
            $csrf->setAttribute('value', '___TOKEN___');
            #$csrf->setAttribute('value', $this->session->csrf->generateToken($formId));

            // Form ID
            $formIdField = $dom->document->createElement('input');
            $formIdField->setAttribute('name', '_form_id');
            $formIdField->setAttribute('type', 'hidden');
            $formIdField->setAttribute('value', $formId);

            $form->insertBefore($csrf, $form->firstChild);
            $form->insertBefore($formIdField, $form->firstChild);;

        }

        return $dom;
    }

    private function generateFormId(HTMLElement $form, RenderContext $context): string
    {
        // 1. Vorhandene ID verwenden, falls gesetzt
        if ($existingId = $form->getAttribute('id')) {
            return $existingId;
        }

        // 2. Hash aus charakteristischen Eigenschaften erstellen
        $hashComponents = [
            $context->route ?? 'unknown_route',
            $form->getAttribute('action') ?? '',
            $form->getAttribute('method') ?? 'post',
            $this->getFormStructureHash($form)
        ];

        return 'form_' . substr(hash('sha256', implode('|', $hashComponents)), 0, 12);
    }

    private function getFormStructureHash(HTMLElement $form): string
    {
        // Hash aus Formular-Struktur (Input-Namen) erstellen
        $inputs = $form->querySelectorAll('input[name], select[name], textarea[name]');
        $names = [];

        foreach ($inputs as $input) {
            if ($name = $input->getAttribute('name')) {
                $names[] = $name;
            }
        }

        sort($names); // Sortieren für konsistente Hashes
        return hash('crc32', implode(',', $names));
    }
}
