<?php

namespace App\Framework\View\Processors;

use App\Framework\Http\Session\Session;
use App\Framework\View\RenderContext;
use App\Framework\View\StringProcessor;

readonly class CsrfReplaceProcessor implements StringProcessor
{
    public function __construct(
        private Session $session,
    ){}

    public function process(string $html, RenderContext $context): string
    {
        if(!str_contains($html, '___TOKEN___')){
            // No token to replace
            return $html;
        }


        $formIds = $this->extractFormIdsFromHtml($html);

        if (empty($formIds)) {
            return $html;
        }

        // Für jede gefundene Form-ID das entsprechende Token generieren
        foreach ($formIds as $formId) {
            $token = $this->session->csrf->generateToken($formId);
            // Token-Platzhalter für diese spezifische Form-ID ersetzen
            $html = $this->replaceTokenForFormId($html, $formId, $token);
        }

        return $html;

        #$csrf->setAttribute('value', $this->session->csrf->generateToken($formId));
    }

    private function extractFormIdsFromHtml(string $html): array
    {
        $formIds = [];

        // Pattern für Form-ID: value="form_xxxxx"
        if (preg_match_all('/value=["\']form_([^"\']+)["\']/', $html, $matches)) {
            foreach ($matches[1] as $match) {
                $formId = 'form_' . $match;
                if (!in_array($formId, $formIds)) {
                    $formIds[] = $formId;
                }
            }
        }

        return $formIds;

    }

    private function replaceTokenForFormId(string $html, string $formId, string $token): string
    {
        // Suche nach dem Token-Platzhalter, der zur entsprechenden Form-ID gehört
        // Wir müssen den Kontext der Form berücksichtigen
        $pattern = '/(<form[^>]*>.*?<input[^>]*name=["\']_form_id["\'][^>]*value=["\']' . preg_quote($formId, '/') . '["\'][^>]*>.*?)<input[^>]*name=["\']_token["\'][^>]*value=["\']___TOKEN___["\'][^>]*>/s';

        return preg_replace_callback($pattern, function($matches) use ($token) {
            return str_replace('___TOKEN___', $token, $matches[0]);
        }, $html);
    }


}
