<?php

namespace KupShop\PohodaBundle\Utils\Exporters;

use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\PohodaBundle\Exceptions\PohodaException;
use KupShop\PohodaBundle\Utils\PohodaBase;
use KupShop\PohodaBundle\Utils\Tools\PohodaOrderExporter;
use Query\Operator;

class IssuesExporter
{
    use \DatabaseCommunication;
    use PohodaBase;

    /**
     * @var PohodaOrderExporter
     */
    public $orderExporter;

    protected $IDs;

    /**
     * @return bool|string
     */
    public function getData()
    {
        $orders = $this->getOrders();

        if (!$orders) {
            return false;
        }

        return $this->orderExporter->getXML($orders, true);
    }

    /**
     * @param null $xml
     *
     * @throws PohodaException
     */
    public function processData($xml = null)
    {
        $this->pohodaConnector->prepareSyncTime();

        if (!$xml) {
            $xml = $this->getData();
        }

        if ($xml) {
            $ordersRequest = $this->transformHelper->baseTransform($xml, $this->transformHelper->loadXslt('issuesOut.xsl'));

            $request = $this->replace($ordersRequest->saveXML());

            $response = $this->pohodaConnector->sendRequest($request);

            if ($response) {
                $this->processResponse($response);
            }
        }

        $this->pohodaConnector->setLastSyncTime('IssuesOut');
        $this->setIDs(null);
    }

    protected function getOrders($spec = null)
    {
        if (!$this->isFullSync()) {
            $qb = sqlQueryBuilder()
                ->select('o.id')
                ->from('orders', 'o');

            if ($spec) {
                $qb->andWhere($spec);
            }

            if (!is_null($this->IDs)) {
                $qb->andWhere(Operator::inIntArray($this->IDs, 'id'));
            } else {
                if (!empty($this->pohodaConnector->getCurrent()['IssuesOut']['last_sync'])) {
                    $datetime = new \DateTime();
                    $datetime->setTimestamp(strtotime($this->pohodaConnector->getCurrent()['IssuesOut']['last_sync']));
                    if ($this->pohodaConnector->getCurrent()['IssuesOut']['last_sync_diff'] ?? false) {
                        $datetime = $datetime->modify("-{$this->pohodaConnector->getCurrent()['IssuesOut']['last_sync_diff']} day");
                    }

                    $qb->andWhere('date_created >="'.$this->prepareDateTime($datetime).'"');
                } else {
                    $qb->andWhere('date_created >= NOW() - INTERVAL 7 DAY');
                }
            }

            $qb->andWhere('o.pohoda_id is null');
            $qb->andWhere('status_storno=0');

            return array_keys(sqlFetchAll($qb->execute(), 'id'));
        }
    }

    protected function processResponse($xmlStringResponse)
    {
        $xml = simplexml_load_string($xmlStringResponse);

        $this->pohodaConnector->checkValidResponse($xml);

        foreach ($xml->xpath('rsp:responsePackItem') as $responsePackItem) {
            // Doklad se zadaným číslem objednávky již existuje
            try {
                if (!$responsePackItem->xpath('vyd:vydejkaResponse/rdc:importDetails/rdc:detail/rdc:errno[text() = 109]')) {
                    $attr = $responsePackItem->attributes();

                    if ($attr['id']) {
                        $order = new \Order($attr['id']);
                        if (!$order->createFromDB($attr['id'])) {
                            continue;
                        }

                        switch ($attr['state']) {
                            case 'ok':
                                $orderUpdateQuery =
                                    sqlQueryBuilder()
                                        ->update('orders')
                                        ->set('pohoda_sync_date', 'NOW()')
                                        ->where(Operator::equals(['id' => $attr['id']]));

                                $pohoda_id = 'UNDEFINED';
                                if ($responsePackItem->xpath('vyd:vydejkaResponse/rdc:producedDetails/rdc:id')) {
                                    $pohoda_id = strval($responsePackItem->xpath('vyd:vydejkaResponse/rdc:producedDetails/rdc:id/text()')[0]);
                                    $orderUpdateQuery->set('pohoda_id', $pohoda_id);
                                }

                                $orderUpdateQuery->execute();
                                $this->afterInsertAction($order, $responsePackItem, $pohoda_id);
                                break;
                            case 'error':
                                $order->logHistory('Výdejku se nepodařilo nahrát do Pohody', false);
                                // no break
                            default:
                                throw new PohodaException("Nedefinovaný vrácený stav nahrání výdejky {$attr['id']}");
                        }
                    }
                }
            } catch (\Exception $e) {
                addActivityLog(ActivityLog::SEVERITY_ERROR, ActivityLog::TYPE_SYNC, 'Výdejku '.$order->order_no.' se nepodařilo nahrát do Pohody '.$attr['note'], ['message' => $e->getMessage(), 'orderId' => $order->order_no, 'responseObject' => (array) $responsePackItem, 'orderObject' => (array) $order]);
            }
        }
    }

    /**
     * @required
     */
    public function setOrderExporter(PohodaOrderExporter $orderExporter)
    {
        $this->orderExporter = $orderExporter;
    }

    /**
     * @param null $pohoda_id
     */
    protected function afterInsertAction(\Order $order, \SimpleXMLElement $responsePackItem, $pohoda_id = null)
    {
        $order->logHistory("Výdejka nahrána do Pohody; ID:{$pohoda_id}", false);
    }

    public function setIDs($IDs)
    {
        $this->IDs = $IDs;
    }
}
