<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;

use Tests\TestCase;

use App\Models\User;
use App\Models\Page;
use App\Models\PageRevision;

class PageBuilderTest extends TestCase
{
    use RefreshDatabase;

    public function test_authenticated_user_can_create_page() {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->post('/dashboard/page-admin/landing-pages/create', [
            'title'      => 'Test Page',
            'content'    => json_encode(['blocks' => []]),
            'publish'    => true,
            'mainpage'   => false,
            'linked'     => false,
            'linkorder'  => 1,
            'visibility' => 'public',
        ]);
    
        $response->assertRedirect();
        $this->assertDatabaseHas('pages', ['title' => 'Test Page']);
        $this->assertDatabaseHas('page_revisions', ['title' => 'Test Page', 'label' => 'published']);
    }

    public function test_authenticated_user_can_update_page() {
        $user = User::factory()->create();

        $page = Page::factory()->create(['user_id' => $user->id]);
        $revision = PageRevision::factory()->create([
            'page_id' => $page->id,
            'user_id' => $user->id,
            'active' => true,
        ]);
    
        $response = $this->actingAs($user)->patch('/dashboard/page-admin/landing-pages/patch', [
            'revision_uuid' => $revision->uuid,
            'title'         => 'Updated Title',
            'content'       => json_encode(['blocks' => [['type' => 'text', 'data' => 'updated']]]),
            'publish'       => true,
            'mainpage'      => false,
            'linked'        => false,
            'linkorder'     => 2,
            'visibility'    => 'public',
        ]);
    
        $response->assertRedirect();
        
        $this->assertDatabaseHas('pages', [
            'id'    => $page->id,
            'title' => 'Updated Title',
            'is_published' => true,
        ]);
    
        $this->assertDatabaseHas('page_revisions', [
            'id'    => $revision->id,
            'title' => 'Updated Title',
            'label' => 'published',
        ]);
    }

    public function test_authenticated_user_can_delete_page() {
        $user = User::factory()->create();
        $page = Page::factory()->create(['user_id' => $user->id]);
    
        $response = $this->actingAs($user)->delete('/dashboard/page-admin/landing-pages/delete', [
            'id' => $page->id,
        ]);
    
        $response->assertRedirect(route('page-builder.index'));
        $this->assertDatabaseMissing('pages', ['id' => $page->id]);
    }

    public function test_unauthorized_user_cannot_delete_page() {
        $owner = User::factory()->create();
        $otherUser = User::factory()->create();
        $page = Page::factory()->create(['user_id' => $owner->id]);

        $response = $this->actingAs($otherUser)->delete('/dashboard/page-admin/landing-pages/delete', [
            'id' => $page->id,
        ]);

        $response->assertRedirect(route('page-builder.index'));
        $response->assertSessionHas('error', 'Du er ikke forfatteren av denne siden og kan derfor ikke slette den.');

        $this->assertDatabaseHas('pages', ['id' => $page->id]);
    }

    public function test_unauthenticated_user_cannot_access_pagebuilder() {
        $response = $this->get('/dashboard/page-admin');

        $response->assertRedirect('/login');
    }

    public function test_user_can_publish_existing_revision() {
        $user = User::factory()->create();
        $page = Page::factory()->create([
            'user_id' => $user->id,
            'is_published' => false,
            'main' => false,
            'visibility' => 'public',
        ]);

        $revision = PageRevision::factory()->create([
            'page_id' => $page->id,
            'user_id' => $user->id,
            'active' => true,
            'label' => 'manual-save',
            'content' => json_encode(['blocks' => [['type' => 'text', 'data' => 'initial']]]),
        ]);

        $response = $this->actingAs($user)->patch('/dashboard/page-admin/landing-pages/patch', [
            'revision_uuid' => $revision->uuid,
            'title'         => 'Published Update',
            'content'       => json_encode(['blocks' => [['type' => 'text', 'data' => 'updated']]]),
            'publish'       => true,
            'mainpage'      => false,
            'linked'        => false,
            'linkorder'     => 1,
            'visibility'    => 'public',
        ]);

        $response->assertRedirect();
        $this->assertDatabaseHas('pages', [
            'id' => $page->id,
            'title' => 'Published Update',
            'is_published' => true,
        ]);
        $this->assertDatabaseHas('page_revisions', [
            'id' => $revision->id,
            'title' => 'Published Update',
            'label' => 'published',
        ]);
    }

    public function test_user_can_save_as_new_revision() {
        $user = User::factory()->create();
        $page = Page::factory()->create(['user_id' => $user->id]);
    
        PageRevision::factory()->create([
            'page_id' => $page->id,
            'user_id' => $user->id,
            'active' => true,
            'label' => 'published',
            'content' => json_encode(['blocks' => [['type' => 'text', 'data' => 'original']]]),
        ]);
    
        $response = $this->actingAs($user)->post('/dasboard/page-admin/landing-pages/save-as', [
            'page_id'    => $page->id,
            'title'      => 'Saved As New Revision',
            'content'    => json_encode(['blocks' => [['type' => 'text', 'data' => 'new version']]]),
            'publish'    => false,
            'mainpage'   => false,
            'linked'     => false,
            'linkorder'  => 1,
            'visibility' => 'public',
        ]);
    
        $response->assertRedirect();
    
        $this->assertDatabaseHas('page_revisions', [
            'page_id' => $page->id,
            'title'   => 'Saved As New Revision',
            'label'   => 'manual-save',
            'active'  => false,
        ]);

        $this->assertDatabaseCount('page_revisions', 2);
    }
}
