/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.fineract.integrationtests;

import static org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder.DEFAULT_STRATEGY;
import static org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY;
import static org.junit.jupiter.api.Assertions.assertEquals;

import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PaymentAllocationOrder;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.accounting.JournalEntry;
import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Named;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

@SuppressWarnings({ "rawtypes", "unchecked" })
@ExtendWith(LoanTestLifecycleExtension.class)
@Slf4j
public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest {

    private ResponseSpecification responseSpec;
    private ResponseSpecification responseSpec403;
    private RequestSpecification requestSpec;
    private LoanTransactionHelper loanTransactionHelper;
    private LoanTransactionHelper loanTransactionHelperValidationError;
    private JournalEntryHelper journalEntryHelper;
    private AccountHelper accountHelper;
    private Integer disbursedLoanID;
    private static final String CASH_BASED = "2";
    private static final String ACCRUAL_PERIODIC = "3";
    private Account assetAccount;
    private Account incomeAccount;
    private Account expenseAccount;
    private Account overpaymentAccount;
    private static final String REPAYMENT = "repayment";
    private static final String MERCHANT_ISSUED_REFUND = "merchantIssuedRefund";
    private static final String PAYOUT_REFUND = "payoutRefund";
    private static final String GOODWILL_CREDIT = "goodwillCredit";

    @BeforeEach
    public void setup() {
        Utils.initializeRESTAssured();
        this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
        this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
        this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
        this.responseSpec403 = new ResponseSpecBuilder().expectStatusCode(403).build();
        this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
        this.loanTransactionHelperValidationError = new LoanTransactionHelper(this.requestSpec, new ResponseSpecBuilder().build());
        this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
        this.assetAccount = this.accountHelper.createAssetAccount();
        this.incomeAccount = this.accountHelper.createIncomeAccount();
        this.expenseAccount = this.accountHelper.createExpenseAccount();
        this.overpaymentAccount = this.accountHelper.createLiabilityAccount();
        this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec);
    }

    private void disburseLoanOfAccountingRule(final String accountingType, LoanProductTestBuilder loanProductTestBuilder) {
        final String principal = "12000.00";
        final String submitApproveDisburseDate = "01 January 2022";
        this.disbursedLoanID = fromStartToDisburseLoan(loanProductTestBuilder, submitApproveDisburseDate, principal, accountingType,
                assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
    }

    private Integer createLoanProduct(LoanProductTestBuilder loanProductTestBuilder, final String principal,
            final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) {
        log.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
        loanProductTestBuilder = loanProductTestBuilder //
                .withPrincipal(principal) //
                .withShortName(Utils.uniqueRandomStringGenerator("", 4)) //
                .withNumberOfRepayments("4") //
                .withRepaymentAfterEvery("1") //
                .withRepaymentTypeAsMonth() //
                .withinterestRatePerPeriod("1") //
                .withInterestRateFrequencyTypeAsMonths() //
                .withAmortizationTypeAsEqualInstallments() //
                .withInterestTypeAsDecliningBalance() //
                .withAccounting(accountingRule, accounts) //
                .withTranches(multiDisburseLoan);
        if (multiDisburseLoan) {
            loanProductTestBuilder = loanProductTestBuilder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true);
            loanProductTestBuilder = loanProductTestBuilder.withMaxTrancheCount("30");
        }
        final String loanProductJSON = loanProductTestBuilder.build(null);
        return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
    }

    private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, String principal, String submitDate) {
        log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
        final String loanApplicationJSON = new LoanApplicationTestBuilder() //
                .withPrincipal(principal) //
                .withLoanTermFrequency("4") //
                .withLoanTermFrequencyAsMonths() //
                .withNumberOfRepayments("4") //
                .withRepaymentEveryAfter("1") //
                .withRepaymentFrequencyTypeAsMonths() //
                .withInterestRatePerPeriod("2") //
                .withAmortizationTypeAsEqualInstallments() //
                .withInterestTypeAsDecliningBalance() //
                .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
                .withExpectedDisbursementDate(submitDate) //
                .withSubmittedOnDate(submitDate) //
                .build(clientID.toString(), loanProductID.toString(), null);
        return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
    }

    private Integer fromStartToDisburseLoan(LoanProductTestBuilder loanProductTestBuilder, String submitApproveDisburseDate,
            String principal, final String accountingRule, final Account... accounts) {

        final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);

        boolean allowMultipleDisbursals = false;
        final Integer loanProductID = createLoanProduct(loanProductTestBuilder, principal, allowMultipleDisbursals, accountingRule,
                accounts);
        Assertions.assertNotNull(loanProductID);

        final Integer loanID = applyForLoanApplication(clientID, loanProductID, principal, submitApproveDisburseDate);
        Assertions.assertNotNull(loanID);
        HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
        LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);

        log.info("-----------------------------------APPROVE LOAN-----------------------------------------");
        loanStatusHashMap = this.loanTransactionHelper.approveLoan(submitApproveDisburseDate, loanID);
        LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
        LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);

        log.info("-------------------------------DISBURSE LOAN -------------------------------------------"); //
        // String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID);
        loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitApproveDisburseDate, loanID, principal);
        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
        return loanID;
    }

    private HashMap makeRepayment(final String repaymentDate, final Float repayment) {
        log.info("-------------Make repayment -----------");
        this.loanTransactionHelper.makeRepayment(repaymentDate, repayment, disbursedLoanID);
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
                "status");
        return loanStatusHashMap;
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void creditBalanceRefundCanOnlyBeAppliedWhereLoanStatusIsOverpaidTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 2000.00f); // not full payment
        LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);

        final String creditBalanceRefundDate = "09 January 2022";
        final Float refund = 1000.00f;
        final String externalId = null;
        ArrayList<HashMap> cbrErrors = (ArrayList<HashMap>) loanTransactionHelperValidationError
                .creditBalanceRefund(creditBalanceRefundDate, refund, externalId, disbursedLoanID, CommonConstants.RESPONSE_ERROR);

        assertEquals("error.msg.loan.credit.balance.refund.account.is.not.overpaid",
                cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void cantRefundMoreThanOverpaidTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final String creditBalanceRefundDate = "09 January 2022";
        Float refund = 10000.00f;
        final String externalId = null;
        ArrayList<HashMap> cbrErrors = (ArrayList<HashMap>) loanTransactionHelperValidationError
                .creditBalanceRefund(creditBalanceRefundDate, refund, externalId, disbursedLoanID, CommonConstants.RESPONSE_ERROR);

        assertEquals("error.msg.transactionAmount.invalid.must.be.>zero.and<=overpaidamount",
                cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));

        refund = (float) -1.00;
        cbrErrors = (ArrayList<HashMap>) loanTransactionHelperValidationError.creditBalanceRefund(creditBalanceRefundDate, refund,
                externalId, disbursedLoanID, CommonConstants.RESPONSE_ERROR);
        assertEquals("validation.msg.loan.transaction.transactionAmount.not.greater.than.zero",
                cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void fullRefundChangesStatusToClosedObligationMetTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float totalOverpaid = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
                "totalOverpaid");

        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = null;
        loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, totalOverpaid, externalId, disbursedLoanID, null);
        loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
                "status");
        LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);

        final Float floatZero = 0.0f;
        Float totalOverpaidAtEnd = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
                "totalOverpaid");
        if (totalOverpaidAtEnd == null) {
            totalOverpaidAtEnd = floatZero;
        }
        assertEquals(totalOverpaidAtEnd, floatZero);

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void partialRefundKeepsOverpaidStatusTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float refund = 5000.00f; // partial refund

        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = null;
        loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId, disbursedLoanID, null);
        loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
                "status");
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newCreditBalanceRefundSavesExternalIdTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float refund = 1000.00f; // partial refund
        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = "cbrextID" + disbursedLoanID.toString();
        Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId,
                disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);

        HashMap creditBalanceRefundMap = (HashMap) this.loanTransactionHelper.getLoanTransactionDetails(disbursedLoanID, resourceId, "");
        Assertions.assertNotNull(creditBalanceRefundMap.get("externalId"));
        Assertions.assertEquals(creditBalanceRefundMap.get("externalId"), externalId, "Incorrect External Id Saved");

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newCreditBalanceRefundFindsDuplicateExternalIdTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float refund = 1000.00f; // partial refund
        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = "cbrextID" + disbursedLoanID.toString();
        final Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId,
                disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);

        final Float refund2 = 10.00f; // partial refund
        final String creditBalanceRefundDate2 = "10 January 2022";
        ArrayList<HashMap> cbrErrors = (ArrayList<HashMap>) loanTransactionHelperValidationError
                .creditBalanceRefund(creditBalanceRefundDate2, refund2, externalId, disbursedLoanID, CommonConstants.RESPONSE_ERROR);
        assertEquals("error.msg.loan.creditBalanceRefund.duplicate.externalId",
                cbrErrors.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newCreditBalanceRefundCreatesCorrectJournalEntriesForPeriodicAccrualsTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float refund = 1000.00f; // partial refund
        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = null;
        final Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId,
                disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);

        this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, creditBalanceRefundDate,
                new JournalEntry(refund, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, creditBalanceRefundDate,
                new JournalEntry(refund, JournalEntry.TransactionType.DEBIT));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newCreditBalanceRefundCreatesCorrectJournalEntriesForCashAccountingTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanStatusHashMap = makeRepayment("08 January 2022", 20000.00f); // overpayment
        LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);

        final Float refund = 1000.00f; // partial refund
        final String creditBalanceRefundDate = "09 January 2022";
        final String externalId = null;
        final Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, refund, externalId,
                disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);

        this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, creditBalanceRefundDate,
                new JournalEntry(refund, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, creditBalanceRefundDate,
                new JournalEntry(refund, JournalEntry.TransactionType.DEBIT));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void repaymentTransactionTypeMatchesTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        verifyRepaymentTransactionTypeMatches(MERCHANT_ISSUED_REFUND);
        verifyRepaymentTransactionTypeMatches(PAYOUT_REFUND);
        verifyRepaymentTransactionTypeMatches(GOODWILL_CREDIT);

    }

    private void verifyRepaymentTransactionTypeMatches(final String repaymentTransactionType) {
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(repaymentTransactionType,
                "06 January 2022", 200.00f, this.disbursedLoanID, "");
        Integer newTransactionId = (Integer) loanStatusHashMap.get("resourceId");
        loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanTransactionDetails(this.disbursedLoanID, newTransactionId, "");

        HashMap typeMap = (HashMap) loanStatusHashMap.get("type");
        Boolean isTypeCorrect = (Boolean) typeMap.get(repaymentTransactionType);
        Assertions.assertTrue(Boolean.TRUE.equals(isTypeCorrect), "Not " + repaymentTransactionType);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void repaymentTransactionTypeWhenPaidTest(LoanProductTestBuilder loanProductTestBuilder) {
        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        verifyRepaymentTransactionTypeWhenPaid(MERCHANT_ISSUED_REFUND);
        verifyRepaymentTransactionTypeWhenPaid(PAYOUT_REFUND);
        verifyRepaymentTransactionTypeWhenPaid(GOODWILL_CREDIT);
        verifyRepaymentTransactionTypeWhenPaid(REPAYMENT);

    }

    private void verifyRepaymentTransactionTypeWhenPaid(final String repaymentTransactionType) {

        // Overpay loan
        Integer resourceId = (Integer) this.loanTransactionHelper.makeRepaymentTypePayment(REPAYMENT, "06 January 2022", 13000.00f,
                this.disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);
        resourceId = (Integer) this.loanTransactionHelper.makeRepaymentTypePayment(repaymentTransactionType, "06 January 2022", 1.00f,
                this.disbursedLoanID, "resourceId");
        Assertions.assertNotNull(resourceId);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void goodWillCreditWillCloseTheLoanCorrectly(LoanProductTestBuilder loanProductTestBuilder) {

        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float goodwillAmount = totalOutstanding;
        final String goodwillDate = "09 March 2022";
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(GOODWILL_CREDIT, goodwillDate,
                goodwillAmount, this.disbursedLoanID, "");

        GetLoansLoanIdResponse details = this.loanTransactionHelper.getLoan(this.requestSpec, this.responseSpec, disbursedLoanID);

        Assertions.assertNull(details.getSummary().getInArrears());
        Assertions.assertTrue(details.getStatus().getClosedObligationsMet());
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void paymentRefundWillCloseTheLoanCorrectly(LoanProductTestBuilder loanProductTestBuilder) {

        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float goodwillAmount = totalOutstanding;
        final String goodwillDate = "09 March 2022";
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(PAYOUT_REFUND, goodwillDate,
                goodwillAmount, this.disbursedLoanID, "");

        GetLoansLoanIdResponse details = this.loanTransactionHelper.getLoan(this.requestSpec, this.responseSpec, disbursedLoanID);

        Assertions.assertNull(details.getSummary().getInArrears());
        Assertions.assertTrue(details.getStatus().getClosedObligationsMet());
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newGoodwillCreditCreatesCorrectJournalEntriesForPeriodicAccrualsTest(LoanProductTestBuilder loanProductTestBuilder) {

        disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float goodwillAmount = totalOutstanding + overpaidAmount;
        final Float goodwillAmountInExpense = principalOutstanding + overpaidAmount;
        final String goodwillDate = "09 January 2022";
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(GOODWILL_CREDIT, goodwillDate,
                goodwillAmount, this.disbursedLoanID, "");

        // only a single credit for principal and interest as test sets up same GL account for both (summed up)
        this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, goodwillDate,
                new JournalEntry(totalOutstanding, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, goodwillDate,
                new JournalEntry(overpaidAmount, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, goodwillDate,
                new JournalEntry(goodwillAmountInExpense, JournalEntry.TransactionType.DEBIT));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void newGoodwillCreditCreatesCorrectJournalEntriesForCashAccountingTest(LoanProductTestBuilder loanProductTestBuilder) {

        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float goodwillAmount = totalOutstanding + overpaidAmount;
        final Float goodwillAmountInExpense = principalOutstanding + overpaidAmount;
        final String goodwillDate = "09 January 2022";
        HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(GOODWILL_CREDIT, goodwillDate,
                goodwillAmount, this.disbursedLoanID, "");

        this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, goodwillDate,
                new JournalEntry(principalOutstanding, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, goodwillDate,
                new JournalEntry(interestOutstanding, JournalEntry.TransactionType.CREDIT));

        this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount, goodwillDate,
                new JournalEntry(overpaidAmount, JournalEntry.TransactionType.CREDIT));
        this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, goodwillDate,
                new JournalEntry(goodwillAmountInExpense, JournalEntry.TransactionType.DEBIT));

    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void undoGoodWillCreditTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(GOODWILL_CREDIT,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.reverseLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void undoPayoutRefundTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(PAYOUT_REFUND,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.reverseLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void undoMerchantIssuedRefundTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(MERCHANT_ISSUED_REFUND,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.reverseLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void adjustGoodWillCreditTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(GOODWILL_CREDIT,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.adjustLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec403);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void adjustPayoutRefundTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(PAYOUT_REFUND,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.adjustLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec403);
    }

    @ParameterizedTest
    @MethodSource("loanProductFactory")
    public void adjustMerchantIssuedRefundTransactionTest(LoanProductTestBuilder loanProductTestBuilder) {
        // Given
        disburseLoanOfAccountingRule(CASH_BASED, loanProductTestBuilder);
        HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID);

        // pay off all of principal, interest (no fees or penalties)
        final Float principalOutstanding = (Float) loanSummaryMap.get("principalOutstanding");
        final Float interestOutstanding = (Float) loanSummaryMap.get("interestOutstanding");
        final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding");
        final Float overpaidAmount = 159.00f;
        final Float transactionAmount = totalOutstanding + overpaidAmount;
        final String transactionDate = "09 January 2022";
        PostLoansLoanIdTransactionsResponse loanTransactionResponse = loanTransactionHelper.makeLoanRepayment(MERCHANT_ISSUED_REFUND,
                transactionDate, transactionAmount, this.disbursedLoanID);
        Assertions.assertNotNull(loanTransactionResponse);
        Assertions.assertNotNull(loanTransactionResponse.getResourceId());

        // Then
        loanTransactionHelper.adjustLoanTransaction(this.disbursedLoanID, loanTransactionResponse.getResourceId(), transactionDate,
                responseSpec403);
    }

    private static AdvancedPaymentData createRepaymentPaymentAllocation() {
        AdvancedPaymentData advancedPaymentData = new AdvancedPaymentData();
        advancedPaymentData.setTransactionType("REPAYMENT");
        advancedPaymentData.setFutureInstallmentAllocationRule("NEXT_INSTALLMENT");

        List<PaymentAllocationOrder> paymentAllocationOrders = getPaymentAllocationOrder(PaymentAllocationType.PAST_DUE_PENALTY,
                PaymentAllocationType.PAST_DUE_FEE, PaymentAllocationType.PAST_DUE_INTEREST, PaymentAllocationType.PAST_DUE_PRINCIPAL,
                PaymentAllocationType.DUE_PENALTY, PaymentAllocationType.DUE_FEE, PaymentAllocationType.DUE_INTEREST,
                PaymentAllocationType.DUE_PRINCIPAL, PaymentAllocationType.IN_ADVANCE_PENALTY, PaymentAllocationType.IN_ADVANCE_FEE,
                PaymentAllocationType.IN_ADVANCE_PRINCIPAL, PaymentAllocationType.IN_ADVANCE_INTEREST);

        advancedPaymentData.setPaymentAllocationOrder(paymentAllocationOrders);
        return advancedPaymentData;
    }

    private static AdvancedPaymentData createDefaultPaymentAllocation() {
        AdvancedPaymentData advancedPaymentData = new AdvancedPaymentData();
        advancedPaymentData.setTransactionType("DEFAULT");
        advancedPaymentData.setFutureInstallmentAllocationRule("NEXT_INSTALLMENT");

        List<PaymentAllocationOrder> paymentAllocationOrders = getPaymentAllocationOrder(PaymentAllocationType.PAST_DUE_PENALTY,
                PaymentAllocationType.PAST_DUE_FEE, PaymentAllocationType.PAST_DUE_PRINCIPAL, PaymentAllocationType.PAST_DUE_INTEREST,
                PaymentAllocationType.DUE_PENALTY, PaymentAllocationType.DUE_FEE, PaymentAllocationType.DUE_PRINCIPAL,
                PaymentAllocationType.DUE_INTEREST, PaymentAllocationType.IN_ADVANCE_PENALTY, PaymentAllocationType.IN_ADVANCE_FEE,
                PaymentAllocationType.IN_ADVANCE_PRINCIPAL, PaymentAllocationType.IN_ADVANCE_INTEREST);

        advancedPaymentData.setPaymentAllocationOrder(paymentAllocationOrders);
        return advancedPaymentData;
    }

    private static List<PaymentAllocationOrder> getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) {
        AtomicInteger integer = new AtomicInteger(1);
        return Arrays.stream(paymentAllocationTypes).map(pat -> {
            PaymentAllocationOrder paymentAllocationOrder = new PaymentAllocationOrder();
            paymentAllocationOrder.setPaymentAllocationRule(pat.name());
            paymentAllocationOrder.setOrder(integer.getAndIncrement());
            return paymentAllocationOrder;
        }).toList();
    }

    private static Stream<Arguments> loanProductFactory() {
        return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                        new LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
                                .addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), createRepaymentPaymentAllocation()))));
    }

}
