<?php
declare(strict_types=1);

namespace Autogedal\PayPo\Test\Unit\Plugin;

use Autogedal\PayPo\Model\PayPoContext;
use Autogedal\PayPo\Model\ApprovalConfig;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Autogedal\PayPo\Plugin\ApprovalStatePlugin;
use Autogedal\Extend\Model\ResourceModel\Order\Handler\State;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Payment;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

class ApprovalStatePluginTest extends TestCase
{
    public static function orders(): array
    {
        return [
            'first PayPo capture' => ['asteptare_plata_paypo', 'paypo', true, 'new', 'pending'],
            'approved order saved during callback' => ['new', 'paypo', true, 'new', 'pending'],
            'already taken' => ['pending', 'paypo', true, 'custom_awb', 'processing'],
            'AWB already issued' => ['custom_awb', 'paypo', true, 'custom_awb', 'processing'],
            'outside approval' => ['asteptare_plata_paypo', 'paypo', false, 'custom_awb', 'processing'],
            'card untouched' => ['new', 'net_card', true, 'custom_awb', 'processing'],
            'custom configured status' => ['custom_waiting', 'paypo', true, 'new', 'pending', 'custom_waiting,new'],
            'waiting removed from configuration' => ['asteptare_plata_paypo', 'paypo', true, 'custom_awb', 'processing', 'new'],
            'empty configuration' => ['new', 'paypo', true, 'custom_awb', 'processing', ''],
        ];
    }

    #[DataProvider('orders')]
    public function testSavingPaidInvoiceKeepsWarehouseState(
        string $originalStatus,
        string $method,
        bool $approving,
        string $expectedStatus,
        string $expectedState,
        string $configured = 'asteptare_plata_paypo,new'
    ): void {
        $order = $this->getMockBuilder(Order::class)->disableOriginalConstructor()
            ->onlyMethods(['getId', 'getPayment', 'canUnhold', 'canInvoice', 'canShip', 'canCreditmemo'])->getMock();
        $order->method('getId')->willReturn(248726);
        $order->setData([
            'state' => 'processing', 'status' => 'custom_awb',
            'total_paid' => 266.10, 'total_invoiced' => 266.10,
        ]);
        $order->setOrigData('status', $originalStatus);
        $payment = $this->createMock(Payment::class);
        $payment->method('getMethod')->willReturn($method);
        $order->method('getPayment')->willReturn($payment);
        $order->method('canUnhold')->willReturn(false);
        $order->method('canInvoice')->willReturn(false);
        $order->method('canShip')->willReturn(true);
        $order->method('canCreditmemo')->willReturn(true);
        $context = new PayPoContext();
        $context->setApprovingOrder($approving);
        $context->setApprovingOrderId(248726);
        $handler = new State();
        $scopeConfig = $this->createMock(ScopeConfigInterface::class);
        $scopeConfig->method('getValue')->willReturn($configured);
        $arguments = (new ApprovalStatePlugin($context, new ApprovalConfig($scopeConfig)))
            ->beforeCheck($handler, $order);
        $handler->check(...$arguments);

        self::assertSame($expectedState, $order->getState());
        self::assertSame($expectedStatus, $order->getStatus());
        self::assertSame(266.10, $order->getTotalPaid());
        self::assertSame(266.10, $order->getTotalInvoiced());
    }
}
