<?php

namespace Tests\Unit\Services\PromptLandingPageEditor;

use App\Services\PromptLandingPageEditor\SanitizeDocument;
use App\Services\PromptLandingPageHtmlSanitizer;
use Tests\TestCase;

class SanitizeDocumentTest extends TestCase
{
    public function test_it_strips_scripts_and_javascript_urls_from_html_but_keeps_form_and_tracking_attributes(): void
    {
        $html = <<<'HTML'
<section id="hero" data-analytics="hero" aria-label="Hero">
    <a href="javascript:alert(1)">Bad</a>
    <a href="/signup?utm_source=hero" data-cta="start">Keep</a>
    <form id="lead-form" class="lead-form" method="post" data-form="lead">
        <input type="hidden" name="source" value="landing">
        <input id="email" type="email" name="email" required>
        <script>alert('xss')</script>
    </form>
</section>
HTML;

        $result = $this->sanitizer()->sanitize($html, 'h1 { color: red; }', 'var ok = 1;');

        $this->assertStringNotContainsString('<script>', $result['html']);
        $this->assertStringNotContainsString('javascript:alert', $result['html']);
        $this->assertStringContainsString('id="lead-form"', $result['html']);
        $this->assertStringContainsString('class="lead-form"', $result['html']);
        $this->assertStringContainsString('name="email"', $result['html']);
        $this->assertStringContainsString('required', $result['html']);
        $this->assertStringContainsString('data-form="lead"', $result['html']);
        $this->assertStringContainsString('data-analytics="hero"', $result['html']);
        $this->assertStringContainsString('aria-label="Hero"', $result['html']);
        $this->assertStringContainsString('/signup?utm_source=hero', $result['html']);
        $this->assertSame('h1 { color: red; }', $result['css']);
        $this->assertSame('var ok = 1;', $result['js']);
    }

    public function test_it_neutralizes_css_and_javascript_breakouts(): void
    {
        $result = $this->sanitizer()->sanitize(
            '<p>Hi</p><base href="https://evil.test">',
            'body { color: red; } </style><script>alert(1)</script>',
            'var a = 1;</script><script>alert(1)',
        );

        $this->assertStringNotContainsString('<base', $result['html']);
        $this->assertStringNotContainsString('</style>', $result['css']);
        $this->assertStringContainsString('<\\/script', $result['js']);
    }

    public function test_it_keeps_scroll_behavior_and_transition_css(): void
    {
        $css = <<<'CSS'
html { scroll-behavior: smooth; }
.button { transition: transform 180ms ease; }
.trust-strip { border-top: 1px solid var(--line); background: var(--soft); }
CSS;

        $result = $this->sanitizer()->sanitize('<p>Hi</p>', $css, '');

        $this->assertStringContainsString('scroll-behavior: smooth', $result['css']);
        $this->assertStringContainsString('transition: transform 180ms ease', $result['css']);
        $this->assertStringContainsString('.trust-strip', $result['css']);
        $this->assertStringNotContainsString('scroll-invalid', $result['css']);
    }

    public function test_it_strips_grapesjs_chrome_css_and_ie_behavior(): void
    {
        $css = <<<'CSS'
[data-gjs-type="wrapper"] { min-height: 100vh; }
.gjs-selected { outline: 2px solid #3b97e3 !important; }
.trust-strip { background: var(--soft); }
body { behavior: url(#default#VML); }
CSS;

        $result = $this->sanitizer()->sanitize('<p>Hi</p>', $css, '');

        $this->assertStringNotContainsString('data-gjs-type', $result['css']);
        $this->assertStringNotContainsString('.gjs-selected', $result['css']);
        $this->assertStringContainsString('.trust-strip', $result['css']);
        $this->assertStringContainsString('invalid:', $result['css']);
    }

    public function test_it_strips_editor_chrome_style_tags_and_draggable_attributes(): void
    {
        $html = <<<'HTML'
<style>
html, body, [data-gjs-type="wrapper"] { min-height: 100%; }
body { background-color: transparent; }
</style>
<style>.hero-card { background: #fff; }</style>
<div id="gjs-css-rules"></div>
<section class="hero" draggable="true"><h1>Live heading</h1></section>
HTML;

        $result = $this->sanitizer()->sanitize($html, 'body { background: #f5effb; }', '');

        $this->assertStringNotContainsString('data-gjs-type', $result['html']);
        $this->assertStringNotContainsString('background-color: transparent', $result['html']);
        $this->assertStringNotContainsString('<style>', $result['html']);
        $this->assertStringNotContainsString('gjs-css-rules', $result['html']);
        $this->assertStringNotContainsString('draggable', $result['html']);
        $this->assertStringContainsString('Live heading', $result['html']);
        $this->assertStringContainsString('body { background: #f5effb; }', $result['css']);
        $this->assertStringContainsString('.hero-card { background: #fff; }', $result['css']);
        $this->assertGreaterThan(
            strpos($result['css'], 'body { background: #f5effb; }'),
            strpos($result['css'], '.hero-card { background: #fff; }'),
        );
    }

    public function test_it_strips_editor_only_attributes(): void
    {
        $result = $this->sanitizer()->sanitize(
            '<h1 data-gjs-type="text" id="headline">Title</h1>',
            '',
            '',
        );

        $this->assertStringNotContainsString('data-gjs-type', $result['html']);
        $this->assertStringContainsString('id="headline"', $result['html']);
    }

    private function sanitizer(): SanitizeDocument
    {
        return new SanitizeDocument(new PromptLandingPageHtmlSanitizer);
    }
}
