<?php

namespace Autogedal\TbiBank\Test\Unit;

use Autogedal\TbiBank\Model\ApplicationRegistry;
use Autogedal\TbiBank\Model\Environment;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Payment;
use Magento\Sales\Model\OrderFactory;
use Magento\Sales\Model\Order\Status\History;
use Magento\Sales\Model\ResourceModel\Order as OrderResource;
use PHPUnit\Framework\TestCase;

class ApplicationRegistryTest extends TestCase
{
    public function testSecondProviderApplicationIsRecordedWithoutReplacingTheFirstToken(): void
    {
        $connection = $this->createMock(AdapterInterface::class);
        $applicationSelect = $this->createMock(Select::class);
        $applicationSelect->method('from')->willReturnSelf();
        $applicationSelect->method('where')->willReturnSelf();
        $applicationSelect->expects($this->once())->method('forUpdate')->with(true)->willReturnSelf();
        $connection->expects($this->once())->method('select')->willReturn($applicationSelect);
        $connection->method('getTableName')->willReturnArgument(0);
        $connection->method('quoteIdentifier')->willReturnArgument(0);
        $connection->expects($this->once())->method('fetchCol')->willReturn([42]);
        $connection->expects($this->once())->method('fetchRow')->willReturn(['provider_order_id' => 60]);
        $connection->expects($this->once())->method('beginTransaction');
        $connection->expects($this->once())->method('commit');
        $connection->expects($this->never())->method('rollBack');
        $connection->expects($this->never())->method('insertOnDuplicate');

        $resource = $this->createMock(ResourceConnection::class);
        $resource->method('getConnection')->willReturn($connection);
        $resource->method('getTableName')->willReturnArgument(0);

        $history = $this->createPartialMock(History::class, []);
        $order = $this->createPartialMock(Order::class, ['getPayment', 'getId', 'getStoreId', 'addStatusHistoryComment']);
        $payment = $this->createPartialMock(Payment::class, []);
        $payment->setMethod('fusionpay');
        $order->method('getPayment')->willReturn($payment);
        $order->method('getId')->willReturn(42);
        $order->method('getStoreId')->willReturn(1);
        $order->expects($this->once())->method('addStatusHistoryComment')->with($this->callback(
            fn ($comment) => str_contains((string) $comment, 'Aplicatia initiala este 60')
                && str_contains((string) $comment, 'aplicatia noua este 61')
        ))->willReturn($history);

        $factory = $this->createMock(OrderFactory::class);
        $factory->expects($this->once())->method('create')->willReturn($order);
        $orderResource = $this->createMock(OrderResource::class);
        $orderResource->expects($this->once())->method('load')->with($order, 42)->willReturnSelf();
        $orderResource->expects($this->once())->method('save')->with($order);

        $environment = $this->createMock(Environment::class);
        $environment->method('getAccountFingerprint')->willReturn('fingerprint');
        $encryptor = $this->createMock(EncryptorInterface::class);
        $encryptor->expects($this->never())->method('encrypt');

        (new ApplicationRegistry($resource, $encryptor, $environment, $factory, $orderResource))
            ->save('AGD-123', 61, 'second-token');
    }
}
