<?php

declare(strict_types=1);

/*
 * This file is part of vonRotenberg WMFGO Cevisio Bundle.
 *
 * (c) vonRotenberg
 *
 * @license proprietary
 */

namespace vonRotenberg\WmfgoCevisioBundle\Cron;

use Contao\CoreBundle\Controller\AbstractController;
use Contao\Date;
use Contao\System;
use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use vonRotenberg\ShopwareApiBundle\API\Shopware;
use vonRotenberg\ShopwareApiBundle\Helper\ShopwareMappings;
use vonRotenberg\WmfgoCevisioBundle\Model\Import\ProductModel;

class ShopwareExportOrdersJob extends AbstractController
{
    /** @var LoggerInterface */
    private $logger;

    /** @var SerializerInterface */
    private $serializer;

    /** @var Shopware */
    private $shopware;

    /** @var ShopwareMappings */
    private $mappings;

    private $xmlContext = [];

    /** @var Finder */
    private $finder;

    /** @var Connection */
    private $db;

    /**
     * Remote
     * @var Connection
     */
    private $rdb;

    public function __construct(Finder $finder, Shopware $shopware, ShopwareMappings $mappings, Connection $db, LoggerInterface $logger)
    {
        $this->finder = $finder;
        $this->db = $db;
        $this->logger = $logger;
        $this->shopware = $shopware;
        $this->mappings = $mappings;

        $encoder      = [new XmlEncoder()];
        $normalizer   = [new ObjectNormalizer()];
        $this->serializer = new Serializer($normalizer,$encoder);

        $this->xmlContext = [
            'xml_root_node_name' => 'Order',
            'xml_encoding' => 'UTF-8',
            'xml_format_output' => true,
        ];
    }

