<?php

namespace KupShop\PohodaBundle\Tests\Orders\Import;

use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\PohodaBundle\Tests\TestUtilHelper;
use KupShop\PohodaBundle\Utils\PohodaConnector;
use KupShop\PohodaBundle\Utils\Tools\PohodaOrderImporter;
use KupShop\PohodaBundle\Utils\Tools\TransformHelper;
use Query\Operator;

class ImportOrderTest extends \DatabaseTestCase
{
    use TestUtilHelper;
    /** @var PohodaConnector */
    private $pohodaConnector;

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

    /**
     * @var TransformHelper
     */
    protected $transformHelper;

    /**
     * @var PohodaOrderImporter
     */
    protected $pohodaOrderImporter;

    protected function setEnvironment()
    {
        \Settings::getDefault()->saveValue('pohoda', []);

        $this->pohodaConnector = ServiceContainer::getService(PohodaConnector::class);
        $this->pohodaOrderImporter = $this->get(PohodaOrderImporter::class);
        $this->transformHelper = $this->get(TransformHelper::class);
        $this->prepareMServer();
    }

    public function testTransformOrdersIn()
    {
        $this->setEnvironment();
        $xmlResponse = file_get_contents(__DIR__.'/ordersInResponse.xml');
        $transformedXML = $this->transformHelper->baseTransform($xmlResponse, $this->transformHelper->loadXslt('ordersIn.xsl'));
        $this->assertXmlStringEqualsXmlFile(__DIR__.'/ordersInResult.xml', $transformedXML);
    }

    public function testImportInsertOrder()
    {
        $instance = $this->autowire(ImportOrderMock::class);
        $this->set(PohodaOrderImporter::class, $instance);

        $this->setEnvironment();
        $this->pohodaConnector->reloadConfig();
        $this->pohodaOrderImporter->resetResolveCounter();

        $xml = file_get_contents(__DIR__.'/ordersInResult.xml');
        $this->pohodaOrderImporter->importOrders($xml, true);

        // ORDER
        $qb = sqlQueryBuilder()
            ->select('invoice_email, pohoda_id, package_id')
            ->from('orders')
            ->andWhere(Operator::equals(['order_no' => 'WEB110011']))
            ->execute()
            ->fetch();

        $this->assertEquals('petr.k@hanibal.cz', $qb['invoice_email']);
        $this->assertEquals('0_284251', $qb['pohoda_id']);
        $this->assertEquals(null, $qb['package_id']);

        // ORDER_ITEM
        $qb_item = sqlQueryBuilder()
            ->select('tax, descr')
            ->from('order_items')
            ->andWhere('pohoda_id=698746')
            ->execute()
            ->fetch();
        $this->assertEquals(2, $this->pohodaOrderImporter->getResolveCounter());
        $this->assertEquals(15, $qb_item['tax']);
        $this->assertEquals('Chimpanzee tyčinka Energy ::citron::-', $qb_item['descr']);
    }

    public function testImportUpdateOrder()
    {
        $instance = $this->autowire(ImportOrderMock::class);
        $this->set(PohodaOrderImporter::class, $instance);

        $this->setEnvironment();
        $this->pohodaConnector->reloadConfig();

        $this->pohodaOrderImporter->resetResolveCounter();

        // BEFORE UPDATE ORDER
        $beforeOrder = sqlQueryBuilder()
            ->select('invoice_name, invoice_surname, pohoda_id, package_id')
            ->from('orders')
            ->andWhere(Operator::equals(['order_no' => 'WEB110010']))
            ->execute()
            ->fetch();
        $this->assertEquals('Petr', $beforeOrder['invoice_name']);
        $this->assertEquals('Kukač', $beforeOrder['invoice_surname']);
        $this->assertEquals('284250', $beforeOrder['pohoda_id']);
        $this->assertEquals(null, $beforeOrder['package_id']);

        // BEFORE UPDATE ITEM
        $beforeItem = sqlQueryBuilder()
            ->select('descr, pieces')
            ->from('order_items')
            ->andWhere(Operator::equals(['pohoda_id' => 698744]))
            ->execute()
            ->fetch();
        $this->assertEquals('Tilak vesta Tourmalet Lady ::ebony grey::M', $beforeItem['descr']);
        $this->assertEquals(1, $beforeItem['pieces']);

        // LOAD CHANGES AND UPDATE
        $xml = file_get_contents(__DIR__.'/ordersInResultChange.xml');
        $this->pohodaOrderImporter->importOrders($xml, true);

        // AFTER UPDATE ORDER
        $afterOrder = sqlQueryBuilder()
            ->select('invoice_name, invoice_surname, pohoda_id, package_id')
            ->from('orders')
            ->andWhere(Operator::equals(['order_no' => 'WEB110010']))
            ->execute()
            ->fetch();
        $this->assertEquals(2, $this->pohodaOrderImporter->getResolveCounter());
        $this->assertEquals('Petr TEST', $afterOrder['invoice_name']);
        $this->assertEquals('Kukač TEST', $afterOrder['invoice_surname']);
        $this->assertEquals('0_284250', $afterOrder['pohoda_id']);
        $this->assertEquals('B123456', $afterOrder['package_id']);

        // LOAD CHANGES AND UPDATE
        $xml = file_get_contents(__DIR__.'/ordersInResultChange2.xml');
        $this->pohodaOrderImporter->importOrders($xml, true);

        // AFTER UPDATE ORDER
        $afterOrder = sqlQueryBuilder()
            ->select('invoice_name, invoice_surname, pohoda_id, package_id')
            ->from('orders')
            ->andWhere(Operator::equals(['order_no' => 'WEB110010']))
            ->execute()
            ->fetch();
        // in ordersInResultChange2.xml is different package id - don't update it on order
        $this->assertEquals('B123456', $afterOrder['package_id']);
    }

    public function testDeleteOrderItem()
    {
        $this->setEnvironment();

        $before = sqlQueryBuilder()
            ->select('id_order')
            ->from('order_items')
            ->andWhere(Operator::equals(['pohoda_id' => 698745]))
            ->execute()
            ->fetchColumn();

        $this->assertEquals(97097, $before);

        $xml = file_get_contents(__DIR__.'/ordersInDeleteItem.xml');
        $this->pohodaOrderImporter->importOrders($xml, true);

        $after = sqlQueryBuilder()
            ->select('id')
            ->from('order_items')
            ->andWhere(Operator::equals(['pohoda_id' => 698745]))
            ->execute()
            ->fetchColumn();

        $this->assertEquals(null, $after);
    }
}

class ImportOrderMock extends PohodaOrderImporter
{
    /** @var int|null */
    private $resolveCounter;

    public function resetResolveCounter(int $resolveCounter = 0)
    {
        $this->resolveCounter = $resolveCounter;
    }

    public function getResolveCounter(): int
    {
        return $this->resolveCounter;
    }

    public function resolveOrder($orderElement, $qbOrder): int
    {
        return $this->resolveCounter++;
    }
}
