<?php

use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Exception\DeliveryException;
use KupShop\OrderingBundle\Exception\PaymentException;

class GLSParcelShop extends Delivery
{
    use DatabaseCommunication;

    public static $type = Delivery::TYPE_POINT;
    public static $className = 'GLS ParcelShop';

    protected $templateDescription = 'deliveries/delivery.GLSParcelShop.description.tpl';

    protected $AdminTemplateSettings = 'deliveries/block.delivery.GLSParcelShop.tpl';

    public static $tableName = '`kupshop_shared`.`delivery_glsparcelshop`';

    public static $jsonDeliveryBalikobot = 'https://test20cztest:QKCufcWs@api.balikobot.cz/gls/branches/2';

    public $zip;

    public $delivery_glsparcelshop_id;

    protected $heureka_delivery_id = 'GLS_PARCELSHOP';

    protected $zbozi_delivery_id = 'GLS_PARCELSHOP';

    protected $track_and_trace = 'https://gls-group.eu/CZ/cs/sledovani-zasilek?match=[PACKAGE_ID]';

    public $defaultIcon = '../../common/static/deliveries/gls.svg';

    public function getName()
    {
        $info = self::getInfo($this->delivery_glsparcelshop_id);

        return parent::getName().' - '.$info['city'].', '.($info['address'] ?? $info['street']).', '.$info['name'];
    }

    public function storeDeliveryInfo($data)
    {
        parent::storeDeliveryInfo($data);

        $pointData = $data['widget'] ?? '';
        $pointData = json_decode($pointData, true);

        if (empty($pointData)) {
            $id = trim($data['glsparcelshop_id'] ?? '');

            $info = $this->getInfo($id);

            return empty($id) ? [] : ($this->data = [
                'zip' => $info['zip'],
                'glsparcelshop_id' => $info['id'],
                'subtype' => $info['type'],
            ]);
        }
        $pointData['deliveryId'] = $this->id;
        $this->data += ['widget' => $pointData];

        return $this->data += [
            'glsparcelshop_id' => $this->getPointId(), // BC
        ];
    }

    public function getInfo($id = null)
    {
        // Není to úplně pěkný, ale jestli chceme do budoucna řešit extra instanci widgetu pro boxy/pobočky tak to je potřeba
        if (!empty($this->data['widget'])) {
            $data = $this->data['widget'];
        } else {
            if (is_null($id)) {
                if (!($id = getVal('glsparcelshop_id', $this->data))) {
                    return ['name' => 'Neznámá pobočka'];
                }
            }
            $data = sqlFetchAssoc(sqlQuery('SELECT * FROM '.self::$tableName.' WHERE id=:id', ['id' => $id]));
            // Make old data compatible with new data
            $data['code'] = $id;
        }

        if (!$data) {
            return ['name' => 'Neznámá pobočka'];
        }

        return $data;
    }

    public function getPointId()
    {
        return $this->data['pclshopid'] ?? $this->data['widget']['pclshopid'] ?? $this->data['glsparcelshop_id'] ?? null;
    }

    /**
     * @param       $data  admin order data
     * @param Order $order
     *
     * @return bool|string
     */
    public function applyToOrder(&$data, $order)
    {
        parent::applyToOrder($data, $order);

        $info = $this->getInfo();
        if (empty($info['id']) && empty($info['pclshopid'])) {
            return 'Není zvolena pobočka GLS ParcelShop!';
        }
        $data['delivery_zip'] = $info['zip'] ?? $info['zipcode'] ?? null;
        $data['delivery_street'] = $info['street'] ?? $info['address'] ?? null;
        $data['delivery_city'] = $info['city'] ?? null;
        $data['delivery_country'] = $info['country'] ?? $info['ctrcode'] ?? null;
        $data['delivery_firm'] = '';

        return true;
    }

    /**
     * @param $cart CartBase
     */
    public function applyToCart(CartBase $cart)
    {
        parent::applyToCart($cart);

        $info = $this->getInfo();

        if (empty($info['pclshopid'])) {
            return;
        }

        if (isset($cart->invoice['name'])) {
            $cart->delivery['name'] = $cart->invoice['name'];
            $cart->delivery['surname'] = $cart->invoice['surname'];
        }

        $cart->delivery['zip'] = $info['zipcode'] ?? null;
        $cart->delivery['street'] = $info['address'] ?? null;
        $cart->delivery['city'] = $info['city'] ?? null;
        $cart->delivery['country'] = $info['ctrcode'] ?? null;
        $cart->delivery['firm'] = '';
    }

    public function printDeliveryInfo()
    {
        $info = $this->getInfo();
        $street = $info['street'] ?? $info['address'] ?? '';
        $zip = $info['zip'] ?? $info['zipcode'] ?? '';

        return "<strong>{$info['city']}</strong>, {$street}, {$info['name']}, <strong>{$zip}</strong>";
    }

    public function checkSelected(Cart $cart, ?Payment $payment = null)
    {
        if (empty($this->data['glsparcelshop_id']) && empty($this->data['widget']) && $cart->hasData('delivery')) {
            throw new DeliveryException(translate('branch_missing_zip', 'delivery'));
        }

        if (($payment instanceof Dobirka) && (Settings::getDefault()['deliveries']['GLSParcelShop']['dobirkaGLSBOX'] ?? null)) {
            $subtype = $this->data['subtype'] ?? $this->data['widget']['parcelBox'] ?? null;
            if ($subtype == 'box' || $subtype == 1) {
                throw new PaymentException('Platba dobírkou není dostupná v případě doručení do GLS ParcelBoxu. 
                                            Zvolte prosím pobočku jiného typu nebo platbu předem.', 'Nedostupná pro GLS ParcelBox');
            }
        }

        $info = $this->getInfo();
        $currencyContext = ServiceContainer::getService(CurrencyContext::class);
        if (!empty($this->data['widget'])) {
            if (($info['ctrcode'] ?? null) && $info['ctrcode'] != $this->getCountryByCurrency($currencyContext->getActiveId())) {
                throw new DeliveryException('Vybraná pobočka GLS ParcelShop nepodporuje vaši měnu.');
            }
        } else {
            if (!empty($this->data['glsparcelshop_id']) && ($info['country'] ?? false) && $info['country'] != $this->getCountryByCurrency($currencyContext->getActiveId())) {
                throw new DeliveryException('Vybraná pobočka GLS ParcelShop nepodporuje vaši měnu.');
            }
        }

        return parent::checkSelected($cart, $payment);
    }

    /**
     * @param $currency string
     *
     * @return string
     */
    private function getCountryByCurrency($currency)
    {
        switch ($currency) {
            case 'CZK':
                return 'CZ';
                break;
            case 'EUR':
                return 'SK';
                break;
            case 'HUF':
                return 'HU';
                break;
            case 'RON':
                return 'RO';
                break;
            case 'PLN':
                return 'PL';
                break;
            default:
                return '';
        }
    }

    public static function getSettingsConfiguration(): array
    {
        return [
            'fields' => [
                'dobirkaGLSBOX' => [
                    'title' => 'Zakázat dobírku pro GLS ParcelBox',
                    'type' => 'toggle',
                    'tooltip' => 'Nepovolit platbu dobírkou při vybrání doručení do GLS ParcelBox',
                ],
            ],
        ];
    }
}
