package cz.moneta.test.regression.transactional.payments.cashless.instant_payment;

import com.google.gson.JsonObject;
import cz.moneta.test.dsl.Harness;
import cz.moneta.test.harness.annotations.Environment;
import cz.moneta.test.harness.annotations.JiraTestCase;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.annotations.TestScenario;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;

import java.math.BigDecimal;
import java.util.Random;


@TestScenario(name = "Test instant payment validations")
public class InstantPaymentValidations {

    String TOKEN_CBL;
    String TOKEN_ATM;

    @BeforeAll
    void testSetUp(Harness harness) {
        TOKEN_CBL = harness.tasks().wso2().authorization().getToken("DigitalchannelsSB_CBL");
        TOKEN_ATM = harness.tasks().wso2().authorization().getToken("ATM");
    }

    @JiraTestCase(id = "PAY-T1290")
    @TestCase(name = "Test transaction duplicity", environments = {Environment.TST1, Environment.PPE})
    void transactionDuplicityValidation(Harness harness) {
        String account = harness.getConfig("payments_cashless.instantPaymentValidations.accounts").split(",")[0];
        String creditor = harness.getConfig("payments_cashless.instantPaymentValidations.accounts").split(",")[1];
        String request = createRequestForTransaction(account, creditor, "AD");

        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/CRT_INST_PAYM/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(request)
                .post()
                .andAssertStatus(201)
                .andAssertFieldValue("rejectionReason", "");

        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/CRT_INST_PAYM/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(request)
                .post()
                .andAssertStatus(201)
                .andAssertFieldValue("rejectionReason", "AM05");
    }

    @Disabled("Not currently maintained")
    @JiraTestCase(id = "PAY-T1640")
    @TestCase(name = "Test creditor bank outage", environments = {Environment.TST1})
    void limitsCreditorBankOutage(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/GET_INST_PAYM_LIMITS/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(createRequestForLimits("123", BigDecimal.valueOf(1.99), "2000", ""))
                .post()
                .andAssertStatus(200)
                .andAssertFieldValue("notInstantReason", "BANK_OUTAGE");
    }

    @Disabled("Not currently maintained")
    @JiraTestCase(id = "PAY-T1639")
    @TestCase(name = "Test amount limit external", environments = {Environment.TST1, Environment.PPE})
    void limitsAmountLimitExternal(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/GET_INST_PAYM_LIMITS/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(createRequestForLimits("123", BigDecimal.valueOf(500000), "0100", ""))
                .post()
                .andAssertStatus(200)
                .andAssertFieldValue("notInstantReason", "LIMIT_EXCEEDED");
    }

    @Disabled("Not currently maintained")
    @JiraTestCase(id = "PAY-T1641")
    @TestCase(name = "Test amount limit internal", environments = {Environment.TST1, Environment.PPE})
    void limitsAmountLimitInternal(Harness harness) {
        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/GET_INST_PAYM_LIMITS/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(createRequestForLimits("123", BigDecimal.valueOf(500000), "0600", ""))
                .post()
                .andAssertStatus(200)
                .andAssertFieldValue("instantPaymentPossible", "true");
    }

    @Disabled("Not currently maintained")
    @JiraTestCase(id = "PAY-T1643")
    @TestCase(name = "Test account AGB format", environments = {Environment.TST1, Environment.PPE})
    void limitsAGBAccount(Harness harness) {
        String[] accountIds = harness.getConfig("payments_cashless.instantPaymentValidations.AGBAccount").split("-");
        harness.withWso2()
                .prepareRequest()
                .withPath("/t/payments.cluster/GET_INST_PAYM_LIMITS/001")
                .withHeader("Content-Type", "application/json")
                .withHeader("Accept", "application/json")
                .withHeader("Authorization", TOKEN_ATM)
                .withHeader("cache-control", "no-cache,no-cache")
                .withPayload(createRequestForLimits(accountIds[1], BigDecimal.valueOf(1000), "0600", accountIds[0]))
                .post()
                .andAssertStatus(200)
                .andAssertFieldValue("instantPaymentPossible", "true");
    }

    private String createRequestForTransaction(String debtorAccountId, String creditorAccountId, String channel) {
        JsonObject json = new JsonObject();
        Random ran = new Random();
        json.addProperty("instructionId", ran.nextInt());
        json.addProperty("debetorAccountId", debtorAccountId);
        json.addProperty("creditorAccountId", creditorAccountId);
        json.addProperty("creditorBankNumber", "0600");
        json.addProperty("amount", 1);
        json.addProperty("constantSymbol", "12");
        json.addProperty("specificSymbol", "34");
        json.addProperty("variableSymbol", "56");
        json.addProperty("AVMessage", "Automated test");
        json.addProperty("channelId", channel);
        json.addProperty("additionalPaymentTextDB1", "VKLAD ATM MONETA");
        json.addProperty("additionalPaymentTextDB2", "RADEK HRUBY");
        json.addProperty("additionalPaymentTextDB3", "S1DS2079 Křížová 9, Brno");
        json.addProperty("additionalPaymentTextCR1", "VKLAD ATM  MONETA");
        json.addProperty("additionalPaymentTextCR2", "RADEK HRUBY");
        json.addProperty("additionalPaymentTextCR3", "S1DS2079 Křížová 9, Brno");
        json.addProperty("userId", "GEMTEST");
        return json.toString();
    }

    private String createRequestForLimits(String creditorAccountId, BigDecimal amount, String creditorBankNumber, String creditorPrefix) {
        JsonObject json = new JsonObject();
        Random ran = new Random();
        json.addProperty("messageId", ran.nextInt());
        json.addProperty("debetorAccountId", 193840582);
        json.addProperty("creditorBankNumber", creditorBankNumber);
        json.addProperty("creditorAccountId", creditorAccountId);
        json.addProperty("creditorAccountIdPrefix", creditorPrefix);
        json.addProperty("amount", amount);
        return json.toString();
    }
}
