<?php

/**
 * Created by PhpStorm.
 * User: ondra
 * Date: 14.2.18
 * Time: 9:17.
 */

namespace KupShop\OrderingBundle\Tests;

use KupShop\DevelopmentBundle\Util\Tests\CartTestTrait;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Exception\DeliveryException;
use KupShop\OrderingBundle\Util\Order\OrderInfo;

class DeliveryTest extends \DatabaseTestCase
{
    use CartTestTrait;

    private OrderInfo $orderInfo;

    protected function setUp(): void
    {
        parent::setUp();

        $this->orderInfo = ServiceContainer::getService(OrderInfo::class);
    }

    /**
     * @dataProvider data_deliveryPriceDontCountinFrom
     */
    public function testDeliveryPriceDontCountinFrom(
        int $productId,
        int $deliveryType,
        int $expectedDeliveryPrice,
        bool $logged,
        string $message,
    ): void {
        if ($logged) {
            $this->loginUser(1);
        }

        $this->createCart();
        $this->insertProduct($productId);
        $this->setDeliveryType($deliveryType);
        $this->cart->createFromDB();

        $this->assertEquals(
            $expectedDeliveryPrice,
            $this->cart->getDeliveryType()->getDelivery()->getPrice()->getPriceWithVat()->asFloat(),
            $message
        );
    }

    public function data_deliveryPriceDontCountinFrom(): array
    {
        return [
            [3, 2, 99, false, 'Delivery dont_countin_from is 99 Kc, item price is 91 Kc. Delivery should not be free.'],
            [2, 2, 0, false, 'Delivery dont_countin_from is 99 Kc, item price is 99 Kc. Delivery should be free.'],
            [4,
                2,
                99,
                false,
                'Delivery dont_countin_from is 99 Kc and dont_countin_from_reg is 50 Kc, item price is 60 Kc and user is not logged. Delivery should not be free.', ],
            [4, 2, 0, true, 'Delivery dont_countin_from_reg is 50 Kc, item price is 60 Kc and user is logged. Delivery should be free.'],
        ];
    }

    public function testBalikNaPostuPSC()
    {
        $this->createCart();
        $this->insertProduct(1, 16, 1);
        $this->setInvoice();

        $this->cart->max_step_submitted = 1;
        $_REQUEST['delivery_data'][1]['balik_na_postu_zip'] = '54234';
        $this->setDeliveryType(1);
        $this->cart->createFromDB();
        $_REQUEST['delivery_data'][1]['balik_na_postu_zip'] = '';

        $exception = null;
        try {
            $this->cart->getDeliveryType()->getDelivery()->check($this->cart);
        } catch (DeliveryException $e) {
            $exception = $e;
        }

        $this->assertNull($exception);
    }

    public function testDeliveryDateNothingInStore()
    {
        $this->prepareCart();
        $this->insertProduct(1, 16, 1);
        $this->cart->createFromDB();

        $order = $this->submitOrder();
        $deliveryDate = $this->orderInfo->getDeliveryDate($order);

        $this->assertNull($deliveryDate);
    }

    /**
     * @dataProvider data_inStore
     */
    public function testDeliveryDateProductIsInStore($variation)
    {
        $this->prepareCart();
        $this->insertProduct(1, $variation, 1);
        $this->cart->createFromDB();

        $order = $this->submitOrder();
        $deliveryDate = $this->orderInfo->getDeliveryDate($order);

        $delivery = $order->getDeliveryType()->getDelivery();
        $expectedDeliveryDays = $delivery->getDeliveryDays();
        $expectedDeliveryDate = $delivery->calcWorkingDays($expectedDeliveryDays['min']);

        $dateFormat = 'Y.m.d';
        $this->assertEquals($expectedDeliveryDate->format($dateFormat), $deliveryDate->format($dateFormat));
    }

    public function testDeliveryPriceVatByProductsMaxVat(): void
    {
        $dbcfg = \Settings::getDefault();
        $dbcfg->delivery_config['from_products'] = 'Y';

        $this->prepareCart();
        $this->insertProduct(5);
        $this->cart->createFromDB();

        $deliveryPrice = $this->cart->getDeliveryType()->getDelivery()->getPrice();

        $this->assertEquals(15, $deliveryPrice->getVat()->asFloat(), 'Vat should be 15% bcs max vat of products in cart is 15%');

        // now insert product with 21% vat
        $this->insertProduct(4);
        $this->recalculateCart();

        // call `getPrice` so we test that `priceCache` member is not used when max vat changed
        $deliveryPrice = $this->cart->getDeliveryType()->getDelivery()->getPrice();

        $this->assertEquals(21, $deliveryPrice->getVat()->asFloat(), 'Vat should be 21% bcs max vat of products in cart is now 21%');
    }

    public function data_inStore()
    {
        return [
            [17], // in store
            [18], // in store supplier
        ];
    }

    public function getDataSet()
    {
        return $this->getJsonDataSetFromFile();
    }
}
