<?php

namespace Tests\Unit\Models;

use App\Models\PromptLandingPage;
use Tests\TestCase;

class PromptLandingPageTest extends TestCase
{
    public function test_preview_includes_a_viewport_tag_and_responsive_base_css(): void
    {
        $page = new PromptLandingPage([
            'title' => 'Yoga studio',
            'html' => '<section><h1>Yoga studio</h1></section>',
            'css' => 'h1 { color: green; }',
            'js' => '',
        ]);

        $document = $page->renderedDocument();

        $this->assertStringContainsString(
            '<meta name="viewport" content="width=device-width, initial-scale=1">',
            $document,
        );
        $this->assertStringContainsString('max-width: 100%', $document);
        $this->assertStringContainsString('@media (max-width: 767px)', $document);
        $this->assertStringContainsString('h1 { color: green; }', $document);
        $this->assertStringContainsString('height: auto !important', $document);
        $this->assertStringContainsString('overflow-y: visible !important', $document);
        $this->assertStringContainsString('window.scrollTo', $document);
    }

    public function test_preview_scrolls_in_page_cta_hashes_on_the_window(): void
    {
        $page = new PromptLandingPage([
            'title' => 'Consultation',
            'html' => '<a href="#consultation">Book</a><form id="consultation"><input name="email"></form>',
            'css' => 'html, body { height: 100%; overflow: hidden; } header { position: sticky; top: 0; }',
            'js' => '',
        ]);

        $document = $page->renderedDocument();

        $this->assertStringContainsString('href="#consultation"', $document);
        $this->assertStringContainsString('id="consultation"', $document);
        $this->assertStringContainsString('event.stopPropagation()', $document);
        $this->assertStringContainsString('window.scrollTo', $document);
        $this->assertStringContainsString('height: auto !important', $document);
    }

    public function test_preview_adds_a_viewport_tag_when_a_full_document_omits_it(): void
    {
        $page = new PromptLandingPage([
            'title' => 'Yoga studio',
            'html' => <<<'HTML'
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Keep me</title>
</head>
<body>
    <h1>Yoga studio</h1>
</body>
</html>
HTML,
            'css' => '.hero { display: flex; }',
            'js' => '',
        ]);

        $document = $page->renderedDocument();

        $this->assertStringContainsString(
            '<meta name="viewport" content="width=device-width, initial-scale=1">',
            $document,
        );
        $this->assertSame(1, substr_count($document, 'name="viewport"'));
        $this->assertStringContainsString('<title>Keep me</title>', $document);
        $this->assertStringContainsString('.hero { display: flex; }', $document);
        $this->assertStringContainsString('@media (max-width: 991px)', $document);
        $this->assertStringContainsString('window.scrollTo', $document);
        $this->assertStringContainsString('height: auto !important', $document);
    }

    public function test_has_setup_requires_both_website_and_purpose(): void
    {
        $page = new PromptLandingPage([
            'website_url' => 'https://lucos.com',
            'purpose' => '',
        ]);

        $this->assertFalse($page->hasSetup());

        $page->purpose = 'Generate demo requests';

        $this->assertTrue($page->hasSetup());
    }

    public function test_can_edit_requires_ready_html_an_idle_status_and_is_not_approved(): void
    {
        $pending = new PromptLandingPage([
            'html' => '<section></section>',
            'status' => 'pending_approval',
        ]);
        $approved = new PromptLandingPage([
            'html' => '<section></section>',
            'status' => 'approved',
        ]);
        $busy = new PromptLandingPage([
            'html' => '<section></section>',
            'status' => 'generating',
        ]);
        $empty = new PromptLandingPage([
            'html' => null,
            'status' => 'draft',
        ]);

        $this->assertTrue($pending->canEdit());
        $this->assertFalse($approved->canEdit());
        $this->assertFalse($busy->canEdit());
        $this->assertFalse($empty->canEdit());
    }

    public function test_normalize_website_url_adds_https_and_keeps_the_host(): void
    {
        $this->assertSame('https://lucos.com', PromptLandingPage::normalizeWebsiteUrl('lucos.com'));
        $this->assertSame('https://lucos.com', PromptLandingPage::normalizeWebsiteUrl('https://lucos.com/about?utm=1'));
        $this->assertSame('http://lucos.com', PromptLandingPage::normalizeWebsiteUrl('http://lucos.com'));
        $this->assertNull(PromptLandingPage::normalizeWebsiteUrl('not a domain'));
        $this->assertNull(PromptLandingPage::normalizeWebsiteUrl('ftp://lucos.com'));
    }

    public function test_pending_pages_can_be_approved_but_not_downloaded(): void
    {
        $page = new PromptLandingPage([
            'status' => 'pending_approval',
            'html' => '<section><h1>Yoga</h1></section>',
            'website_url' => 'https://lucos.com',
            'purpose' => 'Leads Page',
        ]);

        $this->assertTrue($page->canApprove());
        $this->assertFalse($page->canDownload());
        $this->assertFalse($page->composerLocked());
    }

