<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

use Tests\Feature\ContentElementsTestTrait;
use Tests\Feature\TagExcludeTestTrait;
use Tests\Feature\ContentElementsSearchTestTrait;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

use App\Models\StaffProfileList;
use App\Models\Tag;
use App\Models\ContentElement;
use App\Models\Page;

class StaffProfileListTest extends TestCase
{
    use ContentElementsTestTrait;
    use WithFaker;
    use TagExcludeTestTrait;
    use ContentElementsSearchTestTrait;

    protected function getClassname()
    {
        return 'staff-profile-list';
    }

    public function test_a_staff_profile_list_can_be_created()
    {
        $tag1 = Tag::factory()->create();
        $tag2 = Tag::factory()->create();

        $page = Page::factory()->create();

        $staff_profile_list_input = StaffProfileList::factory()->raw();

        $input = [
            'pivot' => $this->getContentableArray($page),
            'type' => Str::kebab(class_basename(StaffProfileList::class)),
            'content' => array_merge($staff_profile_list_input, [
                'tags' => [
                    [ 'id' => $tag1->id, 'pivot' => ['exclude' => false ]],
                    [ 'id' => $tag2->id, 'pivot' => ['exclude' => true ]],
                ]
            ]),
        ];

        $this->signInAdmin();
        $this->enableEditing();

        $this->json('POST', route('content-elements.store'), $input)
             ->assertSuccessful()
             ->assertJsonFragment([
                 'success' => 'Staff Profile List Saved',
             ]);

        $content_element = ContentElement::all()->last();
        $this->assertInstanceOf(ContentElement::class, $content_element);

        $staff_profile_list = $content_element->content;

        $this->assertInstanceOf(StaffProfileList::class, $staff_profile_list);

        $this->assertNotNull($staff_profile_list->header);
        $this->assertNotNull($staff_profile_list->body);
        $this->assertNotNull($staff_profile_list->layout);
        $this->assertNotNull($staff_profile_list->title);

        $this->assertEquals(Arr::get($input, 'content.header'), $staff_profile_list->header);
        $this->assertEquals(Arr::get($input, 'content.body'), $staff_profile_list->body);
        $this->assertEquals(Arr::get($input, 'content.layout'), $staff_profile_list->layout);
        $this->assertEquals(Arr::get($input, 'content.title'), $staff_profile_list->title);

        $this->assertEquals($tag1->id, $staff_profile_list->tags->first()->id);
        $this->assertNotNull($staff_profile_list->tags->first()->pivot);
        $this->assertEquals(0, $staff_profile_list->tags->first()->pivot->exclude);

        $this->assertEquals($tag2->id, $staff_profile_list->tags->last()->id);
        $this->assertNotNull($staff_profile_list->tags->last()->pivot);
        $this->assertEquals(1, $staff_profile_list->tags->last()->pivot->exclude);
    }

    public function test_a_staff_profile_list_can_be_updated()
    {
        $tag1 = Tag::factory()->create();
        $tag2 = Tag::factory()->create();

        $page = Page::factory()->create();
        $content_element = $this->createContentElement(StaffProfileList::factory(), $page);
        $staff_profile_list = $content_element->content;
        $staff_profile_list->addTag($tag2);

        $old_header = $staff_profile_list->header;
        $old_body = $staff_profile_list->body;
        $old_layout = $staff_profile_list->layout;
        $old_title = $staff_profile_list->title;

        $input = $content_element->toArray();
        $input['content'] = array_merge($staff_profile_list->toArray(), StaffProfileList::factory()->raw());
        $input['pivot'] = $this->getContentableArray($page);

        $input['content']['tags'] = [
            [ 'id' => $tag1->id, 'pivot' => ['exclude' => false ]],
            [ 'id' => $tag2->id, 'pivot' => ['exclude' => true ]],
        ];

        $this->signInAdmin();
        $this->enableEditing();

        $this->json('POST', route('content-elements.update', ['id' => $content_element->id]), $input)
             ->assertSuccessful()
             ->assertJsonFragment([
                 'success' => 'Staff Profile List Saved',
             ]);

        $staff_profile_list->refresh();

        $this->assertEquals($content_element->id, ContentElement::all()->last()->id);
        $this->assertEquals($staff_profile_list->id, StaffProfileList::all()->last()->id);

        $this->assertNotEquals($old_header, $staff_profile_list->header);
        $this->assertNotEquals($old_body, $staff_profile_list->body);
        $this->assertNotEquals($old_layout, $staff_profile_list->layout);
        $this->assertNotEquals($old_title, $staff_profile_list->title);
        $this->assertEquals(Arr::get($input, 'content.header'), $staff_profile_list->header);
        $this->assertEquals(Arr::get($input, 'content.body'), $staff_profile_list->body);
        $this->assertEquals(Arr::get($input, 'content.layout'), $staff_profile_list->layout);
        $this->assertEquals(Arr::get($input, 'content.title'), $staff_profile_list->title);

        $this->assertEquals($tag1->id, $staff_profile_list->tags->first()->id);
        $this->assertNotNull($staff_profile_list->tags->first()->pivot);
        $this->assertEquals(0, $staff_profile_list->tags->first()->pivot->exclude);

        $this->assertEquals($tag2->id, $staff_profile_list->tags->last()->id);
        $this->assertNotNull($staff_profile_list->tags->last()->pivot);
        $this->assertEquals(1, $staff_profile_list->tags->last()->pivot->exclude);
    }
}
