<?php

declare(strict_types=1);

namespace KupShop\OrderingBundle\Tests\Order;

use KupShop\OrderingBundle\Util\Order\OrderItemEditTrait;
use Query\Operator;

class OrderItemReplaceTest extends \DatabaseTestCase
{
    private $editUtil;

    protected function setUp(): void
    {
        parent::setUp();

        $this->editUtil = new class {
            use OrderItemEditTrait;
            use \DatabaseCommunication;
        };
    }

    public function assertDatabaseRows(int $expected, array $conds, string $table = 'order_items'): void
    {
        $qb = sqlQueryBuilder()
               ->select('*')
               ->from($table);

        foreach ($conds as $v) {
            $qb->andWhere($v);
        }

        $this->assertEquals($expected, $qb->execute()->rowCount());
    }

    public function testReplaceProductVariant(): void
    {
        $this->assertDatabaseRows(1, [
            Operator::equals(['id' => 184271]),
            Operator::equals(['id_product' => 999]),
            Operator::equals(['id_variation' => 10000]),
        ]);

        $this->editUtil->editItem(68453, [
            'id_product_replace' => 999,
            'id_variation_replace' => 10001,
            'descr' => 'foo',
            'id_variation' => '1002',
            'pieces' => '2',
            'piece_price' => '48.7603',
            'piece_price_vat' => '59',
            'tax' => '21',
            'total_price' => '97.5206',
            'total_price_vat' => '118',
            'discount' => '0',
            'id_product' => '999',
            'id' => '184271',
        ]);

        $this->assertDatabaseRows(1, [Operator::equals(['id_product' => 999])]);
        $this->assertDatabaseRows(1, [
            Operator::equals(['id_product' => 999]),
            Operator::equals(['id_variation' => 10001]),
        ]);
    }

    public function testReplaceProduct(): void
    {
        $this->assertDatabaseRows(1, [
            Operator::equals(['id' => 184271]),
            Operator::equals(['id_product' => 999]),
        ]);

        $this->editUtil->editItem(68453, [
            'id_product_replace' => 1000,
            'id_variation_replace' => '',
            'descr' => 'foo',
            'id_variation' => '1002',
            'pieces' => '2',
            'piece_price' => '48.7603',
            'piece_price_vat' => '59',
            'tax' => '21',
            'total_price' => '97.5206',
            'total_price_vat' => '118',
            'discount' => '0',
            'id_product' => '999',
            'id' => '184271',
        ]);

        $this->assertDatabaseRows(0, [Operator::equals(['id_product' => 999])]);
        $this->assertDatabaseRows(1, [Operator::equals(['id_product' => 1000])]);
        $this->assertDatabaseRows(1, [Operator::equals(['quantity' => 454])], 'stores_items');
    }

    public function testNoReplacement(): void
    {
        $fetch = function () {
            return sqlQueryBuilder()
                ->select('*')
                ->from('order_items')
                ->andWhere(Operator::equals(['id_product' => 999]))
                ->execute()
                ->fetch();
        };

        $qb = $fetch();
        $this->assertDatabaseRows(1, [Operator::equals(['id_product' => 999])]);

        $this->editUtil->editItem(68453, [
            'id_product_replace' => '',
            'id_variation_replace' => '',
        ] + $qb);

        $this->assertDatabaseRows(1, [Operator::equals(['id_product' => 999])]);
        $this->assertSame($fetch(), $qb);
    }

    protected function getDataSet()
    {
        return $this->getJsonDataSetFromFile();
    }
}
