package cz.moneta.test.regression.transactional.payments.cashless.payment_engine.foreign.outgoing;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.payment_engine.home.PaymentEngineHomePage;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_monitoring.PaymentEngineRunInstance;
import cz.moneta.test.dsl.util.credentials.Keys;
import cz.moneta.test.dsl.util.data.payment.PaymentData;
import cz.moneta.test.harness.annotations.*;
import cz.moneta.test.harness.endpoints.payment_engine.PaymentEngineEndpoint;
import cz.moneta.test.harness.support.auth.Credentials;
import cz.moneta.test.harness.support.auth.Key;
import org.junit.jupiter.api.*;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ThreadLocalRandom;

import static cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_monitoring.PaymentEngineRunInstance.LAST_SEQUENCE_NUMBER_KEY;
import static cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchTransactionRecordDetail.SETTLEMENT_DATE_KEY;
import static cz.moneta.test.dsl.payment_engine.enums.TransactionReasonPAE.*;

@NonConcurrentTestScenario
@TestScenarioWithOrder(name = "Create foreign payment in PAE and verify.")
public class OutgoingXctClientPaymentTest extends AbstractOutgoingXctClientPaymentTest {

    private static final String CREDITOR_BIC_AUTO = "KOMBCZPPXXX";
    private static final String CREDITOR_BIC_MAN = "CEKOCZPPXXX";
    private static final String CLEARING_PARTNER = "CERTIS-CZK";
    private static final String CORESP_PARTNER = "CNBACZPP";
    private String INTERMEDIARY_BIC;
    private static final String COVERAGE_ACCOUNT = "10110666996123/0300";
    private PaymentData data;

    @BeforeAll
    void testSetUp(Harness harness) {
        INTERMEDIARY_BIC = harness.getConfig("payments_cashless.foreignPayment.IntermediaryBIC");
        data = PaymentData.builder().distributionDate(LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy")))
                .debtorIban(harness.getConfig("payments_cashless.foreignPayment.XCT"))
                .iban(harness.getConfig("payments_cashless.foreignPayment.foreignIban"))
                .build();
    }

    @BeforeEach
    void testSetUpUniqueData() {
        data.setAmount(ThreadLocalRandom.current().nextInt(1, 10) + "," + ThreadLocalRandom.current().nextInt(1, 99));
        data.setAmount1(ThreadLocalRandom.current().nextInt(1, 299) + "," + ThreadLocalRandom.current().nextInt(1, 99));
        data.setRandom(String.valueOf(ThreadLocalRandom.current().nextInt(1, 5)));
    }

    @JiraTestCase(id = "PAY-T2464")
    @Order(1)
    @TestCase(name = "Create foreign payment", environments = {Environment.TST1, Environment.PPE})
    void createForeignPaymentXct(Harness harness, @Key(Keys.paymentEngine.firstUser) Credentials credentials) {
        setTransactionData("8765434567890",
                "",
                "Harrness automated test XCT Client Payment",
                "USD - US Dollar",
                "Barack Obama",
                "IRVTUS3N", "Bank of New York Mellon"
        );
        createForeignPayment(harness, credentials, data);
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully created."
                + "\n" + "Amount: " + data.getAmount()
                + "\n" + "Debtor IBAN: " + data.getDebtorIban()
                + "\n" + "Creditor Account: 8765434567890");
    }

