package cz.moneta.test.dsl.payment_engine.utils;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.payment_engine.enums.AccountStates;
import cz.moneta.test.dsl.payment_engine.enums.CurrencyPAE;
import cz.moneta.test.dsl.payment_engine.enums.TransactionReasonPAE;
import cz.moneta.test.dsl.util.data.payment.PaymentData;
import cz.moneta.test.harness.endpoints.payment_engine.PaymentEngineEndpoint;
import cz.moneta.test.harness.support.web.Lookup;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

public class PaymentEngineUtils {

    public static final int STATUS_WAIT_TIMEOUT_SEC = 300;
    public static final int STATUS_WAIT_LONG_TIMEOUT_SEC = 900;

    public static void waitForElementPresence(Harness harness, String elementXpath, String refreshButtonXpath) {
        PaymentEngineEndpoint endpoint = harness.getEndpoint(PaymentEngineEndpoint.class);
        endpoint.waitForElementAndRefresh(elementXpath, refreshButtonXpath, STATUS_WAIT_TIMEOUT_SEC, 10);
    }

    public static void storeElementAttribute(Harness harness, String xpath, String key) {
        PaymentEngineEndpoint endpoint = harness.getEndpoint(PaymentEngineEndpoint.class);
        String value = endpoint.getAttribute(xpath, Lookup.XPATH, "value");
        harness.store(key, value);
    }

    public static BufferedReader getFileByFilePath(String filePath) {
        return new BufferedReader(new InputStreamReader(getFileFromResourceAsStream(filePath)));
    }

    public static String getTransactionalId(Harness harness) {
        return StringUtils.substringBetween(harness.get("TRANSACTION_ID_KEY"), "ID ", ".");
    }

    public static File createFile(String fileName) {
        return new File(fileName);
    }

    private static InputStream getFileFromResourceAsStream(String fileName) {
        ClassLoader classLoader = PaymentEngineUtils.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream(fileName);
        if (inputStream == null) {
            throw new IllegalArgumentException("file not found! " + fileName);
        } else {
            return inputStream;
        }
    }

    public static void logResultShort(Harness harness, String transactionId, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified"
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK");
    }

