<?php

namespace Tests\Browser;

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

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;
use Tests\Browser\Components\ContentElements;

use App\Models\Page;
use App\Models\User;
use App\Models\ContentElement;
use App\Models\ContentFilter;
use App\Models\Tag;

class ContentFilterTest extends DuskTestCase
{
    use WithFaker;

    public function test_a_content_filter_can_be_created_and_updated()
    {
        $this->browse(function ($browser) {
            $page = Page::factory()->create();
            $user = User::factory()->create();
            $user->addRole('admin');

            $tag1 = Tag::factory()->create();
            $tag2 = Tag::factory()->create();

            $browser->visit(new Login())
                    ->loginAndEditPage($page, $user)
                    ->pause(500)
                    ->with(new AddContentElement(), function ($browser) {
                        $browser->create('content-filter');
                    })
                    ->pause(1500)
                    ->within(new Feedback(), function ($browser) {
                        $browser->assertFeedbackContains('Content Filter Saved');
                    });

            $content_element = ContentElement::all()->last();
            $header = $this->faker->words(3, true);
            $body = $this->faker->paragraph();
            $subtitle = $this->faker->words(2, true);
            $title = $this->faker->numberBetween(1, 99);
            $this->assertInstanceOf(ContentFilter::class, $content_element->content);

            $browser->with('@content-element-'.$content_element->id, function ($browser) use ($header, $body, $subtitle, $title, $content_element) {
                $browser->waitFor('@header')
                    ->type('@header', $header)
                    ->within(new Editor('body', $content_element->id), function ($browser) use ($body) {
                        $browser->typeInEditor($body);
                    })
                    ->click('@show-titles')
                    ->pause(250)
                    ->type('@subtitle', $subtitle)
                    ->type('@title', $title);
            })
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Content Filter Saved');
            });

            // create the content filters
            $browser->within(new ContentElements(), function ($browser) {
                $browser->createPhotoBlock();
            });

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

            $browser->with('@content-element-'.$content_element1->id, function ($browser) use ($tag1) {
                $browser->with(new Autocomplete('tags'), function ($browser) use ($tag1) {
                    $browser->searchAndSelectMultiple($tag1);
                })
                ->click('@toggle-filter');
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Photo Block Saved');
            });

            $browser->within(new ContentElements(), function ($browser) {
                $browser->createPhotoBlock();
            });

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

            $browser->with('@content-element-'.$content_element2->id, function ($browser) use ($tag2) {
                $browser->with(new Autocomplete('tags'), function ($browser) use ($tag2) {
                    $browser->searchAndSelectMultiple($tag2);
                })
                ->click('@toggle-filter');
            })
            ->pause(1500) // so that the debounce triggers
            ->within(new Feedback(), function ($browser) {
                $browser->assertFeedbackContains('Photo Block Saved');
            });

            $browser->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 ($tag1, $tag2, $header, $body, $subtitle, $title) {
                    $browser->assertSee($header)
                            ->assertSee($body)
                            ->assertSee($subtitle)
                            ->assertSee($title)
                            ->assertSee($tag1->name)
                            ->assertSee($tag2->name)
                            ->assertVisible('@tag-filter-'.$tag1->id)
                            ->assertVisible('@tag-filter-'.$tag2->id)
                            ->click('@tag-filter-'.$tag1->id);
                })
                ->pause(1000)
                ->waitFor('@content-element-'.$content_element1->id)
                //->assertMissing('@content-element-'.$content_element2->id)
                ->assertDontSeeIn('@content-element-'.$content_element2->id, $content_element1->content->header)
                ->assertSeeIn('@content-element-'.$content_element1->id, $content_element1->content->header)
                ->assertSeeIn('@content-element-'.$content_element1->id, strip_tags($content_element1->content->body))
                ->with('@content-element-'.$content_element->id, function ($browser) use ($tag1, $tag2) {
                    $browser->click('@tag-filter-'.$tag2->id);
                })
                ->pause(1000)
                ->waitFor('@content-element-'.$content_element2->id)
                //->assertMissing('@content-element-'.$content_element1->id)
                ->assertDontSeeIn('@content-element-'.$content_element1->id, $content_element1->content->header)
                ->assertSeeIn('@content-element-'.$content_element2->id, $content_element2->content->header)
                ->assertSeeIn('@content-element-'.$content_element2->id, strip_tags($content_element2->content->body))

                ->with('@content-element-'.$content_element->id, function ($browser) use ($tag1, $tag2) {
                    $browser->click('@tag-filter-'.$tag2->id);
                })
                ->pause(1000)
                //->assertMissing('@content-element-'.$content_element1->id)
                //->assertMissing('@content-element-'.$content_element2->id)
                ->assertDontSeeIn('@content-element-'.$content_element1->id, $content_element1->content->header)
                ->assertDontSeeIn('@content-element-'.$content_element2->id, $content_element1->content->header)

                ->clickAndWaitForReload('@editing-button')
                ->waitFor('@content-elements-editor')
                ->whenAvailable('@content-element-'.$content_element->id, function ($browser) {
                    $browser->click('@checkbox-toggle-select-multiple');
                })
                ->pause(1500)
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Content Filter Saved');
                })
                ->refresh()
                ->waitFor('@publish-page')
                ->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->pause(1000);

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

            $browser->clickAndWaitForReload('@editing-button')
                ->waitFor('@content-element-'.$content_element->id)
                ->with('@content-element-'.$content_element->id, function ($browser) use ($tag1, $tag2) {
                    $browser->click('@tag-filter-'.$tag1->id)
                        ->click('@tag-filter-'.$tag2->id);
                })
                ->pause(1000)
                ->waitFor('@content-element-'.$content_element1->id)
                ->waitFor('@content-element-'.$content_element2->id)
                ->assertSeeIn('@content-element-'.$content_element1->id, $content_element1->content->header)
                ->assertSeeIn('@content-element-'.$content_element1->id, strip_tags($content_element1->content->body))
                ->assertSeeIn('@content-element-'.$content_element2->id, $content_element2->content->header)
                ->assertSeeIn('@content-element-'.$content_element2->id, strip_tags($content_element2->content->body));
        });
    }
}
