<?php

use KupShop\KupShopBundle\Util\Delivery\RestrictionParams;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use KupShop\OrderingBundle\Exception\DeliveryException;

class PPL extends Delivery
{
    public static $className = 'PPL';

    protected $heureka_delivery_id = 'PPL';
    protected $zbozi_delivery_id = 'PPL';

    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]',
        'DE' => 'https://www.ppl.cz/en/track-a-shipment?shipmentId=[PACKAGE_ID]',
    ];

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

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

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

    /**
     * @param $cart \Cart
     */
    public function check(Cart $cart)
    {
        if ($cart->hasData('user') && $cart->addressesSet && !empty($cart->invoice['zip'])) {
            // Check ZIP exists
            $country = $cart->invoice['country'];
            if ($country == 'CZ' || $country == 'SK') {
                $zip = $cart->invoice['zip'];
                $zipRow = sqlQueryBuilder()->select('id')->from('kupshop_shared.delivery_ppl_zip')
                    ->where('country=:country AND zip=:zip')->setParameters(['country' => $country, 'zip' => $zip])
                    ->setMaxResults(1)->execute()->fetch();
                if (!$zipRow && $cart->hasData('delivery')) {
                    throw new DeliveryException(translate('false_zip', 'order_error'));
                }
            }
        }

        return parent::check($cart);
    }

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

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

        return $rParams;
    }

    public static function calculateMaxSumOfDimensions(RestrictionParams $rParams): float
    {
        $dimensions = $rParams->getMaxDimensions();

        if (is_array($dimensions)) {
            sort($dimensions);
        }

        // A + 2B + 2C, kde A je nejdelsi strana
        return (float) ($rParams->getMaxLength() + (2 * ($dimensions[0] ?? 0.0)) + (2 * ($dimensions[1] ?? 0.0)));
    }

    /**
     * @return bool
     *
     * @throws Exception
     */
    public function import()
    {
        $dataToImport = [];
        foreach (self::$jsonZipCodesURLs as $country => $url) {
            $json = file_get_contents($url);
            $data = json_decode_strict($json, true);
            if ($data['status'] ?? 0 === 200 && count($data['zip_codes'] ?? []) > 0) {
                $dataToImport[$country] = $data;
            }
        }

        if (count($dataToImport) !== count(self::$jsonZipCodesURLs)) {
            return false;
        }

        sqlGetConnection()->transactional(function () use ($dataToImport) {
            sqlQuery('DELETE FROM '.self::$tableName.' WHERE 1');
            $index = 1;
            foreach ($dataToImport as $data) {
                foreach ($data['zip_codes'] as $id => $zipData) {
                    if (!empty($zipData['country']) && !empty($zipData['zip'])) {
                        sqlQueryBuilder()->insert(self::$tableName)
                            ->directValues(
                                [
                                    'id' => $index++,
                                    'country' => $zipData['country'],
                                    'zip' => $zipData['zip'],
                                    'evening_delivery' => $zipData['del_eveninig'] ?? $zipData['del_evening'] ?? false,
                                ]
                            )
                            ->execute();
                    }
                }
            }
        });

        return true;
    }
}
