package com.fiuu.xdk.reactnative;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static org.junit.Assert.assertEquals;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE, sdk = 28)
public class TransactionResultHandlerTest {

    @Test
    public void classify_successFromStatCode() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"StatCode\":\"00\",\"TranID\":\"123\"}"
        );

        assertEquals(TransactionResultHandler.Route.SUCCESS, dispatch.route);
        assertEquals("{\"StatCode\":\"00\",\"TranID\":\"123\"}", dispatch.payload);
    }

    @Test
    public void classify_successFromStatusCode() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"status_code\":\"00\",\"txn_ID\":\"456\"}"
        );

        assertEquals(TransactionResultHandler.Route.SUCCESS, dispatch.route);
    }

    @Test
    public void classify_prefersStatCodeWhenBothPresent() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"StatCode\":\"00\",\"status_code\":\"11\"}"
        );

        assertEquals(TransactionResultHandler.Route.SUCCESS, dispatch.route);
    }

    @Test
    public void classify_pendingStatCode22RoutesToPending() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"StatCode\":\"22\",\"TranID\":\"789\"}"
        );

        assertEquals(TransactionResultHandler.Route.PENDING, dispatch.route);
        assertEquals("{\"StatCode\":\"22\",\"TranID\":\"789\"}", dispatch.payload);
    }

    @Test
    public void classify_pendingStatusCode22RoutesToPending() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"status_code\":\"22\",\"txn_ID\":\"789\"}"
        );

        assertEquals(TransactionResultHandler.Route.PENDING, dispatch.route);
    }

    @Test
    public void classify_failureStatCode11RoutesToFailure() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(
                "{\"StatCode\":\"11\",\"ErrorCode\":\"GP01\"}"
        );

        assertEquals(TransactionResultHandler.Route.FAILURE, dispatch.route);
    }

    @Test
    public void classify_malformedJsonRoutesToMalformed() {
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify("{not-json");

        assertEquals(TransactionResultHandler.Route.MALFORMED, dispatch.route);
        assertEquals(
                "Payment completed but transaction result was malformed.",
                dispatch.message
        );
    }

    @Test
    public void classify_missingStatusKeepsNativePayloadAsFailure() {
        String payload = "{\"TranID\":\"123\"}";
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(payload);

        assertEquals(TransactionResultHandler.Route.FAILURE, dispatch.route);
        assertEquals(payload, dispatch.payload);
    }

    @Test
    public void classify_closeWithoutStatusKeepsNativePayload() {
        String payload = "{\"error\":\"Transaction Cancelled\"}";
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(payload);

        assertEquals(TransactionResultHandler.Route.FAILURE, dispatch.route);
        assertEquals(payload, dispatch.payload);
    }

    @Test
    public void classify_webcoreClosePayloadKeepsNativeJson() {
        String payload =
                "{\"error_code\":\"M00008\",\"error_message\":\"Transaction not found\",\"msgType\":\"D7\"}";
        TransactionResultHandler.Dispatch dispatch = TransactionResultHandler.classify(payload);

        assertEquals(TransactionResultHandler.Route.FAILURE, dispatch.route);
        assertEquals(payload, dispatch.payload);
    }
}
