<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
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\EmbedVideo;
use App\Models\User;
use App\Models\VideoText;

class EmbedVideoTest extends DuskTestCase
{
    public function test_an_embed_video_can_be_created_and_viewed()
    {
        $this->browse(function ($browser) {
            $page = Page::factory()->create();
            $user = User::factory()->create();
            $user->createPermission('publish', $page);
            $user->addRole('web-committee');

            $link_page = Page::factory()->create();
            $link_page->publish();

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

            $content_element = ContentElement::all()->last();
            $input = EmbedVideo::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'));
                        });
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

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

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

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($input, $content_element) {
                $browser->assertVisible('@toggle-upload-form')
                    ->assertSourceHas('dusk="embed-video-'.$content_element->uuid)
                    ->attach('embed-video-'.$content_element->uuid, __DIR__.'/default.mp4');
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

            $embed_video->refresh();
            $url = $embed_video->url;
            $this->assertNotNull($url);

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($input, $content_element, $embed_video, $url) {
                $browser->waitFor('@video-player-'.$embed_video->id)
                    ->pause(500)
                    ->assertSourceHas($url)
                    ->assertSourceHas('dusk="embed-video-banner-'.$content_element->uuid)
                    ->attach('embed-video-banner-'.$content_element->uuid, __DIR__.'/default.png');
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

            $embed_video->refresh();
            $banner = $embed_video->banner;

            $this->assertNotNull($banner);

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($input, $content_element) {
                $browser->assertVisible('@add-video-text')
                    ->click('@add-video-text');
            })
            ->pause(2500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

            $video_text = VideoText::all()->last();
            $this->assertEquals($embed_video->id, $video_text->embedVideo->id);
            $video_text_input = VideoText::factory()->raw([
                'start_time' => 0,
                'length' => 2,
            ]);

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($video_text, $video_text_input, $content_element) {
                $browser->waitFor('@video-text-form-'.$video_text->id)
                    ->with('@video-text-form-'.$video_text->id, function ($browser) use ($video_text_input, $video_text) {
                        $browser->type('@header', Arr::get($video_text_input, 'header'))
                            ->within(new Editor('body', $video_text->id), function ($browser) use ($video_text_input) {
                                $browser->typeInEditor(Arr::get($video_text_input, 'body'));
                            })
                            ->click('@link')
                            ->pause(500);
                    });
            });

            $browser->with('@modal', function ($browser) use ($link_page) {
                $browser->with('@link-menu', function ($browser) use ($link_page) {
                    $browser->waitFor('@page-list-'.$link_page->id)
                            ->click('@page-list-'.$link_page->id);
                });
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($video_text, $video_text_input, $content_element, $link_page) {
                $browser->with('@video-text-form-'.$video_text->id, function ($browser) use ($video_text_input, $video_text, $link_page) {
                    $browser->waitFor('@link-url')
                        ->assertVisible('@link-url')
                        ->assertSeeIn('@link-url', $this->getEditingValue($link_page, 'full_slug'))
                        ->type('@link-text', Arr::get($video_text_input, 'link_text'))
                        ->assertVisible('@increase-header-size')
                        ->assertVisible('@decrease-header-size')
                        ->type('@start-time', Arr::get($video_text_input, 'start_time'))
                        ->assertInputValue('@length', 5) // should be 5 seconds of video
                        ->type('@length', Arr::get($video_text_input, 'length'))
                        ->type('@offsetX', Arr::get($video_text_input, 'offsetX'))
                        ->type('@offsetY', Arr::get($video_text_input, 'offsetY'));
                });
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Embed Video Saved');
            });

            $video_text->refresh();

            $this->assertEquals(Arr::get($video_text_input, 'header'), $video_text->header);
            $this->assertEquals('<p>'.Arr::get($video_text_input, 'body').'</p>', $video_text->body);
            $this->assertEquals(Arr::get($video_text_input, 'start_time'), $video_text->start_time);
            $this->assertEquals(Arr::get($video_text_input, 'length'), $video_text->length);
            $this->assertEquals(Arr::get($video_text_input, 'offsetX'), $video_text->offsetX);
            $this->assertEquals(Arr::get($video_text_input, 'offsetY'), $video_text->offsetY);

            $browser->pause(1500)
                ->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 ($video_text, $content_element, $link_page, $embed_video) {
                    $browser->assertSee($embed_video->header)
                        ->assertSee(strip_tags($embed_video->body))
                        ->waitFor('@video-player-'.$embed_video->id)
                        ->with('@video-player-'.$embed_video->id, function ($browser) use ($video_text) {
                            $browser->waitFor('@video-text-'.$video_text->id)
                                ->pause(750)
                                ->assertSee($video_text->header)
                                ->assertSee(strip_tags($video_text->body))
                                ->assertSee($video_text->link_text)
                                ->pause(500)
                                ->click('@video-text-link');
                        })
                        ->waitForLocation('/'.$link_page->full_slug);
                });
        });
    }
}
