<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Illuminate\Support\Arr;

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

use Tests\Browser\Pages\Login;

use Tests\Browser\Components\Feedback;
use Tests\Browser\Components\Editor;
use Tests\Browser\Components\AddContentElement;
use Tests\Browser\Components\Autocomplete;

class StaffProfileListTest extends DuskTestCase
{
    public function test_a_staff_profile_list_can_be_created_and_viewed()
    {
        $this->browse(function ($browser) {
            $page = Page::factory()->create();
            $staff_profile = StaffProfile::factory()->create([
                'published_at' => null,
            ]);
            $tag = Tag::factory()->create();
            $staff_profile->addTag($tag);
            $user = User::factory()->create();
            $user->createPermission('publish', $page);

            $browser->visit(new Login())
                    ->loginAndEditPage($page, $user)
                    ->with(new AddContentElement(), function ($browser) {
                        $browser->create('staff-profile-list');
                    })
                    ->pause(1500)
                    ->within(new Feedback(), function ($browser) {
                        $browser->assertFeedbackContains('Staff Profile List Saved');
                    });

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

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

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($input, $content_element, $tag) {
                $browser->waitFor('@header')
                    ->pause(1000)
                    ->type('@header', Arr::get($input, 'header'))
                    ->within(new Editor('body', $content_element->id), function ($browser) use ($input) {
                        $browser->typeInEditor(Arr::get($input, 'body'));
                    })
                    ->type('@title', Arr::get($input, 'title'))
                    ->with(new Autocomplete('tags'), function ($browser) use ($tag) {
                        $browser->searchAndSelectMultiple($tag);
                    })
                    ->click('@select-grid')
                    ->click('@select-inline')
                    ->click('@select-thumbnails')
                    ->click('@select-list');
            })
                ->pause(1500)
                ->click('@debug')
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Staff Profile List Saved');
                });

            $content_element->refresh();
            $staff_profile_list = $content_element->content;

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

            $browser->waitFor('@publish-page')
                ->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->pause(1000)
                ->clickAndWaitForReload('@editing-button')
                ->waitFor('@content-element-'.$content_element->id)
                ->pause(500)
                ->with('@content-element-'.$content_element->id, function ($browser) use ($tag, $staff_profile_list, $staff_profile) {
                    $browser->assertSee($staff_profile_list->header)
                            ->assertSee(strip_tags($staff_profile_list->body))
                            ->assertMissing('@staff-profile-'.$staff_profile->id);
                })
                ->pause(1000);

            $staff_profile->publish();

            $browser->refresh()
                ->pause(1000)
                ->assertMissing('@page-editor')
                ->click('@debug');

            $this->viewStaffProfile($browser, $staff_profile, $content_element, 'list');

            $content_element = ContentElement::all()->last();

            $browser->clickAndWaitForReload('@editing-button')
                ->whenAvailable('@content-element-'.$content_element->id, function ($browser) {
                    $browser->pause(500)
                        ->click('@select-grid');
                })
                ->pause(3000)
                ->waitFor('@publish-page', 10)
                ->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->clickAndWaitForReload('@editing-button');

            $this->viewStaffProfile($browser, $staff_profile, $content_element, 'grid');
            $content_element = ContentElement::all()->last();

            $browser->clickAndWaitForReload('@editing-button')
                ->whenAvailable('@content-element-'.$content_element->id, function ($browser) {
                    $browser->pause(1000)
                        ->waitFor('@select-thumbnails')
                        ->click('@select-thumbnails');
                })
                ->pause(3000)
                ->waitFor('@publish-page', 10)
                ->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->clickAndWaitForReload('@editing-button');

            $content_element = ContentElement::all()->last();
            $this->viewStaffProfile($browser, $staff_profile, $content_element, 'thumbnails');
        });
    }

    public function viewStaffProfile($browser, $staff_profile, $content_element, $layout)
    {
        $browser->waitFor('@content-element-'.$content_element->id)
            ->with('@content-element-'.$content_element->id, function ($browser) use ($staff_profile, $layout) {
                $browser->assertVisible('@staff-profile-layout-'.$layout)
                        ->assertVisible('@staff-profile-link-'.$staff_profile->id)
                        ->click('@staff-profile-link-'.$staff_profile->id);
            })
            ->waitFor('@modal')
            ->assertFragmentIs($staff_profile->anchor)
            ->with('@modal', function ($browser) use ($staff_profile) {
                $browser->assertVisible('@staff-profile-'.$staff_profile->id)
                        ->assertSee($staff_profile->full_name)
                    ->click('@close-modal');
            })
            ->pause(500)
            ->assertFragmentIsNot($staff_profile->anchor);
    }
}
