<?php

namespace Tests\Browser;

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

use Tests\Browser\Components\PhotoUpload;
use Tests\Browser\Components\Feedback;
use Tests\Browser\Components\Editor;
use Tests\Browser\Components\AddContentElement;
use Tests\Browser\Pages\Login;

use App\Models\Page;
use App\Models\ContentElement;
use App\Models\Photo;
use App\Models\Slideshow;
use App\Models\User;

class SlideshowTest extends DuskTestCase
{
    use WithFaker;

    public function test_a_slideshow_can_be_created_and_viewed()
    {
        $this->browse(function ($browser) {
            $page = Page::factory()->create();
            $user = User::factory()->create();
            $user->createPermission('publish', $page);

            $browser->visit(new Login())
                ->loginAndEditPage($page, $user)
                ->waitFor('@content-elements-editor')
                ->with(new AddContentElement(), function ($browser) {
                    $browser->create('slideshow');
                });

            $content_element = ContentElement::all()->last();
            $input = Slideshow::factory()->raw();

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($input, $content_element) {
                $browser->click('@toggle-text')
                        ->waitFor('@header')
                        ->type('@header', Arr::get($input, 'header'))
                        ->within(new Editor('body', $content_element->id), function ($browser) use ($input) {
                            $browser->typeInEditor(Arr::get($input, 'body'));
                        })
                        ->type('@delay', Arr::get($input, 'delay'));
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Slideshow Saved');
            });

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

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

            $browser->with(new PhotoUpload($content_element), function ($browser) {
                $browser->addPhoto();
            });

            $photo = Photo::all()->last();
            $caption = $this->faker->sentence();
            $alt = $this->faker->sentence();
            $span = $photo->span;
            $title = $this->faker->words(2, true);
            $subtitle = $this->faker->words(2, true);

            $browser->whenAvailable('@form-photo-'.$photo->id, function ($browser) use ($photo, $alt, $caption, $title, $subtitle) {
                $browser->assertSourceHas($photo->large)
                    ->type('@caption', $caption)
                    ->type('@alt', $alt)
                    ->click('@show-titles')
                    ->waitFor('@title')
                    ->type('@title', $title)
                    ->type('@subtitle', $subtitle);
            })
                ->pause(1500)
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Slideshow Saved');
                });

            $browser->with(new PhotoUpload($content_element), function ($browser) {
                $browser->addPhoto();
            });

            $photo2 = Photo::all()->last();

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($content_element, $photo, $photo2) {
                $browser->assertVisible('@thumbnails')
                        ->waitFor('@photo-preview-'.$photo->id)
                        ->waitFor('@photo-preview-'.$photo2->id)
                        ->click('@photo-preview-'.$photo->id);
            });

            $browser->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->clickAndWaitForReload('@editing-button')
                ->assertNotPresent('@page-editor')
                ->click('@debug')
                ->with('@content-element-'.$content_element->id, function ($browser) use ($photo, $photo2, $title, $subtitle) {
                    $browser->waitFor('@photo-'.$photo->id)
                        ->pause(500)
                        ->assertSee($title)
                        ->assertSee($subtitle)
                        ->waitFor('@photo-'.$photo2->id);
                });
        });
    }
}
