<?php declare(strict_types=1);

namespace App\Tests\Controller;

use App\Entity\FoodOrder;
use App\Entity\FoodVendor;
use App\Entity\MenuItem;
use App\Entity\OrderItem;
use App\Repository\MenuItemRepository;
use App\Tests\DbWebTest;
use Override;

use function sprintf;

final class OrderItemControllerTest extends DbWebTest
{
    public FoodVendor $vendor;
    public FoodOrder $order;
    public Menuitem $menuItem;
    public MenuItemRepository $menuItemRepository;
    private string $path = '/order/item/';

    #[Override]
    public function setUp(): void
    {
        parent::setUp();
        $this->vendor = new FoodVendor;
        $this->vendor->setName('Food Vendor');

        $this->manager->persist($this->vendor);
        $this->order = new FoodOrder;
        $this->order->setFoodVendor($this->vendor);

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

        $this->menuItem = new MenuItem;
        $this->menuItem->setName('Testing');
        $this->menuItem->setFoodVendor($this->vendor);

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

        $this->menuItemRepository = static::getContainer()->get(MenuItemRepository::class);
    }

    public function testNew(): void
    {
        $this->client->request(
            'GET',
            sprintf('%snew/%s', $this->path, $this->order->getId())
        );

        self::assertResponseStatusCodeSame(200);

        $this->client->submitForm('Save', [
            'order_item[name]' => 'Testing',
            'order_item[extras]' => 'Testing',
        ]);

        self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId()));

        self::assertSame(1, $this->repository->count([]));
        self::assertSame(1, $this->menuItemRepository->count([]));
    }

    public function testNewCreateMenuItem(): void
    {
        $this->client->request(
            'GET',
            sprintf('%snew/%s', $this->path, $this->order->getId())
        );

        self::assertResponseStatusCodeSame(200);

        $this->client->submitForm('Save', [
            'order_item[name]' => 'Testing-1',
            'order_item[extras]' => 'Testing-1',
        ]);

        self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId()));

        self::assertSame(1, $this->repository->count([]));
        self::assertSame(2, $this->menuItemRepository->count([]));
    }

    public function testRemove(): void
    {
        $fixture = new OrderItem;
        $fixture->setName('Testing');
        $fixture->setExtras('Value');
        $fixture->setMenuItem($this->menuItem);

        $fixture->setFoodOrder($this->order);

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

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

        self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId()));
        self::assertSame(0, $this->repository->count([]));
    }

    public function testCopy(): void
    {
        $orderItem = new OrderItem;
        $orderItem->setName('My Title');
        $orderItem->setExtras('My Title');
        $orderItem->setFoodOrder($this->order);
        $orderItem->setMenuItem($this->menuItem);

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

        $this->client->request('GET', sprintf('%s%s/copy', $this->path, $orderItem->getId()));
        self::assertResponseRedirects(sprintf('/food/order/%s', $this->order->getId()));

        $result = $this->repository->findBy([
            'foodOrder' => $this->order->getId(),
        ]);
        $this->assertCount(2, $result);
        foreach ($result as $item) {
            $this->assertSame($orderItem->getName(), $item->getName());
            $this->assertSame($orderItem->getExtras(), $item->getExtras());
        }

    }

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