<?php

namespace Admin;

use Export\ExportDataDBFUcto;
use KupShop\AdminBundle\Exception\ExportException;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\OrdersExcelExport;
use KupShop\OrderingBundle\OrdersItemsExcelExport;
use Query\Operator;

class Export
{
    public const EXPORT_TYPES_MAPPING = [
        'products_selling' => 'productsSelling',
    ];

    protected $ORDERS_LIMIT = 100000;

    protected $handled;

    protected $encoding;

    protected $format;

    protected $params = [];

    protected $orderIds = [];

    protected $type;

    public function setOrderIds($ids)
    {
        $this->orderIds = $ids;
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    public function setFormat($format)
    {
        $this->format = $format;
    }

    public function run()
    {
        $type = getVal('type', null, $this->type);
        $data = getVal('data');

        $this->format = getVal('format', null, $this->format);
        $this->handled = getVal('what', $data);
        $this->encoding = getVal('coding', null, 'utf-8');

        $filter = getVal('filter');
        if ($filter['date_handled']['to'] ?? false) {
            $this->params['dateTo'] = $filter['date_handled']['to'];
        } elseif ($filter['date_created']['to'] ?? false) {
            $this->params['dateTo'] = $filter['date_created']['to'];
        } else {
            $this->params['dateTo'] = '';
        }
        if ($filter['date_handled']['from'] ?? false) {
            $this->params['dateFrom'] = $filter['date_handled']['from'];
        } elseif ($filter['date_created']['from'] ?? false) {
            $this->params['dateFrom'] = $filter['date_created']['from'];
        } else {
            $this->params['dateFrom'] = '';
        }

        $this->params['data'] = getVal('data');
        $this->params['format'] = $this->format;

        if (array_key_exists($type, self::EXPORT_TYPES_MAPPING)) {
            $type = self::EXPORT_TYPES_MAPPING[$type];
        }

        if ($type == 'orders') {
            $report = 'Export objednávek: ';
            $report .= 'format = '.$this->format.'; ';
            $report .= ($this->params['dateFrom'] ? 'datum od = '.$this->params['dateFrom'].'; ' : '');
            $report .= ($this->params['dateTo'] ? 'datum do = '.$this->params['dateTo'].'; ' : '');
            $report .= (($this->handled == 'Y') ? 'jen vyřízené objednávky; ' : '');
            writeDownActivity($report);
        }

        ini_set('memory_limit', '1024M');
        ini_set('max_execution_time', '600');

        try {
            $method = 'export'.ucfirst($type);
            if (method_exists($this, $method)) {
                $this->$method();
            } else {
                $this->applyFallback();
            }
        } catch (ExportException $e) {
            redirect('launch.php?s=board.php&type=export_orders&ErrStr='.urlencode($e->getMessage()));
        }
    }

    protected function getOrderIdsToExport()
    {
        if (!empty($this->orderIds)) {
            return $this->orderIds;
        }

        $filter = getVal('filter');
        $ordersFilterSpecs = ServiceContainer::getService(\KupShop\AdminBundle\Util\Filter\OrdersFilterSpecs::class);
        $specs = $ordersFilterSpecs->getSpecs($filter);
        $qb = sqlQueryBuilder()->select('o.id')->from('orders', 'o')
                ->setMaxResults($this->ORDERS_LIMIT)
                ->orderBy('o.id', 'ASC');

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

        $order_ids = getVal('order_ids');

        if ($order_ids) {
            $order_ids = explode(',', $order_ids);
            $order_ids = array_map('trim', $order_ids);
            $qb->andWhere(Operator::inStringArray($order_ids, 'o.order_no'));
        }

        $orders = $qb->execute();

        if ($orders->rowCount() >= $this->ORDERS_LIMIT) {
            throw new ExportException('Export se nepodařil, protože byl překročen limit '.$this->ORDERS_LIMIT.' objednávek');
        }

        return array_map(function ($x) {
            return $x['id'];
        }, $orders->fetchAll());
    }

    public function exportOrders()
    {
        if (in_array($this->format, ['overview', 'excelOss', 'excel', 'excelWithItems'])) {
            // Overview se renderuje u klienta, tak zvednem limit
            $this->ORDERS_LIMIT = 1000000;
        }

        include_once 'export/orders.php';
        $export = new \ExportOrders();
        $export->setOrderIds($this->getOrderIdsToExport());

        if ($this->format == 'csv' || $this->format == 'csv_premier' || $this->format == 'csv_helios') {
            $this->params['file_ext'] = 'csv';
            $this->params['content_type'] = 'application/csv';
            $export->exportData($this->params);
        } elseif ($this->format == 'txt_premier') {
            $this->params['file_ext'] = 'txt';
            $this->params['content_type'] = 'application/txt';
            $export->exportData($this->params);
        } elseif ($this->format == 'dbf_ucto') {
            $dateFrom = null;
            $dateTo = null;
            $filename_dates = '';
            if (!empty($this->params['dateFrom'])) {
                $dateFrom = new \DateTime($this->params['dateFrom']);
                $filename_dates .= '_'.$dateFrom->format('Y-m-d');
            }
            if (!empty($this->params['dateTo'])) {
                $dateTo = new \DateTime($this->params['dateTo']);
                $filename_dates .= (empty($filename_dates) ? '_x-' : '-').$dateTo->format('Y-m-d');
            } else {
                if (!empty($filename_dates)) {
                    $filename_dates .= '-x';
                }
            }

            $dbcfg = \Settings::getDefault();

            $filename = createScriptURL_Text($dbcfg->shop_title).$filename_dates.'.dbf';

            $ids = $export->getOrderIds();

            $export = new ExportDataDBFUcto('browser', $filename);
            $export->setCoding($this->encoding);
            $export->initialize();

            $export->loadOrdersData($ids);

            $export->finalize();
        } elseif ($this->format == 'pohoda' || $this->format == 'pohoda_with_items') {
            $this->params['file_ext'] = 'xml';
            $this->params['content_type'] = 'application/xml';

            $export->exportData($this->params);
        } elseif ($this->format == 'excel') {
            /** @var $excelExport OrdersExcelExport */
            $excelExport = ServiceContainer::getService(OrdersExcelExport::class);
            $excelExport->setOrderIDs($this->getOrderIdsToExport());
            $excelExport->export();
        } elseif ($this->format == 'excelOss') {
            $excelExport = ServiceContainer::getService(\KupShop\OSSVatsBundle\OssOrdersExcelExport::class);
            $excelExport->setOrderIDs($this->getOrderIdsToExport());
            $excelExport->export();
        } elseif ($this->format == 'excelWithItems') {
            /** @var $excelExport OrdersItemsExcelExport */
            $excelExport = ServiceContainer::getService(OrdersItemsExcelExport::class);
            $excelExport->setOrderIDs($this->getOrderIdsToExport());
            $excelExport->export();
        } elseif ($this->format == 'money' || $this->format == 'money_foreign' || $this->format == 'money_s4s5' || $this->format == 'flexibee') {
            $this->params['file_ext'] = 'xml';
            $this->params['content_type'] = 'application/xml';
            $export->exportData($this->params);
        } else {
            $this->applyFallback();
        }
    }

    protected function applyFallback()
    {
        $orderIds = $this->getOrderIdsToExport();

        include_once 'export_sracka.php';
    }

    public static function getOrderPayment(\Order $order)
    {
        if ($payment = $order->getDeliveryType()->getPayment()) {
            switch ($payment->getPayMethod()) {
                case \Payment::METHOD_COD:
                    return 'COD';
                case \Payment::METHOD_CASH:
                    return 'CASH';
                case \Payment::METHOD_TRANSFER:
                    return 'TRANSFER';
            }
        }

        return 'COD';
    }
}

return Export::class;
