<?php

namespace Tests\Unit;

use App\Http\logic\api\PayPlusLogic;
use App\Services\PayPlus;
use Tests\TestCase;

class PayPlusLogicTest extends TestCase
{
    /** @test */
    public function it_builds_payment_payload_with_configured_method_mapping()
    {
        $service = new PayPlus([
            'currency' => 'USD',
            'return' => 'https://example.com/return',
            'payment_methods' => [
                1 => 8,
                2 => 2,
            ],
        ]);

        $logic = new PayPlusLogic($service);
        $payload = $logic->buildPaymentPayload([
            'order_sn' => 'P100',
            'amount' => 12.34,
            'user_id' => 10001,
            'user_email' => 'user@example.com',
            'user_phone' => '1234567890',
            'user_name' => 'Nico Smith',
            'buy_ip' => '8.8.8.8',
            'pay_method' => 2,
        ]);

        $this->assertSame('P100', $payload['platform_order_id']);
        $this->assertSame('RECHARGE', $payload['order_type']);
        $this->assertSame('12.34', $payload['amount']);
        $this->assertSame(2, $payload['payment_method']);
        $this->assertSame('10001', $payload['account_info']['merchant_user_id']);
        $this->assertSame('user', $payload['account_info']['first_name']);
        $this->assertSame('user', $payload['account_info']['last_name']);
    }

    /** @test */
    public function it_maps_successful_capture_only_as_paid()
    {
        $logic = new PayPlusLogic(new PayPlus([]));

        $this->assertTrue($logic->isSuccessfulPayment([
            'event' => 'PAYMENT.CAPTURE.COMPLETED',
            'event_detail_name' => 'payment_captured',
            'data' => ['order_status' => 3],
        ]));

        $this->assertFalse($logic->isSuccessfulPayment([
            'event' => 'PAYMENT.CAPTURE.COMPLETED',
            'event_detail_name' => 'payment_declined',
            'data' => ['order_status' => 4],
        ]));
    }

    /** @test */
    public function it_confirms_successful_notify_with_order_query()
    {
        $service = new FakePayPlusForPayinQuery([
            'decryptedComponentDelta' => [
                'order_status' => 3,
                'event_detail_name' => 'payment_captured',
            ],
        ]);

        $logic = new PayPlusLogic($service);

        $this->assertTrue($logic->confirmSuccessfulPayment([
            'event' => 'PAYMENT.CAPTURE.COMPLETED',
            'event_detail_name' => 'payment_captured',
            'data' => [
                'platform_order_id' => 'P100',
                'order_id' => 'O100',
                'order_status' => 3,
            ],
        ]));

        $this->assertSame('P100', $service->queriedPlatformOrderId);
        $this->assertSame('O100', $service->queriedOrderId);
    }

    /** @test */
    public function it_rejects_successful_notify_when_order_query_is_not_successful()
    {
        $service = new FakePayPlusForPayinQuery([
            'decryptedComponentDelta' => [
                'order_status' => 4,
                'event_detail_name' => 'payment_declined',
            ],
        ]);

        $logic = new PayPlusLogic($service);

        $this->assertFalse($logic->confirmSuccessfulPayment([
            'event' => 'PAYMENT.CAPTURE.COMPLETED',
            'event_detail_name' => 'payment_captured',
            'data' => [
                'platform_order_id' => 'P100',
                'order_id' => 'O100',
                'order_status' => 3,
            ],
        ]));
    }
}

class FakePayPlusForPayinQuery extends PayPlus
{
    public $queriedPlatformOrderId;
    public $queriedOrderId;

    private $queryResult;

    public function __construct(array $queryResult)
    {
        parent::__construct([]);
        $this->queryResult = $queryResult;
    }

    public function queryPayinOrder($platformOrderId, $orderId = '')
    {
        $this->queriedPlatformOrderId = $platformOrderId;
        $this->queriedOrderId = $orderId;

        return $this->queryResult;
    }
}
