<?php

namespace FCA\StockApi\Tests\Unit\Collection\Filter;

use FCA\StockApi\Collection\Filter\Builder\Fields;
use FCA\StockApi\Collection\Filter\Wizard;
use FCA\StockApi\Exception\ApiException;
use PHPUnit\Framework\TestCase;

class WizardTest extends TestCase
{
    /**
     * @throws ApiException
     */
    public function testGetFilter()
    {
        $stock = new Wizard();
        $result = $stock->getFilters();
        $this->assertEquals([], $result);

        $stock = new Wizard();
        $stock->setEnginePowerTo(104);
        $stock->setEnginePowerFrom(90);
        $result = $stock->getFilters();

        $returnArray = [
            '$and' => [
                [
                    Fields::ENGINE_POWER => [
                        '$lte' => 104
                    ]
                ],
                [
                    Fields::ENGINE_POWER => [
                        '$gte' => 90
                    ]
                ]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetEnginePowerTo()
    {
        $value = 55;

        $stock = new Wizard();
        $stock->setEnginePowerTo($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::ENGINE_POWER => [
                '$lte' => $value
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetEnginePowerFrom()
    {
        $value = 55;

        $stock = new Wizard();
        $stock->setEnginePowerFrom($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::ENGINE_POWER => [
                '$gte' => $value
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }


    /**
     * @throws ApiException
     */
    public function testSetPriceTypeWithInvalidValue()
    {
        $this->expectException(ApiException::class);
        $stock = new Wizard();
        $stock->setPriceType('invalidType');
    }

    /**
     * @throws ApiException
     */
    public function testSetFuelType()
    {
        $value = "Benzyna";

        $stock = new Wizard();
        $stock->setFuelType($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::FUEL_TYPE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetModel()
    {
        $value = "357HB";

        $stock = new Wizard();
        $stock->setModel($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::MODEL_COMMERCIAL_CODE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetInteriorType()
    {
        $value = "Skóra";

        $stock = new Wizard();
        $stock->setInteriorType($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::INTERIOR_TYPE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetPriceFrom()
    {
        $value = 65464.00;

        $stock = new Wizard();
        $stock->setPriceFrom($value);
        $stock->setPriceType(Fields::FINAL_PRICE_BRUTTO);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::FINAL_PRICE_BRUTTO => [
                '$gte' => $value
            ]
        ];

        $this->assertEquals($returnArray, $result);

        $stock = new Wizard();
        $stock->setPriceFrom($value);
        $this->expectException(ApiException::class);
        $stock->getFilters();
    }

    /**
     * @throws ApiException
     */
    public function testSetPriceTo()
    {
        $value = 65464.00;

        $stock = new Wizard();
        $stock->setPriceTo($value);
        $stock->setPriceType(Fields::FINAL_PRICE_BRUTTO);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::FINAL_PRICE_BRUTTO => [
                '$lte' => $value
            ]
        ];

        $this->assertEquals($returnArray, $result);

        $stock = new Wizard();
        $stock->setPriceTo($value);
        $this->expectException(ApiException::class);
        $stock->getFilters();
    }

    /**
     * @throws ApiException
     */
    public function testSetProductionYear()
    {
        $value = 2018;

        $stock = new Wizard();
        $stock->setProductionYear($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::PRODUCTION_YEAR => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetGearboxType()
    {
        $value = "Automatyczna";

        $stock = new Wizard();
        $stock->setGearboxType($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::GEARBOX_TYPE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetBrandCode()
    {
        $value = "00";

        $stock = new Wizard();
        $stock->setBrandCode($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::BRAND_CODE => $value
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetDriveType()
    {
        $value = "Napęd na przednie koła";

        $stock = new Wizard();
        $stock->setDriveType($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::DRIVE_TYPE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetColor()
    {
        $value = "WHITE";

        $stock = new Wizard();
        $stock->setColor($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::COLOR_CATEGORY => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testSetEquipmentCodes()
    {
        $value = "BNG";

        $stock = new Wizard();
        $stock->setEquipmentCode($value);
        $result = $stock->getFilters();

        $returnArray = [
            Fields::EQUIPMENT_CODE => [
                '$in' => [$value]
            ]
        ];

        $this->assertEquals($returnArray, $result);
    }

    /**
     * @throws ApiException
     */
    public function testNearByCoordinates()
    {
        $stock = new Wizard();
        $stock->setLatitude(12.54465);
        $stock->setLongitude(45.55478);
        $stock->setMaxDistance(10000);

        $expectedArray = [
            Fields::DEALER_COORDINATES => [
                '$near' => [
                    '$geometry' => ['type' => "Point", 'coordinates' => [45.55478, 12.54465]],
                    '$maxDistance' => 10000
                ]
            ]
        ];

        $this->assertEquals($expectedArray, $stock->getFilters());

        //===========================================================================================

        $stock = new Wizard();
        //$stock->setLatitude(12.54465);
        $stock->setLongitude(45.55478);
        $stock->setMaxDistance(10000);


        $this->assertEquals([], $stock->getFilters());

        //===========================================================================================

        $stock = new Wizard();
        $stock->setLatitude(12.54465);
        //$stock->setLongitude(45.55478);
        $stock->setMaxDistance(10000);


        $this->assertEquals([], $stock->getFilters());

        //===========================================================================================

        $stock = new Wizard();
        $stock->setLatitude(12.54465);
        $stock->setLongitude(45.55478);
        //$stock->setMaxDistance(10000);


        $this->assertEquals([], $stock->getFilters());
    }

    /**
     * @throws ApiException
     */
    public function testSetLatitudeWithBadValue()
    {
        $stock = new Wizard();
        $this->expectException(ApiException::class);
        $stock->setLongitude("45.55478");
    }

    /**
     * @throws ApiException
     */
    public function testSetLongitudeWithBadValue()
    {
        $stock = new Wizard();
        $this->expectException(ApiException::class);
        $stock->setLongitude("45.55478");
    }

    /**
     * @throws ApiException
     */
    public function testSetMaxDistanceWithBadValue()
    {
        $stock = new Wizard();
        $this->expectException(ApiException::class);
        $stock->setLongitude("45.55478");
    }
}
