/**
 * 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 java.lang.Boolean.TRUE;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends BaseLoanIntegrationTest {

    public static final BigDecimal DOWN_PAYMENT_PERCENTAGE = new BigDecimal(25);

    @Test
    public void testNextPaymentDateForUnpaidInstallmentsWithNPlusOneTest() {
        runAt("01 November 2023", () -> {
            try {
                // update Global configuration for next payment date
                GlobalConfigurationHelper.updateLoanNextPaymentDateConfiguration(this.requestSpec, this.responseSpec,
                        "next-unpaid-due-date");
                // Create Client
                Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();

                // Create Loan Product
                Long loanProductId = createLoanProductWith25PctDownPaymentAndDelinquencyBucket(false, true, false, 0);

                // Apply and Approve Loan
                Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 November 2023", 1000.0, 3, req -> {
                    req.submittedOnDate("01 November 2023");
                    req.setLoanTermFrequency(45);
                    req.setRepaymentEvery(15);
                    req.setGraceOnArrearsAgeing(0);
                });

                // Loan amount Disbursement
                disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 November 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, false, "01 November 2023"), //
                        installment(250.0, false, "16 November 2023"), //
                        installment(250.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023") //
                );

                // delinquency next payment date for 01 Nov Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "01 November 2023", false);

                // Update business date
                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("13 November 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 13 Nov Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("16 November 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 16 Nov Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("01 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 01 Dec Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false);

                // add charge with due date after loan maturity date (N + 1)
                Long loanChargeId = addCharge(loanId, false, 50, "23 December 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, false, "01 November 2023"), //
                        installment(250.0, false, "16 November 2023"), //
                        installment(250.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023"), //
                        installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") //
                );

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("17 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 17 Dec Business date N + 1
                verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("25 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency null next payment date for date after maturity date
                verifyLoanDelinquencyNextPaymentDate(loanId, "", true);

            } finally {
                // reset global config
                GlobalConfigurationHelper.updateLoanNextPaymentDateConfiguration(this.requestSpec, this.responseSpec,
                        "earliest-unpaid-date");
            }

        });
    }

    @Test
    public void testNextPaymentDateFor2Paid1PartiallyPaidInstallmentsWithNPlusOneTest() {
        runAt("01 November 2023", () -> {
            try {
                // update Global configuration for next payment date
                GlobalConfigurationHelper.updateLoanNextPaymentDateConfiguration(this.requestSpec, this.responseSpec,
                        "next-unpaid-due-date");
                // Create Client
                Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();

                // Create Loan Product with auto downpayment enabled
                Long loanProductId = createLoanProductWith25PctDownPaymentAndDelinquencyBucket(true, true, false, 0);

                // Apply and Approve Loan
                Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 November 2023", 1000.0, 3, req -> {
                    req.submittedOnDate("01 November 2023");
                    req.setLoanTermFrequency(45);
                    req.setRepaymentEvery(15);
                    req.setGraceOnArrearsAgeing(0);
                });

                // Loan amount Disbursement
                disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 November 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, true, "01 November 2023"), //
                        installment(250.0, false, "16 November 2023"), //
                        installment(250.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023") //
                );

                // delinquency next payment date for 01 Nov Business date with auto paid downpayment installment
                verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);

                // Update business date
                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("13 November 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 13 Nov Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);

                // pay 16 Nov Installment
                addRepaymentForLoan(loanId, 250.0, "13 November 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, true, "01 November 2023"), //
                        installment(250.0, true, "16 November 2023"), //
                        installment(250.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023")//
                );

                // delinquency next payment date for 13 Nov Business date after paying 16 November Installment
                verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("16 November 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 16 Nov Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);

                // partially pay 01 December installment
                addRepaymentForLoan(loanId, 100.0, "16 November 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, true, "01 November 2023"), //
                        installment(250.0, true, "16 November 2023"), //
                        installment(250.0, 0.0, 150.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023")//
                );

                // delinquency next payment date for 16 Nov Business date after partial payment of 01 Dec installment
                verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("01 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 01 December Business date
                verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false);

                // add charge with due date after loan maturity date (N + 1)
                Long loanChargeId = addCharge(loanId, false, 50, "23 December 2023");

                // verify repayment schedule
                verifyRepaymentSchedule(loanId, //
                        installment(0, null, "01 November 2023"), //
                        installment(250.0, true, "01 November 2023"), //
                        installment(250.0, true, "16 November 2023"), //
                        installment(250.0, 0.0, 150.0, false, "01 December 2023"), //
                        installment(250.0, false, "16 December 2023"), //
                        installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") //
                );

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("17 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency next payment date for 17 Dec Business date N + 1
                verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false);

                businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("25 December 2023")
                        .dateFormat(DATETIME_PATTERN).locale("en"));

                // delinquency null next payment date for date after maturity date
                verifyLoanDelinquencyNextPaymentDate(loanId, "", true);

            } finally {
                // reset global config
                GlobalConfigurationHelper.updateLoanNextPaymentDateConfiguration(this.requestSpec, this.responseSpec,
                        "earliest-unpaid-date");
            }

        });
    }

    private void verifyLoanDelinquencyNextPaymentDate(Long loanId, String nextPaymentDate, boolean verifyNull) {
        GetLoansLoanIdResponse loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
        Assertions.assertNotNull(loan.getDelinquent());
        if (!verifyNull) {
            Assertions.assertNotNull(loan.getDelinquent().getNextPaymentDueDate());
            assertThat(loan.getDelinquent().getNextPaymentDueDate().isEqual(LocalDate.parse(nextPaymentDate, dateTimeFormatter)));
        } else {
            Assertions.assertNull(loan.getDelinquent().getNextPaymentDueDate());
        }

    }

    private Long createLoanProductWith25PctDownPaymentAndDelinquencyBucket(boolean autoDownPaymentEnabled, boolean multiDisburseEnabled,
            boolean installmentLevelDelinquencyEnabled, Integer graceOnArrearsAging) {
        // Create DelinquencyBuckets
        Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, List.of(//
                Pair.of(1, 3), //
                Pair.of(4, 10), //
                Pair.of(11, 60), //
                Pair.of(61, null)//
        ));
        PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
        product.setDelinquencyBucketId(delinquencyBucketId.longValue());
        product.setMultiDisburseLoan(multiDisburseEnabled);
        product.setEnableDownPayment(true);
        product.setGraceOnArrearsAgeing(graceOnArrearsAging);

        product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE);
        product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
        product.setEnableInstallmentLevelDelinquency(installmentLevelDelinquencyEnabled);

        PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
        GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
                .retrieveLoanProductById(loanProductResponse.getResourceId());

        Long loanProductId = loanProductResponse.getResourceId();

        assertEquals(TRUE, getLoanProductsProductIdResponse.getEnableDownPayment());
        assertNotNull(getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment());
        assertEquals(0, getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment().compareTo(DOWN_PAYMENT_PERCENTAGE));
        assertEquals(autoDownPaymentEnabled, getLoanProductsProductIdResponse.getEnableAutoRepaymentForDownPayment());
        assertEquals(multiDisburseEnabled, getLoanProductsProductIdResponse.getMultiDisburseLoan());
        return loanProductId;

    }
}
