<?php

namespace KupShop\PohodaBundle\Utils\Exporters;

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

class OrdersDeleter
{
    use \DatabaseCommunication;
    use PohodaBase;

    protected $requestTemplate = 'requests/ordersDel.tpl';
    protected $IDs;
    protected $results;

    public function getData()
    {
        $orders = $this->getOrders();

        if (!$orders) {
            return false;
        }

        return $orders;
    }

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

        getLogger()->notice('POHODA REQUEST: Order Deleter loaded orders', ['orders' => $orders]);
        $ordersBymServers = $this->splitOrdersBymServers($orders);
        if ($ordersBymServers) {
            foreach ($ordersBymServers as $mServerId => $orders) {
                $this->pohodaConnector->setActiveConfigById($mServerId);
                if (!$this->pohodaConnector->isActive()) {
                    return false;
                }
                $request = $this->pohodaConnector->getRequestContent($this->requestTemplate, ['orders' => $orders]);
                $request = $this->replace($request);
                $this->addRequestLog('Order Export Deleter', $request);
                $response = $this->pohodaConnector->sendRequest($request);
                if ($response) {
                    $this->processResponse($response);
                }
            }
        } else {
            foreach ($this->IDs as $order_id) {
                $this->results[$order_id] = [
                    'result' => false,
                    'errno' => '115',
                    'error' => 'Objednávka nemá pohoda ID',
                ];
            }
        }
    }

    protected function getOrders($spec = null)
    {
        if (!$spec && !$this->IDs) {
            throw new PohodaException('Nedefinované spec nebo id objednávek ke smazání');
        }

        getLogger()->notice('POHODA REQUEST: Order Deleter loaded IDS', ['ids' => $this->IDs]);

        $qb = sqlQueryBuilder()
            ->select('o.id, o.pohoda_id')
            ->from('orders', 'o')
            ->sendToMaster();

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

        if (!is_null($this->IDs)) {
            $qb->andWhere(Operator::inIntArray($this->IDs, 'id'));
        }

        $qb->andWhere('pohoda_id is not null');

        getLogger()->notice('POHODA REQUEST: Order Deleter loaded query', ['sql' => $qb->getRunnableSQL()]);

        return sqlFetchAll($qb->execute(), ['id' => 'pohoda_id']);
    }

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

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

        $message = [];
        foreach ($xml->xpath('rsp:responsePackItem') as $responsePackItem) {
            try {
                $this->addResponseLog('Order Export Deleter', $responsePackItem->asXML());
            } catch (\Throwable $exception) {
            }

            $attr = $responsePackItem->attributes();
            $order_id = (string) $attr['id'];
            // obj. smazána
            if ($attr['state'] == 'ok') {
                if ($order_id) {
                    $order = new \Order($order_id);
                    if (!$order->createFromDB($order_id)) {
                        continue;
                    }
                    switch ($responsePackItem->xpath('ord:orderResponse')[0]['state']) {
                        case 'ok':
                            $this->clearPohodaFieldsFromOrder($order_id);
                            $this->results[$order_id]['result'] = true;
                            $this->afterDeleteAction($order, $responsePackItem);
                            break;
                        case 'error':
                            $this->results[$order_id] = [
                                'result' => true,
                                'errno' => strval($responsePackItem->xpath('ord:orderResponse/rdc:importDetails/rdc:detail/rdc:errno')[0]),
                                'error' => strval($responsePackItem->xpath('ord:orderResponse/rdc:importDetails/rdc:detail/rdc:note')[0]),
                            ];
                            if ($this->results[$order_id]['errno'] == '115') {
                                $this->clearPohodaFieldsFromOrder($order_id);
                            } elseif ($this->results[$order_id]['errno'] == '114') {
                                $this->clearPohodaFieldsFromOrder($order_id);
                                $parts = [];
                                if ($order['invoice_firm']) {
                                    $parts[] = $order['invoice_firm'];
                                }

                                if ($order['invoice_name'] || $order['invoice_surname']) {
                                    $parts[] = join(' ', [$order['invoice_surname'], $order['invoice_name']]);
                                }
                                $name = join(', ', $parts);
                                $message[] = "Kód objednávky {$order['order_no']} (ID: {$order['id']}) {$name}";
                                $order->logHistory('Objednávka nebyla smazána z Pohody - objednávka je v Pohodě stornovaná, smažte ji v Pohodě', false);
                            }
                            break;
                        default:
                            throw new PohodaException("Nedefinovaný vrácený stav nahrání objednávky {$order_id}");
                    }
                }
            }
        }

        if (!empty($message)) {
            addActivityLog(ActivityLog::SEVERITY_WARNING,
                ActivityLog::TYPE_SYNC,
                'Objednávky se nepodařilo smazat z Pohody - objednávky jsou v Pohodě stornované, smažte je v Pohodě',
                $message);
        }
    }

    /**
     * @param null $pohoda_id
     */
    protected function afterDeleteAction(\Order $order, \SimpleXMLElement $responsePackItem, $pohoda_id = null)
    {
        $order->logHistory('Objednávka smazána z Pohody', false);
    }

    /**
     * @throws \Exception
     */
    public function clearPohodaFieldsFromOrder($order_id)
    {
        sqlQueryBuilder()
            ->update('orders')
            ->directValues([
                'pohoda_sync_date' => null,
                'pohoda_id' => null, ])
            ->where(Operator::equals(['id' => $order_id]))
            ->execute();
    }

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

    public function getResults()
    {
        return $this->results;
    }

    public function deleteStornoOrders()
    {
        $orderIds = sqlQueryBuilder()
            ->select('o.pohoda_id, o.id')
            ->from('orders o')
            ->where('o.pohoda_id is not null AND o.status_storno=1')
            ->andWhere('o.date_updated >= NOW() - INTERVAL 30 DAY')
            ->execute()->fetchAllKeyValue();

        if (!empty($orderIds)) {
            $this->setIDs($orderIds);
            $this->processData();
        }
    }
}
