<?php

namespace KupShop\PohodaBundle\Tests\Users\Export;

use KupShop\DevelopmentBundle\Util\Tests\LoggerTestTrait;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\PohodaBundle\Tests\TestUtilHelper;
use KupShop\PohodaBundle\Utils\Exporters\UsersExporter;
use KupShop\PohodaBundle\Utils\PohodaConnector;
use KupShop\PohodaBundle\Utils\Tools\TransformHelper;
use KupShop\UserBundle\Event\UserRegisteredEvent;
use KupShop\UserBundle\Util\UserExporter;
use Query\Operator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Messenger\TraceableMessageBus;

class ExportUserTest extends \DatabaseTestCase
{
    use LoggerTestTrait;

    use TestUtilHelper;

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

    protected TransformHelper $transformHelper;

    protected UserExporter $userExporter;

    protected UsersExporter $usersExporter;

    private TraceableMessageBus $asyncBus;

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

        $this->asyncBus = $this->get('async_bus');
    }

    protected function setEnvironment()
    {
        $this->userExporter = $this->get(UserExporter::class);
        $this->transformHelper = $this->get(TransformHelper::class);
        $this->usersExporter = $this->get(UsersExporter::class);
        $this->getLogger();
        $this->prepareMServer();
    }

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

        // LOAD FILE
        $xmlResponse = file_get_contents(__DIR__.'/exportedUsersOut.xml');

        // TRANSFORM XML
        $resultXML = $this->transformHelper->baseTransform($xmlResponse, $this->transformHelper->loadXslt('usersOut.xsl'));

        // COMPARE TRANSFORMATION
        $this->assertXmlStringEqualsXmlFile(__DIR__.'/usersOutResult.xml', $resultXML);
    }

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

        // LOAD RESPONSE FILE
        $xmlResponse = file_get_contents(__DIR__.'/addressProcessResponse.xml');

        // SUSPICIOUS USERS
        $IDs = [18];

        // TEST BEFORE UPDATE
        $beforeAction = $this->getActualUsers($IDs);
        $this->assertEquals(null, $beforeAction['martin.strejcek@volny.cz']['pohoda_id']);

        // UPDATE USERS pohoda_id
        $this->usersExporter->processResponse($xmlResponse);

        // TEST AFTER UPDATE
        $afterAction = $this->getActualUsers($IDs);
        $this->assertEquals('8867', $afterAction['martin.strejcek@volny.cz']['pohoda_id']);

        $response = simplexml_load_string($xmlResponse);
        $logData = null;
        foreach ($response->xpath('rsp:responsePackItem') as $responsePackItem) {
            $logData = $responsePackItem->asXML();
        }
        $testHandler = $this->getTestHandler();
        $this->assertEquals(true, $testHandler->hasNoticeThatContains('POHODA RESPONSE: User Export'));
        foreach ($testHandler->getRecords() as $record) {
            if ($record['message'] == 'POHODA RESPONSE: User Export') {
                $this->assertEquals($logData, $record['context']['data']);
            }
        }
    }

    public function testAsyncExportUser()
    {
        $instance = $this->autowire(PohodaConnectorMock::class);
        $this->set(PohodaConnector::class, $instance);

        $this->prepareMServer();

        $eventDispatcher = ServiceContainer::getService(EventDispatcherInterface::class);
        $event = new UserRegisteredEvent(\User::createFromId(2));

        $returnValue = $eventDispatcher->dispatch($event);

        self::assertEquals(2, $returnValue->getUser()->id);

        $pohodaId = sqlQueryBuilder()->select('pohoda_id')
            ->from('users')
            ->where('id=2')
            ->execute()->fetchOne();

        $this->assertEquals(999, $pohodaId);
    }

    private function getActualUsers($IDs)
    {
        return sqlFetchAll(sqlQueryBuilder()
            ->select('id, pohoda_id, email')
            ->from('users')
            ->andWhere(Operator::inIntArray($IDs, 'id'))
            ->execute(), 'email');
    }
}

class PohodaConnectorMock extends PohodaConnector
{
    public function sendRequest($XmlBodyRequest)
    {
        return '<?xml version="1.0" encoding="WINDOWS-1250"?>
                <rsp:responsePack xmlns:lwl="http://www.stormware.cz/schema/version_2/liquidationWithoutLink.xsd"
                  xmlns:adb="http://www.stormware.cz/schema/version_2/addressbook.xsd"
                  xmlns:rdc="http://www.stormware.cz/schema/version_2/documentresponse.xsd"
                  xmlns:rsp="http://www.stormware.cz/schema/version_2/response.xsd" note="Users export"
                  key="0cf0e9cd-23ce-498c-8f2d-2b2149efa343" ico="0123456789" programVersion="13304.1 SQL (2.2.2023)" state="ok" id=""
                  version="2.0">
                    <rsp:responsePackItem state="ok" id="2" version="2.0">
                        <adb:addressbookResponse state="ok" version="2.0">
                            <rdc:producedDetails>
                                <rdc:id>999</rdc:id>
                                <rdc:code/>
                                <rdc:actionType>add</rdc:actionType>
                            </rdc:producedDetails>
                        </adb:addressbookResponse>
                    </rsp:responsePackItem>
                </rsp:responsePack>';
    }
}
