<?php

use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Delivery\RestrictionParams;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;

class PPLParcelShop extends Delivery
{
    use DatabaseCommunication;

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

    protected $track_and_trace = [
        'EN' => 'https://www.ppl.cz/en/track-a-shipment?shipmentId=[PACKAGE_ID]',
        'CZ' => 'https://www.ppl.cz/cs/track-a-shipment?shipmentId=[PACKAGE_ID]',
        'SK' => 'https://www.ppl.cz/cs/track-a-shipment?shipmentId=[PACKAGE_ID]',
        'PL' => 'https://www.ppl.cz/en/track-a-shipment?shipmentId=[PACKAGE_ID]',
        'DE' => 'https://www.logistics.dhl/de-de/home/tracking.html?tracking-id=[PACKAGE_ID]&submit=1',
    ];

    protected $templateInit = 'deliveries/delivery.PPLParcelShop.init.tpl';

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

    protected $AdminTemplateSettings = 'deliveries/block.delivery.PPLParcelShop.tpl';
    protected $adminWindowTemplate = 'delivery/delivery.PPLParcelShop.customData.tpl';

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

    public static $jsonDeliveryBalikobot = [
        'CZ' => 'https://test20cztest:QKCufcWs@api.balikobot.cz/ppl/branches/4',
        'SK' => 'https://test20cztest:QKCufcWs@api.balikobot.cz/ppl/branches/2/SK',
        'DE' => 'https://test20cztest:QKCufcWs@api.balikobot.cz/ppl/branches/2/DE',
        'PL' => 'https://test20cztest:QKCufcWs@api.balikobot.cz/ppl/branches/2/PL',
    ];

    public $zip;

    public $delivery_pplparcelshop_id;

    protected $heureka_delivery_id = 'PPL_PARCELSHOP';
    protected $zbozi_delivery_id = 'PPL_PARCELSHOP';

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

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

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

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

        $pointData = $data['PPLParcelShop_data'] ?? '';
        $pointData = json_decode($pointData, true);
        $pointData['deliveryId'] = $this->id;

        if (empty($pointData)) {
            $pointData = $data['pplparcelshop_id'] ?? '';
            if (empty($pointData)) {
                return [];
            }
        }

        return $this->data += ['PPLParcelShop_data' => $pointData];
    }

    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 (($this->data['PPLParcelShop_data']['deliveryId'] ?? false) == $this->id) {
            $data = $this->data['PPLParcelShop_data'];
        } else {
            if (is_null($id)) {
                $id = getVal('pplparcelshop_id', $this->data);
            }
            $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;
    }

    /**
     * @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'])) {
            return 'Není zvolena pobočka PPL ParcelShop!';
        }
        $data['delivery_zip'] = $info['zip'] ?? $info['zipCode'];
        $data['delivery_street'] = $info['street'];
        $data['delivery_city'] = $info['city'];
        $data['delivery_country'] = $info['country'];
        $data['delivery_firm'] = '';

        return true;
    }

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

        $info = $this->getInfo();

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

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

        $cart->delivery['zip'] = $info['zip'] ?? $info['zipCode'];
        $cart->delivery['street'] = $info['street'];
        $cart->delivery['city'] = $info['city'];
        $cart->delivery['country'] = $info['country'];
        $cart->delivery['firm'] = '';
    }

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

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

    public function getPointId()
    {
        return $this->data['PPLParcelShop_data']['code'] ?? $this->data['pplparcelshop_id'] ?? null;
    }

    public function checkSelected(Cart $cart, ?Payment $payment = null)
    {
        if (empty($this->data['pplparcelshop_id']) && empty($this->data['PPLParcelShop_data']['code']) && $cart->hasData('delivery')) {
            throw new \KupShop\OrderingBundle\Exception\DeliveryException(translate('branch_missing_zip', 'delivery'));
        }

        $info = $this->getInfo();
        $currencyContext = ServiceContainer::getService(CurrencyContext::class);
        if (!empty($this->data['pplparcelshop_id']) && !in_array($info['country'],
            $this->getCountryByCurrency($currencyContext->getActiveId()))) {
            throw new \KupShop\OrderingBundle\Exception\DeliveryException(translate('branch_currency_not_supported', 'delivery'));
        }

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

    public function importFromBalikobot($url = null, $where = null)
    {
        foreach (static::$jsonDeliveryBalikobot as $country => $url) {
            parent::importFromBalikobot($url, \Query\Operator::equals(['country' => $country]));
        }
    }

    protected function getRestrictionParams(PurchaseState $purchaseState): RestrictionParams
    {
        $rParams = clone parent::getRestrictionParams($purchaseState);

        $rParams->setMaxSumOfDimensions(
            PPL::calculateMaxSumOfDimensions($rParams)
        );

        return $rParams;
    }

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

    public function BOXOnly(): bool
    {
        $hidden_points = $this->getCustomData()['widget_options']['hidden_points'] ?? [];

        if (in_array('ParcelShop', $hidden_points)) {
            // hidden ParcelShop - show only boxes
            return true;
        }

        return false;
    }
}
