<?php

namespace Tests\Browser;

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

use Illuminate\Support\Arr;

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

use App\Models\User;
use App\Models\Page;
use App\Models\ContentElement;
use App\Models\Calendar;
use App\Models\GoogleCalendar;

class CalendarTest extends DuskTestCase
{
    public function test_a_calendar_can_be_created_and_navigated()
    {
        $this->browse(function ($browser) {
            $page = Page::factory()->create();

            $input = Calendar::factory()->raw();
            $google_input = GoogleCalendar::factory()->raw();

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

            $browser->visit(new Login())
                ->loginAndEditPage($page, $user)
                ->waitFor('@content-elements-editor')
                ->pause(300) // wait for transitions
                ->with('@add-content-element-last', function ($browser) {
                    $browser->waitFor('@add-calendar')
                        ->click('@add-calendar');
                })
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Calendar Saved');
                });

            $content_element = ContentElement::all()->last();
            $calendar = $content_element->content;
            $google_calendar = GoogleCalendar::all()->last();

            $this->assertInstanceOf(Calendar::class, $content_element->content);

            $browser->waitFor('@content-element-'.$content_element->id)
                ->with('@content-element-'.$content_element->id, function ($browser) use ($input, $google_input, $content_element, $google_calendar) {
                    $browser->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('@google-calendar-'.$google_calendar->id.'-name', Arr::get($google_input, 'name'))
                        ->type('@google-calendar-'.$google_calendar->id.'-google-id', Arr::get($google_input, 'google_id'))
                        ->pause(2000)
                        ->waitFor('@pagination-count', 30)
                        ->type('@pagination-count', 2)
                        ->pause(1000);
                })
                ->pause(2500) // so that the debounce triggers
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Calendar Saved');
                });

            $calendar->refresh();
            $google_calendar->refresh();

            $this->assertEquals(Arr::get($input, 'header'), $calendar->header);
            $this->assertEquals(Arr::get($input, 'body'), strip_tags($calendar->body));

            $this->assertEquals(Arr::get($google_input, 'name'), $google_calendar->name);
            $this->assertEquals(Arr::get($google_input, 'google_id'), $google_calendar->google_id);

            $events = $calendar->getCalendarEvents();

            $browser->click('@publish-page')
                ->acceptDialog()
                ->within(new Feedback(), function ($browser) {
                    $browser->assertFeedbackContains('Page Published');
                })
                ->clickAndWaitForReload('@editing-button')
                ->waitFor('@content-element-'.$content_element->id)
                ->pause(2000)
                ->with('@content-element-'.$content_element->id, function ($browser) use ($calendar, $google_calendar, $events) {
                    $browser->assertSee($calendar->header)
                        ->assertSee(strip_tags($calendar->body))
                        ->waitFor('@google-calendar-'.$events->first()->id)
                        ->waitFor('@page-2')
                        ->click('@page-2')
                        ->waitFor('@google-calendar-'.$events[2]->id);
                });
        });
    }
}