    public function export(string $scope, ?string $start=null, ?string $stop=null, ?SymfonyStyle &$io = null): void
    {
        $intCounter = 0;
        $isCli = false;
        if (strtolower($scope) == 'cli' && $io !== null) {
            $isCli = true;
        }
        $translator = System::getContainer()->get('translator');
        $translator->setLocale('de');
//        date_default_timezone_set('Europe/Berlin');
        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
        $srcDir = $projectDir.'/export/orders';
        if (!file_exists($srcDir)) {
            mkdir($srcDir, 0777,true);
        }

        $Today = new Date();

        if (($start || $stop) && ($start === null || $stop === null))
        {
            return;
        }

        // Set working period
        if ($start && $stop) {
            $StartDate = new Date($start,'Y-m-d');
            $StopDate = new Date($stop,'Y-m-d');
            $intStart = $StartDate->dayBegin;
            $intEnd = $StopDate->dayEnd;
        } else {
            $WorkingDate = new Date($Today->dayBegin);
            $intStart = strtotime(date('Y-m-d',$WorkingDate->dayBegin) . ' -1 day');
            $intEnd = $WorkingDate->dayBegin;
        }

        if ($isCli) {
            $io->definitionList('Using export timeframe:',['Start'=>Date::parse(Date::getNumericDateFormat(),$intStart)],['End'=>Date::parse(Date::getNumericDateFormat(),$intEnd)]);
        }

        $arrFilter = [
            [
                'type'=> 'range',
                'field'=> 'createdAt',
                'parameters'=> [
                    'gte'=> date(\DateTime::ATOM,$intStart),
                    'lte'=> date(\DateTime::ATOM,$intEnd),
                ],
            ],
        ];

        $Response = $this->shopware->findOrdersByFilter($arrFilter);

        if ($Response->getStatusCode() !== 200 || !json_validate($Response->getContent())) {
            if ($isCli) $io->error('Could not export orders');
            dump($Response->getContent(false));
        }

        $Content = json_decode($Response->getContent(), true);

        foreach ($Content['data'] as $order)
        {
            $arrOrderExport = [];
//            dump($order);die;
//            dump($order);

            $Delivery = count($order['deliveries']) ? array_shift($order['deliveries']) : null;
            $Transaction = count($order['transactions']) ? array_shift($order['transactions']) : null;
            $LineItems = count($order['lineItems']) ? $order['lineItems'] : null;

            $arrOrderExport = [
                '@xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
                '@xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
                'OrderNumber' => $order['orderNumber'],
                'OrderDate'   => date(\DateTime::ATOM,strtotime($order['createdAt'])),
                'TODO' => 'One field missing',
                'PaymentMethod' => isset($Transaction['paymentMethod']['name']) ? $Transaction['paymentMethod']['name'] : null,
                'ShippingKind' => isset($Delivery['shippingMethod']['name']) ? $Delivery['shippingMethod']['name'] : null,
                'BuyerId'     => $order['orderCustomer']['email'],
                'BuyerFirstName'     => $order['billingAddress']['firstName'],
                'BuyerLastName'     => $order['billingAddress']['lastName'],
                'BuyerCompanyName' => $order['billingAddress']['company'],
                'BuyerStreet' => $order['billingAddress']['street'],
                'BuyerPostalCode' => $order['billingAddress']['zipcode'],
                'BuyerCity' => $order['billingAddress']['city'],
                'BuyerCountry' => $order['billingAddress']['country']['name'],
                'BuyerCountryCode' => $order['billingAddress']['country']['iso'],
                'BuyerEmail' => $order['orderCustomer']['email'],
                'BuyerPhone' => $order['billingAddress']['phoneNumber'],
                'BuyerVATID' => $order['billingAddress']['vatId'],
            ];

            if (count($Delivery['shippingOrderAddress']))
            {
                $arrOrderExport = array_merge($arrOrderExport,[
                    'ShippingName1' => $Delivery['shippingOrderAddress']['firstName']. ' '.$Delivery['shippingOrderAddress']['lastName'],
                    'ShippingStreet' => $Delivery['shippingOrderAddress']['street'],
                    'ShippingPostalCode' => $Delivery['shippingOrderAddress']['zipcode'],
                    'ShippingCity' => $Delivery['shippingOrderAddress']['city'],
                    'ShippingCountry' => $Delivery['shippingOrderAddress']['country']['name'],
                    'ShippingCountryCode' => $Delivery['shippingOrderAddress']['country']['iso'],
                    'ShippingPhone' => $Delivery['shippingOrderAddress']['phoneNumber'],
                ]);
            }

            $arrOrderExport = array_merge($arrOrderExport,[
                'PriceDeclaration' => ucfirst($order['taxStatus']),
                'TotalAmount' => $order['amountTotal'],
                'ShippingCosts' => $order['shippingTotal'],
                'PaidAmount' => in_array($Transaction['paymentMethod']['shortName'],['cash_payment','pre_payment']) ? 0.00 : $order['amountTotal'],
            ]);

            if (count($LineItems))
            {
                $arrPositions = [];
                foreach ($LineItems as $item)
                {
                    if ($item['type'] == 'promotion')
                    {
                        $arrPositions['Position'][] = [
                            'PositionNumber' => $item['position'],
                            'ProductNumber' => 'Rabatt-'.$item['payload']['promotionId'],
                            'ProductName' => 'Rabatt als Artikel ('.$item['label']. ' - ' .($item['priceDefinition']['type'] == 'percentage' ? $item['priceDefinition']['percentage']*-1 . '%' : $item['priceDefinition']['price']*-1 . ' EUR') . ')',
                            'Quantity' => $item['quantity'],
                            'Unit' => 'Stk',
                            'UnitPrice' => $item['unitPrice'],
                            'TaxRate' => $item['price']['calculatedTaxes'][0]['taxRate'],
                        ];
                    } else {
                        $arrPositions['Position'][] = [
                            'PositionNumber' => $item['position'],
                            'ProductNumber' => isset($item['product']) ? $item['product']['productNumber'] : null,
                            'ProductName' => $item['label'],
                            'Quantity' => $item['quantity'],
                            'Unit' => 'Stk',
                            'UnitPrice' => $item['unitPrice'],
                            'TaxRate' => $item['price']['calculatedTaxes'][0]['taxRate'],
                        ];
                    }
                }

                $arrOrderExport = array_merge($arrOrderExport,['Positions' => $arrPositions]);
            }

            \file_put_contents($projectDir.'/export/orders/order__' . $order['orderNumber'] . '.xml', $this->serializer->encode($arrOrderExport,'xml', $this->xmlContext));
        }


    }
}