<?php

declare(strict_types=1);

namespace Tests\Framework\View\Processors;

use App\Framework\Http\Session\FormIdGenerator;
use App\Framework\Meta\MetaData;
use App\Framework\View\DomFormService;
use App\Framework\View\DomWrapper;
use App\Framework\View\Processors\FormProcessor;
use App\Framework\View\RenderContext;
use PHPUnit\Framework\TestCase;

final class FormProcessorTest extends TestCase
{
    private FormProcessor $processor;

    protected function setUp(): void
    {
        // Use real instances since classes are final
        $formIdGenerator = new FormIdGenerator();
        $formService = new DomFormService();

        $this->processor = new FormProcessor(
            $formService,
            $formIdGenerator
        );
    }

    public function test_finds_simple_form(): void
    {
        $html = '<html><body><form action="/test" method="post">
            <input type="text" name="username" />
            <input type="submit" value="Submit" />
        </form></body></html>';

        $dom = DomWrapper::fromString($html);
        $context = new RenderContext('test', new MetaData('Test'), []);

        $result = $this->processor->process($dom, $context);

        // Check that placeholders were added
        $finalHtml = $result->document->saveHTML();

        $this->assertStringContainsString('___TOKEN___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_username___', $finalHtml);
        // Form ID will be generated dynamically, just check it exists
        $this->assertStringContainsString('name="_form_id"', $finalHtml);
    }

    public function test_finds_contact_form(): void
    {
        $html = '<html><body>
        <form action="/kontakt" method="post">
            <input type="text" name="name" />
            <input type="email" name="email" />
            <select name="subject">
                <option value="1">Option 1</option>
                <option value="2">Option 2</option>
            </select>
            <textarea name="message"></textarea>
            <input type="submit" value="Senden" />
        </form>
        </body></html>';

        $dom = DomWrapper::fromString($html);
        $context = new RenderContext('contact', new MetaData('Contact'), []);

        $result = $this->processor->process($dom, $context);
        $finalHtml = $result->document->saveHTML();

        // Check form found and processed
        $this->assertStringContainsString('___TOKEN___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_name___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_email___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_message___', $finalHtml);
        $this->assertStringContainsString('name="_form_id"', $finalHtml);

        // Check select options have placeholders
        $this->assertStringContainsString('data-selected-if="___OLD_SELECT_subject_1___"', $finalHtml);
        $this->assertStringContainsString('data-selected-if="___OLD_SELECT_subject_2___"', $finalHtml);
    }

    public function test_handles_no_forms(): void
    {
        $html = '<html><body><h1>No forms here</h1></body></html>';

        $dom = DomWrapper::fromString($html);
        $context = new RenderContext('test', new MetaData('Test'), []);

        $result = $this->processor->process($dom, $context);
        $finalHtml = $result->document->saveHTML();

        $this->assertStringNotContainsString('___TOKEN___', $finalHtml);
        $this->assertStringNotContainsString('___OLD_INPUT_', $finalHtml);
    }

    public function test_handles_layout_tag_content(): void
    {
        // This tests the specific case from contact.view.php
        $html = '<layout src="main"/>
        <section>
            <h1>Kontakt</h1>
            <form action="/kontakt" method="post">
                <input type="text" name="name" id="name">
                <input type="email" name="email" id="email">
                <input type="submit" value="Senden">
            </form>
        </section>';

        $dom = DomWrapper::fromString($html);
        $context = new RenderContext('contact', new MetaData('Contact'), []);

        $result = $this->processor->process($dom, $context);
        $finalHtml = $result->document->saveHTML();

        // Should find the form even with layout tag
        $this->assertStringContainsString('___TOKEN___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_name___', $finalHtml);
        $this->assertStringContainsString('___OLD_INPUT_email___', $finalHtml);
    }
}