    @JiraTestCase(id = "PAY-T2465")
    @Order(2)
    @TestCase(name = "Verify foreign payment", environments = {Environment.TST1, Environment.PPE})
    void verifyForeignPaymentXct(Harness harness, @Key(Keys.paymentEngine.secondUser) Credentials credentials) {
        verifyForeignPaymentAndClosePAE(harness, credentials);
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified."
                + "\n" + "Amount: " + data.getAmount()
                + "\n" + "Debtor IBAN: " + data.getDebtorIban()
                + "\n" + "Creditor Account: 8765434567890");
    }

    @JiraTestCase(id = "PAY-T2420")
    @Order(3)
    @TestCase(name = "Test Xct with automatic tracing", environments = {Environment.TST1, Environment.PPE})
    void outgoingXctAutomaticTracing(Harness harness, @Key(Keys.paymentEngine.firstUser) Credentials user1,
                                       @Key(Keys.paymentEngine.secondUser) Credentials user2) {
        assumption_BicExistence(harness, user1, "BYLADEMMXXX", true);

        setTransactionData("",
                "DE63702501500029263621",
                "Harness CZK automaticke trasovani",
                "CZK - Czech Koruna",
                "ANGELA MERKEL",
                "",
                ""
        );

        //create transaction
        createForeignPayment(harness, user1, data);
        harness.closeEndpoint(harness.getEndpoint(PaymentEngineEndpoint.class));

        //verify transaction by user2
        verifyForeignPaymentAndClosePAE(harness, user2);

        //run distribution and check result with user1
        logInPae(harness, user1)
                .clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterXCTDistribution()
                .clickOnRunButton()
                .clickOnOk()
                .closeErrorPopUpIfVisibleXCT()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, ARCHIV)
                .clickOnTransactionDetail()
                .clickOnRecordDetail()
                .checkXctRecordDetailElements(CREDITOR_BIC_AUTO, CORESP_PARTNER, CREDITOR_BIC_AUTO, INTERMEDIARY_BIC)
                .clickExitFromRecordDetail()
                .clickOnLifeCycle()
                .clickOnHD21()
                .clickOnHD21Detail()
                .clickOnRecordDetail()
                .checkDistributionDate(data.getDistributionDate())
                .storeSettlementDate();

        Assertions.assertTrue(LocalDate.now().isBefore(LocalDate.parse(harness.get(SETTLEMENT_DATE_KEY), DateTimeFormatter.ofPattern("dd.MM.yyyy"))));

        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully created."
                + "\n" + "Amount: " + data.getAmount()
                + "\n" + "Debtor IBAN: " + data.getDebtorIban()
                + "\n" + "Creditor IBAN: DE63702501500029263621"
                + "\n" + "Settlement date: " + harness.get(SETTLEMENT_DATE_KEY));
    }

    @JiraTestCase(id = "PAY-T2421")
    @Order(4)
    @TestCase(name = "Test Xct with manual tracing", environments = {Environment.TST1, Environment.PPE})
    void outgoingXctManualTracing(Harness harness, @Key(Keys.paymentEngine.firstUser) Credentials user1,
                                    @Key(Keys.paymentEngine.secondUser) Credentials user2) {

        assumption_BicExistence(harness, user1, "DABAFIHHXXX", false);

        setTransactionData("",
                "FI8280002618079049",
                "Harness CZK manualni trasovani",
                "CZK - Czech Koruna",
                "JO NESBO",
                "",
                ""
        );

        //create transaction
        createForeignPayment(harness, user1, data);
        harness.closeEndpoint(harness.getEndpoint(PaymentEngineEndpoint.class));

        //verify transaction by user2 and edit it
        verifyTransactionAndWaitForStatus(harness, user2, IRREDUCIBLE)
                .closeTab()
                .clickTransactionAndChooseManualFromOutgoing()
                .clickOnFilterButton()
                .fillTransactionId(transactionId)
                .clickOnSearchButtonAndWaitForResult(transactionId)
                .clickOnManualActions()
                .clickOnEditAndRelease()
                .fillAdditionalData(CREDITOR_BIC_MAN, COVERAGE_ACCOUNT, CREDITOR_BIC_MAN)
                .clickOnClearingPartnerList()
                .selectClearingPartner(CLEARING_PARTNER)
                .clickOnOKButton();

        harness.closeEndpoint(harness.getEndpoint(PaymentEngineEndpoint.class));

        //verify transaction and check HD21
        logInPae(harness, user1)
                .clickTransactionAndChooseForVerificationFromOutgoing()
                .pressSearch()
                .fillId(transactionId)
                .searchUnverified()
                .selectTransaction(transactionId)
                .clickOnVerifyTransaction()
                .clickOnAccept()
                .clickOnOk()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, DISTRIBUTION)
                .closeTab()
                .clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterXCTDistribution()
                .clickOnRunButton()
                .clickOnOk()
                .closeErrorPopUpIfVisibleXCT()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, ARCHIV)
                .clickOnTransactionDetail()
                .clickOnLifeCycle()
                .clickOnHD21()
                .clickOnHD21Detail()
                .clickOnRecordDetail()
                .checkDistributionDate(data.getDistributionDate())
                .storeSettlementDate();

        Assertions.assertTrue(LocalDate.now().isBefore(LocalDate.parse(harness.get(SETTLEMENT_DATE_KEY), DateTimeFormatter.ofPattern("dd.MM.yyyy"))));

        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully created."
                + "\n" + "Amount: " + data.getAmount()
                + "\n" + "Debtor IBAN: " + data.getDebtorIban()
                + "\n" + "Creditor IBAN: FI8280002618079049"
                + "\n" + "Settlement date: " + harness.get(SETTLEMENT_DATE_KEY));
    }

    @Disabled
    @JiraTestCase(id = "PAY-T2489")
    @Order(5)
    @TestCase(name = "Test Xct with incoming MT101", environments = {Environment.TST1, Environment.PPE})
    void outgoingXctBasedOnIncomingMT101(Harness harness, @Key(Keys.paymentEngine.firstUser) Credentials credentials) throws IOException {

        setTransactionData("", harness.getConfig("payments_cashless.foreignPayment.MT101"), "", "", "", "", "");

        PaymentEngineRunInstance getId = logInPae(harness, credentials)
                .clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputMT101()
                .clickOnRunButton()
                .storeLastNumberInSequence(harness);

        lastField = Integer.valueOf(harness.get(LAST_SEQUENCE_NUMBER_KEY));
        createMT101TemFile(harness, data);

        PaymentEngineHomePage homePage;
        try {
            homePage = getId.clickOnUploadFileButton()
                    .uploadFile(file.getAbsolutePath())
                    .clickSendPopupButton()
                    .clickOkPopupButton()
                    .clickOnFileTab("Soubory")
                    .waitForFileAndClickOnIt(file.getName())
                    .clickOkButton()
                    .closeTab();
            file.delete();
        } catch (Exception e) {
            throw e;
        } finally {
            file.delete();
        }

        homePage = homePage.clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                .clickOnSelectStatus()
                .selectStatusSuccess()
                .clickOnApplyButton()
                .waitForChannelAndClickOnRecords(file.getName())
                .storeTransactionId()
                .waitForStatus(harness, DISTRIBUTION)
                .closeTab();
        transactionId = harness.get("TRANSACTION_ID");
        harness.closeEndpoint(harness.getEndpoint(PaymentEngineEndpoint.class));

        logInPae(harness, credentials).clickMonitoringAndChooseProcessListFromProcessMonitoring()
                .enterXCTDistribution()
                .clickOnRunButton()
                .clickOnOk()
                .closeErrorPopUpIfVisibleXCT()
                .closeTab()
                .search()
                .typeId(transactionId)
                .clickSearch()
                .waitForStatus(harness, ARCHIV)
                .clickOnTransactionDetail()
                .clickOnLifeCycle()
                .clickOnHD21()
                .clickOnHD21Detail()
                .clickOnRecordDetail()
                .storeSettlementDate();

        Assertions.assertEquals(data.getDistributionDate(), harness.get(SETTLEMENT_DATE_KEY));
        harness.store("reports.tmfj.execution.comment", "Transaction id is " + transactionId
                + "\n" + "Settlement date: " + harness.get(SETTLEMENT_DATE_KEY));
    }

}