<?php

namespace Tests\Feature;

use App\Models\PromptLandingPage;
use App\Models\User;
use App\Services\PublicPromptLandingPageDocument;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Fixtures\PromptLandingPageEditorDocument;
use Tests\TestCase;

class PromptLandingPageEditorControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_guests_are_redirected_from_the_editor(): void
    {
        $page = PromptLandingPage::factory()->approved()->create();

        $this->get(route('prompt-landing-pages.editor', $page))
            ->assertRedirect(route('login'));
    }

    public function test_another_user_receives_403_from_the_editor(): void
    {
        $page = PromptLandingPage::factory()->approved()->create();
        $other = User::factory()->create();

        $this->actingAs($other)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertForbidden();
    }

    public function test_a_page_without_html_returns_404_from_the_editor(): void
    {
        $user = User::factory()->create();
        $page = PromptLandingPage::factory()->configured()->for($user)->create();

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertNotFound();
    }

    public function test_a_busy_page_returns_409_from_the_editor(): void
    {
        $user = User::factory()->create();
        $page = PromptLandingPage::factory()->completed()->for($user)->create([
            'status' => 'generating',
        ]);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertStatus(409);
    }

    public function test_the_owner_can_open_the_editor_for_a_ready_page(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertOk()
            ->assertSee('id="gjs"', false)
            ->assertSee('Visual', false)
            ->assertSee('Grow Your Business Faster', false)
            ->assertSee('id="editorClassList"', false)
            ->assertSee('Classes', false)
            ->assertSee('Add a piece to the current page', false)
            ->assertSee('Full-width blocks that match a landing page', false)
            ->assertDontSee('Text + Image', false)
            ->assertDontSee('Embedded video', false)
            ->assertSee('Preview a snapshot without changing the live page', false)
            ->assertSee('Open in Editor loads it into the editor', false)
            ->assertSee('id="editorOpenVersion"', false)
            ->assertSee('id="editorLoader"', false)
            ->assertSee('Loading page', false)
            ->assertSee('"open_version":1', false)
            ->assertSee('Delete removes any version except the live page and the original generated page', false)
            ->assertSee('publishUrlTemplate', false)
            ->assertSee('deleteUrlTemplate', false)
            ->assertSee('Save draft', false)
            ->assertDontSee('id="editorReset"', false)
            ->assertSee('draftUrl', false)
            ->assertSee('versionPreviewUrlTemplate', false)
            ->assertSee('Original', false);
    }

    public function test_opening_the_editor_records_the_live_page_as_original_version_one(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertOk();

        $this->assertDatabaseHas('prompt_landing_page_versions', [
            'prompt_landing_page_id' => $page->id,
            'version' => 1,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
        ]);
        $this->assertSame(1, $page->versions()->count());
    }

    public function test_editor_canvas_base_css_does_not_force_a_white_page_background(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertDontSee('background-color: transparent;', false)
            ->assertSee('height: auto;', false)
            ->assertSee('overflow-y: visible;', false)
            ->assertSee('overflow-x: hidden;', false);
    }

    public function test_editor_canvas_base_css_shows_javascript_reveal_content(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertSee('.reveal, .reveal-up, .reveal-left, .reveal-right, .fade-in, .fade-up, .slide-up, .js-reveal, [data-reveal], [data-animate] { opacity: 1 !important;', false)
            ->assertSee('transform: none !important;', false)
            ->assertSee('.lp-inline-label::before, .lp-inline-label::after { content: none !important; }', false);
    }

    public function test_editor_canvas_base_css_keeps_accordions_open(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertSee('*:not(summary) { display: block !important;', false)
            ->assertSee('details::details-content { display: block !important;', false);
    }

    public function test_editor_data_returns_the_published_document_even_when_a_leftover_table_draft_exists(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->editorDraft()->create([
            'html' => '<h1>Draft heading</h1>',
            'css' => 'h1 { color: blue; }',
            'js' => 'var leftover = 1;',
        ]);

        $this->actingAs($user)
            ->getJson(route('prompt-landing-pages.editor.data', $page))
            ->assertOk()
            ->assertJsonPath('from_draft', false)
            ->assertJsonPath('html', PromptLandingPageEditorDocument::html())
            ->assertJsonPath('saved_html', PromptLandingPageEditorDocument::html())
            ->assertJsonPath('css', PromptLandingPageEditorDocument::css())
            ->assertJsonPath('js', PromptLandingPageEditorDocument::js())
            ->assertJsonPath('open_version', 1);
    }

    public function test_the_editor_page_opens_the_published_document_not_a_leftover_table_draft(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->editorDraft()->create([
            'html' => '<h1>Leftover draft</h1>',
            'css' => 'h1 { color: blue; }',
            'js' => 'var leftover = 1;',
        ]);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor', $page))
            ->assertOk()
            ->assertSee('Grow Your Business Faster', false)
            ->assertDontSee('Leftover draft', false);
    }

    public function test_save_updates_live_html_and_css_and_keeps_javascript_and_form_markup(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $html = str_replace('Grow Your Business Faster', 'Grow Your Business With AI', PromptLandingPageEditorDocument::html());
        $css = PromptLandingPageEditorDocument::css()."\n".'.hero h1 { color: #cc0000; }';

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => $html,
                'css' => $css,
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk()
            ->assertJsonPath('ok', true);

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business With AI', $page->html);
        $this->assertStringContainsString('color: #cc0000', $page->css);
        $this->assertStringContainsString('@media (max-width: 767px)', $page->css);
        $this->assertSame(PromptLandingPageEditorDocument::js(), $page->js);
        $this->assertStringContainsString('id="lead-form"', $page->html);
        $this->assertStringContainsString('name="email"', $page->html);
        $this->assertStringContainsString('type="email"', $page->html);
        $this->assertStringContainsString('required', $page->html);
        $this->assertStringContainsString('name="source"', $page->html);
        $this->assertStringContainsString('data-form="lead"', $page->html);
        $this->assertStringContainsString('data-analytics="header"', $page->html);
        $this->assertStringContainsString('utm_source=hero', $page->html);
        $this->assertSame(2, $page->versions()->count());
        $this->assertNull($page->editorDraft);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.preview', $page))
            ->assertOk()
            ->assertSee('Grow Your Business With AI', false)
            ->assertSee('color: #cc0000', false)
            ->assertSee("document.getElementById('lead-form')", false);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.download', $page))
            ->assertOk()
            ->assertSee('Grow Your Business With AI', false);

        $public = (new PublicPromptLandingPageDocument)->render($page, '11111111-1111-1111-1111-111111111111');
        $this->assertStringContainsString('Grow Your Business With AI', $public);
        $this->assertStringContainsString('data-admedia-lead="1"', $public);
        $this->assertStringContainsString('name="email"', $public);
        $this->assertStringContainsString("document.getElementById('lead-form')", $public);
    }

    public function test_save_draft_does_not_change_the_live_or_public_document(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.draft', $page), [
                'html' => '<h1>Only a draft</h1>',
                'css' => 'h1 { color: pink; }',
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonPath('status', 'draft')
            ->assertJsonPath('kind', 'draft')
            ->assertJsonPath('version', 2)
            ->assertJsonPath('open_version', 2)
            ->assertJsonPath('from_draft', false)
            ->assertJsonPath('versions.0.kind', 'draft')
            ->assertJsonPath('versions.1.kind', 'published')
            ->assertJsonPath('versions.1.version', 1)
            ->assertJsonPath('versions.1.is_original', true)
            ->assertJsonPath('versions.1.is_live', true);

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertStringNotContainsString('Only a draft', $page->html);
        $this->assertDatabaseHas('prompt_landing_page_versions', [
            'prompt_landing_page_id' => $page->id,
            'kind' => 'draft',
            'html' => '<h1>Only a draft</h1>',
        ]);
        $this->assertDatabaseHas('prompt_landing_page_versions', [
            'prompt_landing_page_id' => $page->id,
            'version' => 1,
            'kind' => 'published',
        ]);
        $this->assertDatabaseHas('prompt_landing_page_versions', [
            'prompt_landing_page_id' => $page->id,
            'version' => 1,
            'kind' => 'published',
        ]);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.preview', $page))
            ->assertSee('Grow Your Business Faster', false)
            ->assertDontSee('Only a draft', false);
    }

    public function test_another_user_receives_403_from_save_draft(): void
    {
        $page = $this->readyPage(User::factory()->create());

        $this->actingAs(User::factory()->create())
            ->postJson(route('prompt-landing-pages.editor.draft', $page), [
                'html' => '<h1>Stolen</h1>',
                'css' => '',
                'js' => '',
            ])
            ->assertForbidden();
    }

    public function test_reset_discards_the_draft_and_returns_the_last_saved_document(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->editorDraft()->create([
            'html' => '<h1>Draft heading</h1>',
            'css' => 'h1 { color: blue; }',
            'js' => 'var draft = 1;',
        ]);

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.reset', $page))
            ->assertOk()
            ->assertJsonPath('from_draft', false)
            ->assertJsonPath('html', PromptLandingPageEditorDocument::html());

        $this->assertNull($page->refresh()->editorDraft);
    }

    public function test_restore_loads_a_snapshot_without_changing_the_live_page(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'draft',
            'html' => '<h1>Version one</h1>',
            'css' => 'h1 { color: green; }',
            'js' => 'var version = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.versions.restore', [$page, 1]))
            ->assertOk()
            ->assertJsonPath('html', '<h1>Version one</h1>')
            ->assertJsonPath('css', 'h1 { color: green; }')
            ->assertJsonPath('js', 'var version = 1;')
            ->assertJsonPath('kind', 'draft')
            ->assertJsonPath('status', 'loaded')
            ->assertJsonPath('open_version', 1)
            ->assertJsonPath('version', 1);

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertStringNotContainsString('Version one', $page->html);
        $this->assertSame(PromptLandingPageEditorDocument::js(), $page->js);
        $this->assertSame(1, $page->versions()->count());
    }

    public function test_make_live_publishes_that_snapshot_without_creating_a_new_version(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
            'created_by' => $user->id,
            'created_at' => now(),
        ]);
        $page->versions()->create([
            'version' => 2,
            'kind' => 'draft',
            'html' => '<h1>Draft to go live</h1>',
            'css' => 'h1 { color: navy; }',
            'js' => 'var draftLive = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.versions.publish', [$page, 2]))
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonPath('status', 'saved')
            ->assertJsonPath('version', 2)
            ->assertJsonPath('kind', 'published')
            ->assertJsonPath('html', '<h1>Draft to go live</h1>')
            ->assertJsonPath('open_version', 2)
            ->assertJsonPath('versions.0.version', 2)
            ->assertJsonPath('versions.0.is_live', true)
            ->assertJsonPath('versions.0.kind', 'published')
            ->assertJsonPath('versions.1.is_live', false);

        $page->refresh();

        $this->assertSame('<h1>Draft to go live</h1>', $page->html);
        $this->assertSame('h1 { color: navy; }', $page->css);
        $this->assertSame('var draftLive = 1;', $page->js);
        $this->assertSame(2, $page->versions()->count());
        $this->assertDatabaseHas('prompt_landing_page_versions', [
            'prompt_landing_page_id' => $page->id,
            'version' => 2,
            'kind' => 'published',
            'html' => '<h1>Draft to go live</h1>',
        ]);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.preview', $page))
            ->assertOk()
            ->assertSee('Draft to go live', false);
    }

    public function test_another_user_receives_403_from_make_live(): void
    {
        $page = $this->readyPage(User::factory()->create());
        $page->versions()->create([
            'version' => 1,
            'kind' => 'draft',
            'html' => '<h1>Secret</h1>',
            'css' => '',
            'js' => '',
            'created_by' => $page->user_id,
            'created_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->postJson(route('prompt-landing-pages.editor.versions.publish', [$page, 1]))
            ->assertForbidden();
    }

    public function test_delete_removes_a_draft_without_changing_the_live_page(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
            'created_by' => $user->id,
            'created_at' => now(),
        ]);
        $page->versions()->create([
            'version' => 2,
            'kind' => 'draft',
            'html' => '<h1>Throw away</h1>',
            'css' => 'h1 { color: pink; }',
            'js' => 'var trash = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->deleteJson(route('prompt-landing-pages.editor.versions.destroy', [$page, 2]))
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonPath('status', 'deleted')
            ->assertJsonPath('deleted_version', 2)
            ->assertJsonPath('html', PromptLandingPageEditorDocument::html())
            ->assertJsonPath('open_version', 1);

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertSame(1, $page->versions()->count());
        $this->assertFalse($page->versions()->where('kind', 'draft')->exists());
    }

    public function test_delete_returns_422_for_the_original_generated_version(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->deleteJson(route('prompt-landing-pages.editor.versions.destroy', [$page, 1]))
            ->assertUnprocessable();

        $this->assertSame(1, $page->versions()->count());
    }

    public function test_delete_removes_a_published_version_that_is_not_live(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'published',
            'html' => '<h1>Original generated</h1>',
            'css' => 'h1 { color: black; }',
            'js' => 'var original = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);
        $page->versions()->create([
            'version' => 2,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
            'created_by' => $user->id,
            'created_at' => now(),
        ]);
        $page->versions()->create([
            'version' => 3,
            'kind' => 'published',
            'html' => '<h1>Old published</h1>',
            'css' => 'h1 { color: gray; }',
            'js' => 'var old = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->deleteJson(route('prompt-landing-pages.editor.versions.destroy', [$page, 3]))
            ->assertOk()
            ->assertJsonPath('deleted_version', 3)
            ->assertJsonPath('html', PromptLandingPageEditorDocument::html());

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertSame(2, $page->versions()->count());
        $this->assertFalse($page->versions()->where('version', 3)->exists());
    }

    public function test_delete_returns_422_for_the_live_version(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'kind' => 'published',
            'html' => '<h1>Original generated</h1>',
            'css' => 'h1 { color: black; }',
            'js' => 'var original = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);
        $page->versions()->create([
            'version' => 2,
            'kind' => 'published',
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->deleteJson(route('prompt-landing-pages.editor.versions.destroy', [$page, 2]))
            ->assertUnprocessable();

        $this->assertSame(2, $page->versions()->count());
    }

    public function test_another_user_receives_403_from_draft_delete(): void
    {
        $page = $this->readyPage(User::factory()->create());
        $page->versions()->create([
            'version' => 1,
            'kind' => 'draft',
            'html' => '<h1>Secret draft</h1>',
            'css' => '',
            'js' => '',
            'created_by' => $page->user_id,
            'created_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->deleteJson(route('prompt-landing-pages.editor.versions.destroy', [$page, 1]))
            ->assertForbidden();
    }

    public function test_another_user_receives_403_from_version_restore(): void
    {
        $page = $this->readyPage(User::factory()->create());
        $page->versions()->create([
            'version' => 1,
            'html' => '<h1>Secret snapshot</h1>',
            'css' => '',
            'js' => '',
            'created_by' => $page->user_id,
            'created_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->postJson(route('prompt-landing-pages.editor.versions.restore', [$page, 1]))
            ->assertForbidden();
    }

    public function test_version_preview_shows_that_snapshot_without_changing_the_live_page(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $page->versions()->create([
            'version' => 1,
            'html' => '<h1>Version one preview</h1>',
            'css' => 'h1 { color: green; }',
            'js' => 'var versionPreview = 1;',
            'created_by' => $user->id,
            'created_at' => now(),
        ]);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor.versions.preview', [$page, 1]))
            ->assertOk()
            ->assertSee('Version one preview', false)
            ->assertSee('color: green', false)
            ->assertSee('var versionPreview = 1;', false);

        $page->refresh();

        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertStringNotContainsString('Version one preview', $page->html);
    }

    public function test_another_user_receives_403_from_version_preview(): void
    {
        $page = $this->readyPage(User::factory()->create());
        $page->versions()->create([
            'version' => 1,
            'html' => '<h1>Secret snapshot</h1>',
            'css' => '',
            'js' => '',
            'created_by' => $page->user_id,
            'created_at' => now(),
        ]);

        $this->actingAs(User::factory()->create())
            ->get(route('prompt-landing-pages.editor.versions.preview', [$page, 1]))
            ->assertForbidden();
    }

    public function test_missing_version_preview_returns_404(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->get(route('prompt-landing-pages.editor.versions.preview', [$page, 99]))
            ->assertNotFound();
    }

    public function test_preview_keeps_style_panel_css_after_the_page_stylesheet(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $css = PromptLandingPageEditorDocument::css()."\n".'.stories-section { background-color: #1a0107; }';

        $this->actingAs($user)
            ->post(route('prompt-landing-pages.editor.preview', $page), [
                'html' => PromptLandingPageEditorDocument::html(),
                'css' => $css,
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk()
            ->assertSee('background-color: #1a0107', false)
            ->assertSee('--theme:', false);
    }

    public function test_save_draft_keeps_style_panel_css_after_the_page_stylesheet(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $css = PromptLandingPageEditorDocument::css()."\n".'.stories-section { background-color: #1a0107; }';

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.draft', $page), [
                'html' => PromptLandingPageEditorDocument::html(),
                'css' => $css,
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk()
            ->assertJsonPath('ok', true)
            ->assertJsonPath('status', 'draft');

        $draft = $page->versions()->where('kind', 'draft')->first();

        $this->assertNotNull($draft);
        $this->assertStringContainsString('--theme:', (string) $draft->css);
        $this->assertStringContainsString('.stories-section { background-color: #1a0107; }', (string) $draft->css);
        $this->assertGreaterThan(
            strpos((string) $draft->css, '--theme:'),
            strpos((string) $draft->css, 'background-color: #1a0107'),
        );
        $this->assertStringNotContainsString('background-color: #1a0107', (string) $page->refresh()->css);
    }

    public function test_preview_assembles_unsaved_html_css_and_javascript(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->post(route('prompt-landing-pages.editor.preview', $page), [
                'html' => '<section><h1>Unsaved preview</h1></section>',
                'css' => 'h1 { color: purple; }',
                'js' => 'var preview = 1;',
            ])
            ->assertOk()
            ->assertSee('Unsaved preview', false)
            ->assertSee('color: purple', false)
            ->assertSee('var preview = 1;', false)
            ->assertSee('<meta name="viewport"', false);
    }

    public function test_editor_preview_keeps_accordions_closed(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->post(route('prompt-landing-pages.editor.preview', $page), [
                'html' => '<details><summary>Question</summary><p>Answer copy</p></details>',
                'css' => 'summary { font-weight: 700; }',
                'js' => '',
            ])
            ->assertOk()
            ->assertSee('<details>', false)
            ->assertSee('Question', false)
            ->assertSee('Answer copy', false)
            ->assertDontSee('<details open', false)
            ->assertDontSee('*:not(summary) { display: block !important;', false);
    }

    public function test_save_does_not_persist_open_accordions(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);
        $html = '<details><summary>Question</summary><p>Answer copy</p></details>';

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => $html,
                'css' => PromptLandingPageEditorDocument::css(),
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk()
            ->assertJsonPath('ok', true);

        $page->refresh();

        $this->assertStringContainsString('<details>', $page->html);
        $this->assertStringContainsString('Answer copy', $page->html);
        $this->assertStringNotContainsString('<details open', $page->html);
        $this->assertStringNotContainsString('*:not(summary)', $page->css);
    }

    public function test_save_does_not_persist_editor_canvas_chrome_in_the_live_html(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => '<style>html, body, [data-gjs-type="wrapper"] { min-height: 100%; } body { background-color: transparent; }</style><style>.final-cta { background-color: #e6d5f4; }</style><section class="hero" draggable="true"><h1>Grow Your Business Faster</h1></section>',
                'css' => PromptLandingPageEditorDocument::css(),
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk();

        $page->refresh();

        $this->assertStringNotContainsString('data-gjs-type', $page->html);
        $this->assertStringNotContainsString('background-color: transparent', $page->html);
        $this->assertStringNotContainsString('<style>', $page->html);
        $this->assertStringNotContainsString('draggable', $page->html);
        $this->assertStringContainsString('Grow Your Business Faster', $page->html);
        $this->assertStringContainsString('.final-cta { background-color: #e6d5f4; }', $page->css);
    }

    public function test_save_publishes_the_current_editor_document_and_reopening_shows_it(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => str_replace('Grow Your Business Faster', 'Grow Your Business With AI', PromptLandingPageEditorDocument::html()),
                'css' => PromptLandingPageEditorDocument::css(),
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk();

        $this->actingAs($user)
            ->getJson(route('prompt-landing-pages.editor.data', $page))
            ->assertOk()
            ->assertJsonPath('from_draft', false)
            ->assertSee('Grow Your Business With AI', false);

        $this->assertStringContainsString('Grow Your Business With AI', $page->refresh()->html);
    }

    public function test_save_keeps_head_scripts_and_only_applies_body_edits(): void
    {
        $user = User::factory()->create();
        $page = PromptLandingPage::factory()->approved()->for($user)->create([
            'html' => PromptLandingPageEditorDocument::fullHtml(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
        ]);

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => str_replace(
                    'Grow Your Business Faster',
                    'Grow Your Business With AI',
                    PromptLandingPageEditorDocument::html(),
                ).'<script>alert(1)</script>',
                'css' => '[data-gjs-type="wrapper"] { min-height: 100vh; } .hero h1 { color: red; }',
                'js' => '',
            ])
            ->assertOk();

        $page->refresh();

        $this->assertStringContainsString('https://cdn.example.test/lp-analytics.js', $page->html);
        $this->assertStringContainsString('window.LP_PAGE = { id: 39 };', $page->html);
        $this->assertStringContainsString('Grow Your Business With AI', $page->html);
        $this->assertStringNotContainsString('alert(1)', $page->html);
        $this->assertSame(PromptLandingPageEditorDocument::css(), $page->css);
        $this->assertSame(PromptLandingPageEditorDocument::js(), $page->js);
    }

    public function test_preview_keeps_original_head_scripts_with_unsaved_body_edits(): void
    {
        $user = User::factory()->create();
        $page = PromptLandingPage::factory()->approved()->for($user)->create([
            'html' => PromptLandingPageEditorDocument::fullHtml(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
        ]);

        $this->actingAs($user)
            ->post(route('prompt-landing-pages.editor.preview', $page), [
                'html' => '<section><h1>Unsaved preview</h1></section>',
                'css' => 'h1 { color: purple; }',
                'js' => 'var preview = 1;',
            ])
            ->assertOk()
            ->assertSee('https://cdn.example.test/lp-analytics.js', false)
            ->assertSee('window.LP_PAGE = { id: 39 };', false)
            ->assertSee('Unsaved preview', false)
            ->assertSee('color: purple', false)
            ->assertSee('var preview = 1;', false);
    }

    public function test_save_rejects_javascript_urls_and_script_tags_in_html(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [
                'html' => '<a href="javascript:alert(1)">X</a><script>alert(1)</script><form><input name="email"></form>',
                'css' => '',
                'js' => PromptLandingPageEditorDocument::js(),
            ])
            ->assertOk();

        $page->refresh();

        $this->assertStringNotContainsString('<script>', $page->html);
        $this->assertStringNotContainsString('javascript:alert', $page->html);
        $this->assertStringContainsString('name="email"', $page->html);
        $this->assertSame(PromptLandingPageEditorDocument::js(), $page->js);
    }

    public function test_save_requires_html_css_and_js_fields(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->putJson(route('prompt-landing-pages.editor.update', $page), [])
            ->assertUnprocessable()
            ->assertJsonValidationErrors(['html', 'css', 'js']);
    }

    public function test_save_draft_requires_html_css_and_js_fields(): void
    {
        $user = User::factory()->create();
        $page = $this->readyPage($user);

        $this->actingAs($user)
            ->postJson(route('prompt-landing-pages.editor.draft', $page), [])
            ->assertUnprocessable()
            ->assertJsonValidationErrors(['html', 'css', 'js']);
    }

    private function readyPage(User $user): PromptLandingPage
    {
        return PromptLandingPage::factory()->approved()->for($user)->create([
            'html' => PromptLandingPageEditorDocument::html(),
            'css' => PromptLandingPageEditorDocument::css(),
            'js' => PromptLandingPageEditorDocument::js(),
        ]);
    }
}
