<?php

namespace KupShop\WarehouseBundle\Tests;

use KupShop\AdminBundle\Util\Stats\StoreDataLoader;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use Query\Operator;

/**
 * @testCase
 *
 * @author <jaroslavklima@wpj.cz>
 */
class StoreDataLoaderTest extends \DatabaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        sqlQuery('SET SESSION sql_mode = "TRADITIONAL"');
        $dt = (new \DateTimeImmutable('now'))
            ->setTime(23, 59, 59)
            ->format('Y-m-d H:i:s');

        sqlQuery('UPDATE warehouse_log SET update_datetime = :dt WHERE id = 999', ['dt' => $dt]);

        $this->updateStockInDates(999);
    }

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

    /**
     * @dataProvider provideDateTime
     */
    public function testGetCurrentStoreQb(\DateTimeInterface $dateTime, int $quantity): void
    {
        $storeDataLoader = ServiceContainer::getService(StoreDataLoader::class);
        $this->assertSame(
            $quantity,
            $storeDataLoader
                ->getCurrentStoreQb($dateTime->format('Y-m-d H:i:s'))
                ->select('*')
                ->execute()->rowCount()
        );
    }

    /**
     * @dataProvider provideDateTime
     */
    public function testGetCurrentStoreValue(\DateTimeInterface $dateTime, int $quantity): void
    {
        $storeDataLoader = ServiceContainer::getService(StoreDataLoader::class);
        $exp = $storeDataLoader->getCurrentStoreValue($dateTime->format('Y-m-d H:i:s'));

        if ($quantity === 0) {
            $this->assertSame(['without_vat' => null, 'with_vat' => null], $exp);
        } else {
            $this->assertSame(['without_vat' => 5.1, 'with_vat' => 6.170999999999999], array_map(fn ($v) => (float) $v, $exp));
        }
    }

    public function provideDateTime(): \Generator
    {
        $dt = (new \DateTimeImmutable('now'))->setTime(11, 11, 11);

        yield 'midnight same day' => [$dt->setTime(0, 0), 1];
        yield 'one second before (same day)' => [$dt->modify('-1 seconds'), 1];
        yield 'referral time' => [$dt, 1];
        yield 'one second after (next day)' => [$dt->modify('+1 seconds'), 1];

        yield 'day before stock in' => [$dt->setTime(0, 0, 0)->modify('-1 seconds'), 0];
        yield 'referral time day before' => [(new \DateTimeImmutable())->modify('-1 day')->setTime(23, 59, 59), 0];
    }

    private function updateStockInDates(int $stockInId): void
    {
        $now = new \DateTime();

        sqlQueryBuilder()
            ->update('stock_in')
            ->directValues([
                'date_created' => "{$now->format('Y')}-01-01 00:00:00",
                'date_stock_in' => $now->format('Y-m-d H:i:s'),
            ])
            ->where(Operator::equals(['id' => $stockInId]))
            ->execute();
    }
}
