<?php

declare(strict_types=1);

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Tests\Commerce\Catalog\Outbox;

use CpCreation\VitiCore\Commerce\Catalog\Configuration\CatalogHubConfiguration;
use CpCreation\VitiCore\Commerce\Catalog\Configuration\CatalogIntegrationConfiguration;
use CpCreation\VitiCore\Commerce\Catalog\Configuration\CatalogWebhookEndpointResolver;
use CpCreation\VitiCore\Commerce\Catalog\Model\CatalogChange;
use CpCreation\VitiCore\Commerce\Catalog\Model\CatalogChangeType;
use CpCreation\VitiCore\Commerce\Catalog\Outbox\Message\ReconcileCatalogStockMessage;
use CpCreation\VitiCore\Commerce\Catalog\Outbox\Message\ReconcileCatalogStockMessageHandler;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;

final class ReconcileCatalogStockMessageHandlerTest extends TestCase
{
    private const string INSTANCE_ID = '7ad9e145-910f-4de4-9cec-5f832494adef';

    public function testItCreatesAReconciliationEventWhenWebhookIsReady(): void
    {
        $entityManager = $this->createMock(EntityManagerInterface::class);
        $entityManager->expects(self::once())
            ->method('persist')
            ->with(self::callback(static fn(object $change): bool => $change instanceof CatalogChange
                && CatalogChangeType::RECONCILIATION_REQUIRED === $change->getType()));
        $entityManager->expects(self::once())->method('flush');

        $configuration = $this->configuration(enabled: true);
        (new ReconcileCatalogStockMessageHandler(
            $configuration,
            $this->webhookEndpointResolver($configuration),
            $entityManager,
        ))(new ReconcileCatalogStockMessage());
    }

    public function testItDoesNothingWhenWebhookIsNotReady(): void
    {
        $entityManager = $this->createMock(EntityManagerInterface::class);
        $entityManager->expects(self::never())->method('persist');
        $entityManager->expects(self::never())->method('flush');

        $configuration = $this->configuration(enabled: false);
        (new ReconcileCatalogStockMessageHandler(
            $configuration,
            $this->webhookEndpointResolver($configuration),
            $entityManager,
        ))(new ReconcileCatalogStockMessage());
    }

    private function configuration(bool $enabled): CatalogIntegrationConfiguration
    {
        return new CatalogIntegrationConfiguration(
            enabled: $enabled,
            instanceId: self::INSTANCE_ID,
            apiTokenHash: hash('sha256', 'central-token'),
            currency: 'EUR',
        );
    }

    private function webhookEndpointResolver(
        CatalogIntegrationConfiguration $configuration,
    ): CatalogWebhookEndpointResolver {
        return new CatalogWebhookEndpointResolver(
            $configuration,
            new CatalogHubConfiguration('', '', '', '', '', '', false),
            'https://hub.example/webhooks/catalog',
            '0123456789abcdef0123456789abcdef',
        );
    }
}
