<?php

namespace Tests\Browser;

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

use Tests\Browser\Pages\Login;
use Tests\Browser\Components\Feedback;
use Tests\Browser\Components\Autocomplete;

use App\Models\Photo;
use App\Models\PhotoBlock;
use App\Models\Page;
use App\Models\Tag;
use App\Models\FileUpload;
use App\Models\ContentElement;
use App\Models\User;

class PhotoTagsTest extends DuskTestCase
{
    public function test_a_photo_can_be_tagged()
    {
        $this->browse(function (Browser $browser) {
            $tag = Tag::factory()->create();
            $tag2 = Tag::factory()->create();

            $content_element = $this->createContentElement(PhotoBlock::factory()->has(Photo::factory()->for(FileUpload::factory()->jpg(), 'fileUpload'), 'photos'));
            $photo_block = $content_element->content;
            $photo = $photo_block->photos()->first();
            $page = $content_element->pages->first();

            $content_element2 = $this->createContentElement(PhotoBlock::factory()->has(Photo::factory()->for(FileUpload::factory()->jpg(), 'fileUpload'), 'photos'), $page);
            $photo_block2 = $content_element2->content;
            $photo2 = $photo_block2->photos()->first();

            $this->assertNotNull($page);
            $this->assertInstanceOf(Page::class, $page);

            $user = User::factory()->create()
                                   ->addRole('pages-editor')
                                   ->createPermission('update', $page);

            $browser->visit(new Login())
                ->loginAndEditPage($page)
                ->waitFor('@toggle-selected-photo-'.$photo->id)
                ->click('@toggle-selected-photo-'.$photo->id)
                ->whenAvailable('@photo-tags-form', function ($browser) use ($tag) {
                    $browser->within(new Autocomplete('photo-tags'), function ($browser) use ($tag) {
                        $browser->searchAndSelectSingle($tag);
                    });
                })
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Photo Saved');
                });

            $photo->refresh();
            $this->assertTrue($photo->tags->contains('id', $tag->id));

            $browser->click('@close-photo-tags-form')
                ->refresh()
                ->waitFor('@toggle-selected-photo-'.$photo->id)
                ->click('@toggle-selected-photo-'.$photo->id)
                ->waitFor('@toggle-selected-photo-'.$photo2->id)
                ->click('@toggle-selected-photo-'.$photo2->id)
                ->whenAvailable('@photo-tags-form', function ($browser) use ($tag, $tag2, $photo) {
                    $browser->waitFor('@selected-photo-'.$photo->id)
                        ->with('@selected-photo-'.$photo->id, function ($browser) use ($tag) {
                            $browser->assertSee($tag->search_label);
                        })
                        ->within(new Autocomplete('photo-tags'), function ($browser) use ($tag2) {
                            $browser->searchAndSelectSingle($tag2);
                        });
                })
                ->pause(1500)
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Photo Saved');
                });

            $photo2->refresh();
            $this->assertTrue($photo2->tags->contains('id', $tag2->id));
            $photo->refresh();
            $this->assertTrue($photo->tags->contains('id', $tag2->id));

            $browser->with('@photo-tags-form', function ($browser) use ($tag, $tag2, $photo) {
                $browser->with('@selected-photo-'.$photo->id, function ($browser) use ($tag, $tag2) {
                    $browser->click('@remove-tag-'.$tag->id);
                });
            })
                ->pause(1500)
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Photo Saved');
                });

            $photo->refresh();
            $this->assertFalse($photo->tags->contains('id', $tag->id));
            $this->assertTrue($photo->tags->contains('id', $tag2->id));
        });
    }
}
