<?php

namespace App\Tests\A_Unit\Import\Sync\Syncer;

use Myvetshop\Module\Clinique\Import\Model\CartRuleModel;
use Myvetshop\Module\Clinique\Import\Sync\Syncer\CartRuleSyncer;
use Myvetshop\Module\Clinique\Import\Sync\SyncStatistics;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class CartRuleSyncerTest extends TestCase
{
    /**
     * @var \Db&MockObject
     */
    private \Db $db;

    /**
     * @var SyncStatistics
     */
    private SyncStatistics $syncStatistics;

    /**
     * @var \Customer&MockObject
     */
    private \Customer $customer;

    /**
     * @var CartRuleModel
     */
    private CartRuleModel $cartRuleModel;

    /**
     * @var CartRuleSyncer&MockObject
     */
    private CartRuleSyncer $syncer;

    protected function setUp(): void
    {
        $this->db = $this->getMockBuilder(\Db::class)
            ->disableOriginalConstructor()
            ->getMock();

        $this->syncStatistics = new SyncStatistics();

        $this->customer = $this->getMockBuilder(\Customer::class)
            ->disableOriginalConstructor()
            ->getMock();

        $this->cartRuleModel = new CartRuleModel();
        $this->cartRuleModel->email = 'test@test.com';
        $this->cartRuleModel->name = 'testname';
        $this->cartRuleModel->dateFrom = new \DateTimeImmutable('2024-04-01 00:00:00');
        $this->cartRuleModel->dateTo = new \DateTimeImmutable('2024-04-30 00:00:00');
        $this->cartRuleModel->description = 'testdescription';
        $this->cartRuleModel->quantity = 1;
        $this->cartRuleModel->code = 'testcode';
        $this->cartRuleModel->reductionAmount = 10.0;
        $this->cartRuleModel->active = true;
        $this->cartRuleModel->dateAdd = new \DateTimeImmutable('2024-04-01 00:00:00');

        $this->syncer = $this->getMockBuilder(CartRuleSyncer::class)
            ->setConstructorArgs([$this->db])
            ->onlyMethods(['getExistingCartRule', 'getCartRule', 'syncCartRuleRestriction'])
            ->getMock();
    }

    public function testSyncCartRuleCreation(): void
    {
        $this->syncer
            ->method('getExistingCartRule')
            ->willReturn(null);

        $this->syncer
            ->method('getCartRule')
            ->willReturn($this->createMock(\CartRule::class));

        $cartRule = $this->syncer->syncCartRule($this->syncStatistics, $this->customer, $this->cartRuleModel);

        $this->assertInstanceOf(\CartRule::class, $cartRule);
        $this->assertSame((int) $this->customer->id, $cartRule->id_customer);
        $this->assertSame($this->cartRuleModel->dateFrom->format('Y-m-d H:i:s'), $cartRule->date_from);
        $this->assertSame($this->cartRuleModel->dateTo->format('Y-m-d H:i:s'), $cartRule->date_to);
        $this->assertSame([1 => $this->cartRuleModel->name], $cartRule->name);
        $this->assertSame($this->cartRuleModel->description, $cartRule->description);
        $this->assertSame($this->cartRuleModel->quantity, $cartRule->quantity);
        $this->assertSame($this->cartRuleModel->code, $cartRule->code);
        $this->assertSame($this->cartRuleModel->reductionAmount, $cartRule->reduction_amount);
        $this->assertSame($this->cartRuleModel->active, $cartRule->active);
        $this->assertSame($this->cartRuleModel->dateAdd->format('Y-m-d H:i:s'), $cartRule->date_add);
        $this->assertSame($this->cartRuleModel->dateAdd->format('Y-m-d H:i:s'), $cartRule->date_upd);
    }

    public function testSync(): void
    {
        $syncStatistics = new SyncStatistics();

        // Prepare the mock CartRuleModels
        $cartRuleModel1 = new CartRuleModel();
        $cartRuleModel1->code = 'ALIM123';
        $cartRuleModel1->email = 'test@test.com';
        $cartRuleModel1->name = 'testname';
        $cartRuleModel1->dateFrom = new \DateTimeImmutable('2024-04-01 00:00:00');
        $cartRuleModel1->dateTo = new \DateTimeImmutable('2024-04-30 00:00:00');
        $cartRuleModel1->description = 'testdescription';
        $cartRuleModel1->quantity = 1;
        $cartRuleModel1->reductionAmount = 10.0;
        $cartRuleModel1->active = true;
        $cartRuleModel1->dateAdd = new \DateTimeImmutable('2024-04-01 00:00:00');

        $cartRuleModel2 = new CartRuleModel();
        $cartRuleModel2->code = 'OTHERCODE';
        $cartRuleModel2->email = 'test@test.com';
        $cartRuleModel2->name = 'testname';
        $cartRuleModel2->dateFrom = new \DateTimeImmutable('2024-04-01 00:00:00');
        $cartRuleModel2->dateTo = new \DateTimeImmutable('2024-04-30 00:00:00');
        $cartRuleModel2->description = 'testdescription';
        $cartRuleModel2->quantity = 1;
        $cartRuleModel2->reductionAmount = 10.0;
        $cartRuleModel2->active = true;
        $cartRuleModel2->dateAdd = new \DateTimeImmutable('2024-04-01 00:00:00');

        $result = $this->syncer->sync($this->syncStatistics, $this->customer, [$cartRuleModel1, $cartRuleModel2]);
        $this->assertArrayHasKey($cartRuleModel1->code, $result);
        $this->assertArrayNotHasKey($cartRuleModel2->code, $result);

        $this->assertSame((int) $this->customer->id, $result[$cartRuleModel1->code]->id_customer);
        $this->assertSame($cartRuleModel1->dateFrom->format('Y-m-d H:i:s'), $result[$cartRuleModel1->code]->date_from);
        $this->assertSame($cartRuleModel1->dateTo->format('Y-m-d H:i:s'), $result[$cartRuleModel1->code]->date_to);
        $this->assertSame($cartRuleModel1->description, $result[$cartRuleModel1->code]->description);
        $this->assertSame($cartRuleModel1->quantity, $result[$cartRuleModel1->code]->quantity);
        $this->assertSame($cartRuleModel1->code, $result[$cartRuleModel1->code]->code);
    }
}
