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

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.PaymentEngineMonitoringInstanceFileRecords;
import cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_monitoring.PaymentEngineRunInstance;
import cz.moneta.test.dsl.payment_engine.tasks.PaymentEngineTasks;
import cz.moneta.test.dsl.util.DateUtils;
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.support.auth.Credentials;
import cz.moneta.test.harness.support.auth.Key;
import cz.moneta.test.dsl.payment_engine.model.FileForInputPreparation;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;

import java.io.*;
import java.util.concurrent.ThreadLocalRandom;

import static cz.moneta.test.dsl.payment_engine.enums.TransactionReasonPAE.*;
import static cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchPage.TRANSACTION_ID_KEY;
import static cz.moneta.test.dsl.payment_engine.parts_of_menu.menu_search.PaymentEngineSearchTransactionDetailLifeCycle.TRANSACTION_BY_TYPE_ID_KEY;

@TestScenarioWithOrder(name = "Ingoing foreign payment controller")
public class IngoingSepaTest extends FileForInputPreparation {

    private String SEPA_FILE;
    private PaymentData data;
    private PaymentEngineTasks tasks;

    @BeforeAll
    public void testSetUp(Harness harness) {
        data = PaymentData.builder()
                .payScheme("SEPA Credit Transfer")
                .front("Distribuce clearing: archiv")
                .debtorAcc(harness.getConfig("payments_cashless.foreignPayment.XCTacc"))
                .settlementDateFrom(DateUtils.getFormattedPreviousWorkday("dd.MM.yyyy"))
                .settlementDateTo(DateUtils.getFormattedTodayDate("dd.MM.yyyy"))
                .transactionCode("FRAD - Fraudulent Origin")
                .transactionType("SCT Recall odchozi")
                .trxReference(DateUtils.getFormattedTodayDateTime("yyyyMMddhhmmssSS"))
                .iban(harness.getConfig("payments_cashless.foreignPayment.XCT"))
                .count(ThreadLocalRandom.current().nextInt(1, 999999))
                .build();
        data.setMessageId(data.getTrxReference() + "-" + ThreadLocalRandom.current().nextInt(100, 999));
        SEPA_FILE = harness.getConfig("payments_cashless.foreignPayment.sepaFile");
    }

    @BeforeEach
    public void testSetUpUniqueData(Harness harness) {
        data.setAmount(String.valueOf(ThreadLocalRandom.current().nextInt(100, 999)));
        data.setRandom(String.valueOf(ThreadLocalRandom.current().nextInt(100000, 999999)));
        tasks = harness.tasks().paymentEngineTasks();
    }

    @JiraTestCase(id = "PAY-T2457")
    @Order(1)
    @TestCase(environments = {Environment.TST1, Environment.PPE})
    public void simulateIngoingSepa(Harness harness, @Key("payment.engine") Credentials credentials) throws IOException {
        harness.log("Random amount is: " + data.getAmount());

        PaymentEngineRunInstance instance = logInPae(harness, credentials)
                .clickMonitoringAndChooseChannelListFromChanelMonitoring()
                .clickOnInputSepa()
                .clickOnRunButton();

        String newFileName = DateUtils.getFormattedTodayDate("yyyy-MM-dd") + "_AGBA_SCF_0" + data.getCount() + "_P008.xml";
        File file = prepareFileForInput(harness, SEPA_FILE, newFileName, data);

        try {
            PaymentEngineMonitoringInstanceFileRecords records = instance.clickOnUploadFileButton()
                    .uploadFile(file.getAbsolutePath())
                    .clickSendPopupButton()
                    .clickOkPopupButton()
                    .clickOnFileTab("Soubory")
                    .waitForFileAndClickOnIt(newFileName)
                    .clickOkButton()
                    .closeTab()
                    .clickMonitoringAndChooseChannelInstanceFromChanelMonitoring()
                    .clickOnSelectStatus()
                    .selectStatusSuccess()
                    .clickOnApplyButton()
                    .waitForChannelAndClickOnRecords(newFileName)
                    .storeTransactionId();

            harness.store("reports.tmfj.execution.comment", "Transaction amount: " + data.getAmount()
                    + "\nFile name: " + newFileName
                    + "\nTransaction ID: " + harness.get(PaymentEngineMonitoringInstanceFileRecords.TRANSACTION_ID_KEY));

            records.waitForStatus(harness, ARCHIV);
        } catch (Exception e) {
            throw e;
        } finally {
            file.delete();
        }
    }

    @JiraTestCase(id = "PAY-T3629")
    @Order(2)
    @TestCase(name = "Foreign SCT Ingoing Payment Reject", environments = {Environment.TST1, Environment.PPE})
    void requestForeignSCTIngoingPaymentReject(Harness harness, @Key(Keys.paymentEngine.firstUser) Credentials user1,
                                               @Key(Keys.paymentEngine.secondUser) Credentials user2) {

        logInPae(harness, user1)
                .then(tasks.searchTransactionBySettlement(data, ARCHIV))
                .then(tasks.searchTransactionAndRequestForCancellation(harness.get(TRANSACTION_ID_KEY), data));
        harness.withPaymentEngine().closePaymentEngine();

        String transactionalId = harness.get(TRANSACTION_ID_KEY);

        logInPae(harness, user2)
                .then(tasks.verifyDistributionToClearingAndWaitForStatus(transactionalId, ARCHIV))
                .then(tasks.checkLifeCycleAndWaitForStatus(data, DISTRIBUTION))
                .storeTransactionIdByType(data.getTransactionType());
        harness.withPaymentEngine().closePaymentEngine();

        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionalId + " was successfully archived."
                + "\n" + "SCT Recall outgoing " + harness.get(TRANSACTION_BY_TYPE_ID_KEY) + " status: " + DISTRIBUTION
                + "\n" + "Debtor account: " + data.getDebtorAcc());
    }

    PaymentEngineHomePage logInPae(Harness harness, @Key("payment.engine") Credentials credentials) {
        return harness.withPaymentEngine()
                .openLoginPage()
                .login(credentials.getUsername(), credentials.getPassword())
                .clickOkButton();
    }
}