    public static void logHD32Result(Harness harness, String transactionId1, String transactionId2, PaymentData data, TransactionReasonPAE status1,TransactionReasonPAE status2) {
        harness.log("HD:32 transaction " + transactionId1 + " reason: " + status1.getStatus());
        harness.store("reports.tmfj.execution.comment", "HD:32 transaction " + transactionId1 + " reason: " + status1.getStatus()
                + "\n"
                + "HD:12 transaction " + transactionId2 + " reason: " + status2.getStatus()
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK");
    }

    public static void logResultShortWithICBS(Harness harness, String transactionId, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified."
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK"
                + "\n"
                + "Transaction " + transactionId + " was successfully booked in ICBS.");
    }
    public static void logResultUfoWithPaeAndICBS(Harness harness, String transactionId, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully created in UFO Banka."
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK"
                + "\n"
                + "Transaction " + transactionId + " was successfully booked in PAE and ICBS.");
    }

    public static void logResultShortWithFileName(Harness harness, String transactionId, String fileName, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified."
                + "\n"
                + "File name: " + fileName
                + "\n"
                + "Channel name: " + data.getCreditorName()
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK");
    }

    public static void logResultShortWithAccountStateChange(Harness harness, AccountStates accountState, AccountStates accountStateNew,
                                                            String transactionId, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Account status has been changed from " + accountState.getState() + " to " + accountStateNew.getState() + " ."
                + "\n"
                + "Transaction " + transactionId + " was successfully verified."
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc() + "/" + data.getBankCode()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK"
                + "\n"
                + "Account status has been changed from " + accountStateNew.getState() + " back to " + accountState.getState() + " .");
    }

    public static void logResultShortWithPrefix(Harness harness, String transactionId, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified"
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getAccPrefix() + "-" + data.getCreditorAcc()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK");
    }

    public static void logResultLong(Harness harness, String transactionId,
                                     String transactionId2, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified"
                + "\n" +
                "Debtor account: " + data.getCreditorAcc()
                + "\n" +
                "Creditor account: " + data.getDebtorAcc()
                + "\n" +
                "Amount: " + data.getAmount() + " CZK"
                + "\n" +
                "Transaction " + transactionId2 + " was successfully verified"
                + "\n" +
                "Debtor account: " + data.getDebtorAcc()
                + "\n" +
                "Creditor account: " + data.getCreditorAcc()
                + "\n" +
                "Amount: " + data.getAmount() + " CZK");
    }

    public static void logResultLongWithICBS(Harness harness, String transactionId, String transactionId2, PaymentData data) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified" + "\n"
                + "\n" +
                "Debtor account: " + data.getCreditorAcc()
                + "\n" +
                "Creditor account: " + data.getDebtorAcc()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK"
                + "\n"
                + "Transaction " + transactionId2 + " was successfully verified"
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n" +
                "Creditor account: " + data.getCreditorAcc()
                + "\n"
                + "Amount: " + data.getAmount() + " CZK"
                + "\n"
                + "Transaction " + transactionId + " was successfully booked in ICBS."
                + "\n"
                + "Transaction " + transactionId2 + " was successfully booked in ICBS.");
    }

    public static void logStandingOrderStatus(Harness harness, String rootId1, String rootId2, String rootId3, PaymentData data) {
        harness.log("Standing Order " + rootId1 + " was successfully verified, archived and deleted.");
        harness.store("reports.tmfj.execution.comment", "Standing Order " + rootId3 + " was successfully deleted"
                + "\n" +
                "Standing Order " + rootId1 + " was successfully archived"
                + "\n" +
                "Standing Order " + rootId2 + " was successfully archived"
                + "\n" +
                "Debtor account:  " + data.getDebtorAcc()
                + "\n" +
                "Creditor account:  " + data.getCreditorAcc()
                + "\n" +
                "Amount:  " + data.getAmount() + " CZK"
                + "\n" +
                "Changed amount:  " + data.getAmount() + ",01 CZK");
    }

    public static void logStandingOrderTransactionStatus(Harness harness, String rootId1, String transactionId, PaymentData data) {
        harness.log("Standing Order " + rootId1 + " status is valid.");
        harness.store("reports.tmfj.execution.comment", "Standing Order " + rootId1 + " status is valid."
                + "\n" +
                "Debtor account:  " + data.getDebtorAcc()
                + "\n" +
                "Creditor account:  " + data.getCreditorAcc()
                + "\n" +
                "Amount:  " + data.getAmount() + " CZK"
                + "\n" +
                "Transaction " + transactionId + " was successfully archived");
    }

    public static void logAuthorizationForDirectDebitStatus(Harness harness, String rootId1, String rootId2, String rootId3, PaymentData data) {
        harness.log("Authorization For Direct Debit " + rootId1 + " was successfully verified, archived and deleted.");
        harness.store("reports.tmfj.execution.comment", "Authorization For Direct Debit " + rootId3 + " was successfully deleted"
                + "\n" +
                "Authorization For Direct Debit " + rootId1 + " was successfully archived"
                + "\n" +
                "Authorization For Direct Debit " + rootId2 + " was successfully archived"
                + "\n" +
                "Debtor account:  " + data.getDebtorAcc()
                + "\n" +
                "Creditor account:  " + data.getCreditorAcc()
                + "\n" +
                "Period max amount:  " + data.getAmount() + " CZK"
                + "\n" +
                "Changed period max amount:  " + data.getAmount() + ",01 CZK");
    }

    public static void logChangeOfClientName(Harness harness, String clientName1, String clientName2, String clientId) {
        harness.log("Client name " + clientName1 + " was successfully changed to " + clientName2 + ". ");
        harness.store("reports.tmfj.execution.comment",
                "Client name " + clientName1 + " was successfully changed to " + clientName2 + ". "
                        + "\n" +
                        "Client ID:  " + clientId
                        + "\n");
    }

    public static void logChangeOfClientAccountState(Harness harness, String clientsAccount, AccountStates accountState1, AccountStates accountState2) {
        harness.log("State of client account " + clientsAccount + " was successfully changed. ");
        harness.store("reports.tmfj.execution.comment",
                "State of client account " + clientsAccount + " was successfully changed. "
                        + "\n" +
                        "Client account state " + accountState1.getState() + " was successfully changed to " + accountState2.getState() + " and back. "
                        + "\n");
    }

    public static void logChangeOfClientAccountBranchCode(Harness harness, String clientsAccount, String branchCode1, String branchCode2) {
        harness.log("State of client account " + clientsAccount + " was successfully changed. ");
        harness.store("reports.tmfj.execution.comment",
                "Branch code of client account " + clientsAccount + " was successfully changed. "
                        + "\n" +
                        "Client account branch code " + branchCode1 + " was successfully changed to " + branchCode2 + " and back. "
                        + "\n");
    }

    public static void logResultOfInput(Harness harness, String fileName, String transactionId, String amount, String currency) {
        harness.log("The file " + fileName + " was successfully processed. ");
        harness.store("reports.tmfj.execution.comment", "The file " + fileName + " was successfully processed. "
                + "\n" +
                "Transaction ID: " + transactionId
                + "\n" +
                "Amount: " + amount + " " + currency
                + "\n");
    }

    public static void logResultOfInputWithEquivalentAmount(Harness harness, String fileName, String transactionId, String amount,
                                                            CurrencyPAE currency, String equivalentAmount, CurrencyPAE equivalentCurrency) {
        harness.log("The file " + fileName + " was successfully processed. ");
        harness.store("reports.tmfj.execution.comment", "The file " + fileName + " was successfully processed. "
                + "\n" +
                "Transaction ID: " + transactionId
                + "\n" +
                "Amount: " + amount + " " + currency.getCurrency()
                + "\n"
                + "Equivalent amount: " + equivalentAmount + " " + equivalentCurrency.getCurrency()
                + "\n"
                + "Transaction " + transactionId + " was successfully booked in ICBS.");
    }

    public static void logResultOfInputLong(Harness harness, String fileName, String transactionId1, String amount1,
                                            String transactionId2, String transactionId3, String amount2, CurrencyPAE currency) {
        harness.log("The file " + fileName + " was successfully processed. ");
        harness.store("reports.tmfj.execution.comment", "The file " + fileName + " was successfully processed. "
                + "\n" +
                "Outgoing HD:11 transaction ID: " + transactionId1
                + "\n" +
                "Amount: " + amount1 + " " + currency.getCurrency()
                + "\n" +
                "Ingoing HD:11 transaction ID: " + transactionId3
                + "\n" +
                "Amount: " + amount1 + " " + currency.getCurrency()
                + "\n" +
                "Outgoing from MC transaction ID: " + transactionId2
                + "\n" +
                "Amount: " + amount2 + " " + currency.getCurrency()
                + "\n"
                + "Transaction " + transactionId1 + " was successfully booked in ICBS."
                + "\n"
                + "Transaction " + transactionId2 + " was successfully booked in ICBS."
                + "\n"
                + "Transaction " + transactionId3 + " was successfully booked in ICBS.");
    }

    public static void logResultWithEquivalentAmount(Harness harness, String transactionId, String debtorAcc, String creditorAcc,
                                                     String amount, String equivalentAmount) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully verified"
                + "\n"
                + "Debtor account: " + debtorAcc
                + "\n"
                + "Creditor account: " + creditorAcc
                + "\n"
                + "Amount: " + amount
                + "\n"
                + "Equivalent amount: " + equivalentAmount
                + "\n"
                + "Transaction " + transactionId + " was successfully booked in ICBS.");
    }

    public static void logResultWithFeeAmount(Harness harness, String transactionId, String transactionId2, String transactionId3, String debtorAcc,
                                              String amount, String feeAmount) {
        harness.log("Transaction (xCT MT103 prichozi) " + transactionId + " was successfully archived.");
        harness.store("reports.tmfj.execution.comment", "Transaction (xCT MT103 prichozi) " + transactionId + " was successfully archived."
                + "\n"
                + "Transaction (CZ Kryti prichozi) " + transactionId2 + " was successfully archived."
                + "\n"
                + "Client's fee transaction " + transactionId3 + " was successfully archived."
                + "\n"
                + "Debtor account: " + debtorAcc
                + "\n"
                + "Amount: " + amount
                + "\n"
                + "Client's fee amount: " + feeAmount
                + "\n"
                + "Transaction (xCT MT103 prichozi) " + transactionId + " was succesfully booked in ICBS."
                + "\n"
                + "Client's fee transaction " + transactionId3 + " was succesfully booked in ICBS.");
    }

    public static void logResultOfMt103WithCreditStatementHd21(Harness harness, String transactionId, String transactionId2, String transactionId3, String debtorAcc,
                                                               String amount, String mt191Amount) {
        harness.log("Transaction (xCT MT103 prichozi) " + transactionId + " was successfully archived.");
        harness.store("reports.tmfj.execution.comment", "Transaction (xCT MT103 prichozi) " + transactionId + " was successfully archived."
                + "\n"
                + "Transaction (xCT MTx91 odchozi) " + transactionId2 + " was successfully archived."
                + "\n"
                + "Transaction (CZ Kreditni vyloha prichozi) " + transactionId3 + " was successfully archived."
                + "\n"
                + "Debtor account: " + debtorAcc
                + "\n"
                + "Amount: " + amount
                + "\n"
                + "MTx91 amount: " + mt191Amount
                + "\n"
                + "Transaction (xCT MT103 prichozi) " + transactionId + " was succesfully booked in ICBS.");
    }

    public static void logResultOfRequestForDirectDebitReturn(Harness harness, String transactionId1, String transactionId2, String transactionId3,
                                                              String transactionId4, String transactionId5, String transactionId6, PaymentData data) {
        harness.log("Transaction (HD:11 odchozi) " + transactionId1 + " was successfully archived.");
        harness.store("reports.tmfj.execution.comment", "Transaction (HD:11 odchozi) " + transactionId1 + " was successfully archived."
                + "\n" +
                "Transaction (HD:11 Inicialni prichozi) " + transactionId2 + " was successfully archived."
                + "\n"
                + "Transaction (HD:33 odchozi) " + transactionId3 + " was successfully accepted Return FOCR."
                + "\n"
                + "Transaction (HD:33 prichozi) " + transactionId4 + " successfully sent a response (RIS)."
                + "\n"
                + "Transaction (HD:13 odchozi) " + transactionId5 + " was successfully archived."
                + "\n"
                + "Transaction (HD:13 Storno prichozi) " + transactionId6 + " was successfully archived."
                + "\n"
                + "Debtor account: " + data.getDebtorAcc()
                + "\n"
                + "Creditor account: " + data.getCreditorAcc()
                + "\n"
                + "Amount: " + data.getAmount()
                + "\n"
                + "Transaction (HD:11 odchozi) " + transactionId1 + " was succesfully booked in ICBS."
                + "\n"
                + "Transaction (HD:13 Storno prichozi) " + transactionId6 + " was succesfully booked in ICBS.");
    }

    public static void logResultOfReturn(Harness harness, String transactionId, String returnedTransactionId,
                                                    String debtorAcc, String returnedAmount, String equivalentAmount) {
        harness.log("Transaction " + transactionId + " was successfully verified");
        harness.store("reports.tmfj.execution.comment", "Transaction " + transactionId + " was successfully returned."
                + "\n"
                + "Debtor account: " + debtorAcc
                + "\n"
                + "Returned amount: " + returnedAmount + " USD."
                + "\n"
                + "Equivalent amount: " + equivalentAmount + " CZK."
                + "\n"
                + "Transaction " + returnedTransactionId + " was successfully booked in ICBS.");
    }
}
