<?php

namespace Tests\Unit\Services\PromptLandingPageEditor;

use App\Models\PromptLandingPage;
use App\Models\PromptLandingPageVersion;
use App\Services\PromptLandingPageEditor\DeleteDraftVersion;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Tests\TestCase;

class DeleteDraftVersionTest extends TestCase
{
    use RefreshDatabase;

    public function test_it_deletes_a_draft_version_without_changing_the_live_page(): void
    {
        $page = PromptLandingPage::factory()->approved()->create([
            'html' => '<h1>Live</h1>',
        ]);
        PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 1,
            'html' => '<h1>Live</h1>',
        ]);
        $draft = PromptLandingPageVersion::factory()->draft()->for($page, 'page')->create([
            'version' => 2,
            'html' => '<h1>Draft</h1>',
        ]);

        (new DeleteDraftVersion)->handle($page, $draft);

        $page->refresh();

        $this->assertSame('<h1>Live</h1>', $page->html);
        $this->assertSame(1, $page->versions()->count());
        $this->assertFalse($page->versions()->where('version', 2)->exists());
    }

    public function test_it_returns_422_when_the_version_is_the_original_generated_page(): void
    {
        $page = PromptLandingPage::factory()->approved()->create();
        $original = PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 1,
        ]);

        $this->expectException(HttpException::class);

        try {
            (new DeleteDraftVersion)->handle($page, $original);
        } catch (HttpException $exception) {
            $this->assertSame(422, $exception->getStatusCode());

            throw $exception;
        }
    }

    public function test_it_deletes_a_published_version_that_is_not_live(): void
    {
        $page = PromptLandingPage::factory()->approved()->create([
            'html' => '<h1>Live</h1>',
            'css' => 'h1 { color: red; }',
            'js' => 'var live = 1;',
        ]);
        PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 1,
            'html' => '<h1>Original</h1>',
            'css' => 'h1 { color: black; }',
            'js' => 'var original = 1;',
        ]);
        PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 2,
            'html' => '<h1>Live</h1>',
            'css' => 'h1 { color: red; }',
            'js' => 'var live = 1;',
        ]);
        $old = PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 3,
            'html' => '<h1>Old published</h1>',
            'css' => 'h1 { color: gray; }',
            'js' => 'var old = 1;',
        ]);

        (new DeleteDraftVersion)->handle($page, $old);

        $page->refresh();

        $this->assertSame('<h1>Live</h1>', $page->html);
        $this->assertSame(2, $page->versions()->count());
        $this->assertFalse($page->versions()->where('version', 3)->exists());
    }

    public function test_it_returns_422_when_the_version_is_live(): void
    {
        $page = PromptLandingPage::factory()->approved()->create([
            'html' => '<h1>Live</h1>',
        ]);
        PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 1,
            'html' => '<h1>Original</h1>',
        ]);
        $live = PromptLandingPageVersion::factory()->for($page, 'page')->create([
            'version' => 2,
            'html' => '<h1>Live</h1>',
        ]);

        $this->expectException(HttpException::class);

        try {
            (new DeleteDraftVersion)->handle($page, $live);
        } catch (HttpException $exception) {
            $this->assertSame(422, $exception->getStatusCode());

            throw $exception;
        }
    }

    public function test_it_returns_404_when_the_snapshot_belongs_to_another_page(): void
    {
        $page = PromptLandingPage::factory()->approved()->create();
        $foreign = PromptLandingPageVersion::factory()->draft()->create();

        $this->expectException(HttpException::class);

        try {
            (new DeleteDraftVersion)->handle($page, $foreign);
        } catch (HttpException $exception) {
            $this->assertSame(404, $exception->getStatusCode());

            throw $exception;
        }
    }
}