    public function test_approved_pages_can_be_downloaded_and_lock_the_composer(): void
    {
        $page = new PromptLandingPage([
            'status' => 'approved',
            'html' => '<section><h1>Yoga</h1></section>',
            'website_url' => 'https://lucos.com',
            'purpose' => 'Leads Page',
        ]);

        $this->assertFalse($page->canApprove());
        $this->assertTrue($page->canDownload());
        $this->assertTrue($page->composerLocked());
    }

    public function test_display_website_returns_the_host(): void
    {
        $page = new PromptLandingPage([
            'website_url' => 'https://webcrawlers.com',
        ]);

        $this->assertSame('webcrawlers.com', $page->displayWebsite());
        $this->assertSame('webcrawlers.com', $page->returnCtaLabel());
        $this->assertSame('Unset', PromptLandingPage::purposeTabLabel(PromptLandingPage::UNSET_PURPOSE));
        $this->assertSame('Leads Page', PromptLandingPage::purposeTabLabel('Leads Page'));
    }

    public function test_return_cta_label_uses_the_brand_name_when_present(): void
    {
        $page = new PromptLandingPage([
            'website_url' => 'https://webcrawlers.com',
            'brief' => ['brand_name' => 'AttestPath'],
        ]);

        $this->assertSame('AttestPath', $page->returnCtaLabel());
    }

    public function test_purpose_slugs_round_trip_the_fixed_purposes(): void
    {
        $page = new PromptLandingPage(['purpose' => 'Leads Page']);

        $this->assertSame('leads-page', $page->purposeSlug());
        $this->assertSame('Leads Page', PromptLandingPage::purposeFromSlug('leads-page'));
        $this->assertSame('Signup page', PromptLandingPage::purposeFromSlug('signup-page'));
        $this->assertNull(PromptLandingPage::purposeFromSlug('unknown'));
    }

    public function test_normalize_host_strips_www_and_a_port(): void
    {
        $this->assertSame('yoga.example.com', PromptLandingPage::normalizeHost('WWW.Yoga.example.com:443'));
        $this->assertSame('yoga.example.com', PromptLandingPage::normalizeHost('yoga.example.com'));
    }

    public function test_partner_preview_url_uses_the_website_the_user_entered(): void
    {
        $attestpath = new PromptLandingPage([
            'status' => 'approved',
            'website_url' => 'https://www.attestpath.ai',
            'purpose' => 'Leads Page',
        ]);
        $attestpath->id = 38;

        $webcrawlers = new PromptLandingPage([
            'status' => 'approved',
            'website_url' => 'https://webcrawlers.com',
            'purpose' => 'Leads Page',
        ]);
        $webcrawlers->id = 37;

        $this->assertSame('https://attestpath.ai/lp/leads-page/38', $attestpath->partnerPreviewUrl());
        $this->assertSame('https://webcrawlers.com/lp/leads-page/37', $webcrawlers->partnerPreviewUrl());
    }

    public function test_partner_preview_url_is_null_when_the_page_is_not_approved(): void
    {
        $pending = new PromptLandingPage([
            'status' => 'pending_approval',
            'website_url' => 'https://attestpath.ai',
            'purpose' => 'Leads Page',
        ]);
        $pending->id = 39;

        $other = new PromptLandingPage([
            'status' => 'approved',
            'website_url' => 'https://news.example.com',
            'purpose' => 'Leads Page',
        ]);
        $other->id = 40;

        $this->assertNull($pending->partnerPreviewUrl());
        $this->assertSame('https://news.example.com/lp/leads-page/40', $other->partnerPreviewUrl());
    }

    public function test_preview_injects_the_brief_favicon_into_the_document_head(): void
    {
        $page = new PromptLandingPage([
            'title' => 'Yoga studio',
            'html' => '<section><h1>Yoga studio</h1></section>',
            'css' => '',
            'js' => '',
            'brief' => [
                'favicon_url' => 'https://yoga.example.com/favicon.ico',
            ],
        ]);

        $document = $page->renderedDocument();

        $this->assertStringContainsString(
            '<link rel="icon" href="https://yoga.example.com/favicon.ico">',
            $document,
        );
    }

    public function test_preview_does_not_replace_an_existing_favicon_link(): void
    {
        $page = new PromptLandingPage([
            'title' => 'Yoga studio',
            'html' => <<<'HTML'
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="icon" href="https://keep.example.com/icon.png">
    <title>Keep me</title>
</head>
<body>
    <h1>Yoga studio</h1>
</body>
</html>
HTML,
            'css' => '',
            'js' => '',
            'brief' => [
                'favicon_url' => 'https://yoga.example.com/favicon.ico',
            ],
        ]);

        $document = $page->renderedDocument();

        $this->assertStringContainsString('https://keep.example.com/icon.png', $document);
        $this->assertStringNotContainsString('https://yoga.example.com/favicon.ico', $document);
    }

    public function test_legacy_completed_pages_are_treated_as_pending_approval(): void
    {
        $page = new PromptLandingPage([
            'status' => 'completed',
            'html' => '<section><h1>Yoga</h1></section>',
            'website_url' => 'https://lucos.com',
            'purpose' => 'Leads Page',
        ]);

        $this->assertTrue($page->canApprove());
        $this->assertFalse($page->canDownload());
        $this->assertFalse($page->isBusy());
    }
}
