<?php

namespace Ignite\Core\Tests\Unit\Models\Menu;

use Ignite\Core\Models\Menu\PageItem;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Event;
use Ignite\Core\Entities\Page;
use Ignite\Core\Events\Menus\NavigationMenuPreCompile;
use Ignite\Core\Models\Menu\Item;
use Ignite\Core\Models\Menu\Manager;
use Ignite\Core\Tests\TestCase;
use stdClass;
use TypeError;

class ManagerTest extends TestCase
{
    /**
     * @test
     * @group Cms
     */
    public function it_will_only_accept_items_that_implement_the_correct_interface()
    {
        $this->expectException(TypeError::class);
        $this->withoutEvents();

        $manager = new Manager();
        $manager->add(new stdClass());
    }

    /**
     * @test
     * @group Cms
     */
    public function it_will_accept_a_page_item()
    {
        $this->withoutEvents();

        $manager = new Manager();
        $manager->add(new PageItem(new Page()));

        $this->assertInstanceOf(PageItem::class, $manager->getItems()->first());
    }

    /**
     * @test
     * @group Cms
     */
    public function it_will_accept_a_menu_item_model()
    {
        $this->withoutEvents();

        $manager = new Manager();
        $manager->add(new Item('test', 'Test', 1));

        $this->assertInstanceOf(Item::class, $manager->getItems()->first());
    }

    /**
     * @test
     * @group Cms
     */
    public function it_can_merge_a_collection_of_items_with_itself()
    {
        $this->withoutEvents();

        $manager = new Manager();

        $page = new PageItem(new Page(['url' => '/test', 'position' => 1]));

        $manager->merge(new Collection([$page]));

        $this->assertEquals($page, $manager->getItems()->first());
    }

    /**
     * @test
     * @group Cms
     */
    public function it_can_sort_any_type_of_menu_item()
    {
        $this->withoutEvents();

        $page1 = new PageItem((new Page())->forceFill(['id' => 2, 'title' => "Home", 'position' => 1]));
        $page2 = new Item('test', 'Test', 2, true);

        $manager = new Manager();
        $manager->add($page2);
        $manager->merge(new Collection([$page1]));

        $this->assertEquals(1, $manager->getItems()->first()->getPosition());
    }

    /**
     * @ test
     * @group Cms
     */
    public function it_dispatches_an_event_when_you_call_get_items()
    {
        $manager = new Manager();
        $manager->add(
            (new Page())->forceFill(['id' => 2, 'position' => 1])
        );

        Event::fake();
        $manager->getItems();
        Event::assertDispatched(NavigationMenuPreCompile::class, function ($event) {
            return $event->getManager() instanceof Manager;
        });
    }
}
