<?php declare(strict_types=1);

namespace App\Tests\Controller;

use App\Entity\FoodVendor;
use App\Entity\MenuItem;
use App\Tests\DbWebTest;
use Override;

use function sprintf;

final class FoodVendorControllerTest extends DbWebTest
{
    private string $path = '/food/vendor/';

    public function testIndex(): void
    {
        $this->client->request('GET', $this->path);

        self::assertResponseStatusCodeSame(200);
        self::assertPageTitleContains('FoodVendor index');
    }

    public function testNew(): void
    {
        self::assertSame(0, $this->repository->count([]));
        $this->client->request('GET', sprintf('%snew', $this->path));

        self::assertResponseStatusCodeSame(200);

        $this->client->submitForm('Save', [
            'food_vendor[name]' => 'TestingNew',
        ]);

        $newVendor = $this->repository->findOneBy([
            'name' => 'TestingNew',
        ]);
        $this->assertInstanceof(FoodVendor::class, $newVendor);
        self::assertSame(1, $this->repository->count([]));

    }

    public function testShow(): void
    {
        $fixture = new FoodVendor;
        $fixture->setName('My Title');
        $fixture->setMenuLink('https://example.com/');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $crawler = $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));

        $this->assertResponseIsSuccessful();

        $nameNode = $crawler->filter('td')
            ->last();
        $nameNode = $crawler->filter(
            '.table > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2)'
        )->text();
        $menuLinkNode = $crawler->filter(
            '.table > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > a:nth-child(1)'
        )->text();
        $this->assertSame('My Title', $nameNode);
        $this->assertSame('https://example.com/', $menuLinkNode);
    }

    public function testShowMenuItems(): void
    {
        $fixture = new FoodVendor;
        $fixture->setName('My Title');

        $this->manager->persist($fixture);

        $this->manager->flush();

        $itemOne = new MenuItem;
        $itemOne->setName('Item One');

        $fixture->addMenuItem($itemOne);
        $this->manager->persist($itemOne);

        $itemTwo = new MenuItem;
        $itemTwo->setName('Item Two');
        $itemTwo->setFoodVendor($fixture);

        $fixture->addMenuItem($itemTwo);
        $this->manager->persist($itemTwo);

        $itemThree = new MenuItem;
        $itemThree->setName('Item Three');
        $itemThree->setFoodVendor($fixture);

        $fixture->addMenuItem($itemThree);
        $this->manager->persist($itemThree);

        $itemFour = new MenuItem;
        $itemFour->setName('Item Four');
        $itemFour->setFoodVendor($fixture);

        $fixture->addMenuItem($itemFour);
        $this->manager->persist($itemFour);

        $this->manager->flush();

        $crawler = $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));

        $this->assertResponseIsSuccessful();
        $nameNode = $crawler->filter(
            '.table > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2)'
        )->text();
        $this->assertSame('My Title', $nameNode);

        $itemNodes = $crawler->filter('li');

        $this->assertCount(4, $itemNodes);
    }

    public function testEdit(): void
    {
        $fixture = new FoodVendor;
        $fixture->setName('Value');
        $fixture->setMenuLink('Value');
        $fixture->setPhone('Value');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $crawler = $this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId()));
        $this->assertSame(
            $crawler->filter('#food_vendor_name')
                ->last()
                ->attr('value', ''),
            'Value'
        );
        $this->assertSame(
            $crawler->filter('#food_vendor_menuLink')
                ->last()
                ->attr('value', ''),
            'Value'
        );
        $this->assertSame(
            $crawler->filter('#food_vendor_phone')
                ->last()
                ->attr('value', ''),
            'Value'
        );

        $this->client->submitForm('Update', [
            'food_vendor[name]' => 'Something New',
            'food_vendor[menuLink]' => 'https://example.com/',
            'food_vendor[phone]' => '1234567890',
        ]);

        self::assertResponseRedirects('/food/vendor/');

        $fixture = $this->repository->findAll();

        self::assertSame('Something New', $fixture[0]->getName());
        self::assertSame('https://example.com/', $fixture[0]->getMenuLink());
        self::assertSame('1234567890', $fixture[0]->getPhone());
    }

    #[Override]
    public function getEntityClass(): string
    {
        return FoodVendor::class;
    }
}