<?php

namespace FluxCms\Core\Tests\Feature;

use FluxCms\Core\Models\Page;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Orchestra\Testbench\TestCase;

class PageManagementTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->loadLaravelMigrations();
        $this->artisan('migrate');
    }

    public function test_can_create_page()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite', 'en' => 'Test Page'],
            'slug' => ['de' => '/test-seite', 'en' => '/test-page'],
            'is_published' => true,
        ]);

        $this->assertDatabaseHas('flux_cms_pages', [
            'id' => $page->id,
            'domain_key' => 'test',
        ]);

        $this->assertEquals('Test Seite', $page->getTranslation('title', 'de'));
        $this->assertEquals('Test Page', $page->getTranslation('title', 'en'));
    }

    public function test_can_add_components_to_page()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite'],
            'slug' => ['de' => '/test'],
            'is_published' => true,
        ]);

        $component = $page->allComponents()->create([
            'component_class' => 'TestComponent',
            'order' => 1,
            'content' => [
                'title' => ['de' => 'Komponenten Titel'],
                'text' => ['de' => 'Komponenten Text'],
            ],
            'is_active' => true,
        ]);

        $this->assertDatabaseHas('flux_cms_page_components', [
            'page_id' => $page->id,
            'component_class' => 'TestComponent',
            'order' => 1,
        ]);

        $this->assertEquals(1, $page->allComponents()->count());
        $this->assertEquals('Komponenten Titel', $component->getTranslatedContent('de')['title']);
    }

    public function test_can_publish_and_unpublish_page()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite'],
            'slug' => ['de' => '/test'],
            'is_published' => false,
        ]);

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

        $page->publish();
        $this->assertTrue($page->fresh()->is_published);
        $this->assertNotNull($page->fresh()->published_at);

        $page->unpublish();
        $this->assertFalse($page->fresh()->is_published);
    }

    public function test_can_create_page_version()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite'],
            'slug' => ['de' => '/test'],
            'is_published' => true,
        ]);

        $page->allComponents()->create([
            'component_class' => 'TestComponent',
            'order' => 1,
            'content' => ['title' => ['de' => 'Original']],
        ]);

        $version = $page->createVersion('Initial version');

        $this->assertDatabaseHas('flux_cms_page_versions', [
            'page_id' => $page->id,
            'change_description' => 'Initial version',
        ]);

        $this->assertNotNull($version->page_data);
        $this->assertNotNull($version->components_data);
        $this->assertEquals(1, $page->versions()->count());
    }

    public function test_page_scope_by_domain()
    {
        Page::create([
            'domain_key' => 'domain1',
            'title' => ['de' => 'Domain 1 Seite'],
            'slug' => ['de' => '/domain1'],
        ]);

        Page::create([
            'domain_key' => 'domain2',
            'title' => ['de' => 'Domain 2 Seite'],
            'slug' => ['de' => '/domain2'],
        ]);

        $domain1Pages = Page::forDomain('domain1')->get();
        $domain2Pages = Page::forDomain('domain2')->get();

        $this->assertEquals(1, $domain1Pages->count());
        $this->assertEquals(1, $domain2Pages->count());
        $this->assertEquals('Domain 1 Seite', $domain1Pages->first()->getTranslation('title', 'de'));
    }

    public function test_page_scope_by_slug()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite'],
            'slug' => ['de' => '/test-seite', 'en' => '/test-page'],
        ]);

        $foundPage = Page::bySlug('/test-seite', 'de')->first();
        $this->assertEquals($page->id, $foundPage->id);

        $foundPage = Page::bySlug('/test-page', 'en')->first();
        $this->assertEquals($page->id, $foundPage->id);

        $notFound = Page::bySlug('/not-found', 'de')->first();
        $this->assertNull($notFound);
    }

    public function test_component_can_be_duplicated()
    {
        $page = Page::create([
            'domain_key' => 'test',
            'title' => ['de' => 'Test Seite'],
            'slug' => ['de' => '/test'],
        ]);

        $originalComponent = $page->allComponents()->create([
            'component_class' => 'TestComponent',
            'order' => 1,
            'content' => ['title' => ['de' => 'Original']],
        ]);

        $duplicate = $originalComponent->duplicate();

        $this->assertEquals(2, $page->allComponents()->count());
        $this->assertEquals($originalComponent->content, $duplicate->content);
        $this->assertEquals(2, $duplicate->order);
        $this->assertNotEquals($originalComponent->id, $duplicate->id);
    }

    protected function getPackageProviders($app)
    {
        return [
            \FluxCms\Core\FluxCmsServiceProvider::class,
        ];
    }

    protected function getEnvironmentSetUp($app)
    {
        $app['config']->set('database.default', 'testing');
        $app['config']->set('database.connections.testing', [
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
        ]);

        $app['config']->set('flux-cms.locales', [
            'de' => 'Deutsch',
            'en' => 'English',
        ]);
    }
}
