package com.avitam.bankloanapplication.service.impl;

import com.avitam.bankloanapplication.model.dto.CustomerDto;
import com.avitam.bankloanapplication.model.dto.LoanDto;
import com.avitam.bankloanapplication.model.dto.LoanEmiDetailDto;
import com.avitam.bankloanapplication.model.dto.LoanTypeDto;
import com.avitam.bankloanapplication.model.dto.LoanWsDto;
import com.avitam.bankloanapplication.model.entity.Customer;
import com.avitam.bankloanapplication.model.entity.Loan;
import com.avitam.bankloanapplication.model.entity.LoanApplication;
import com.avitam.bankloanapplication.model.entity.LoanType;
import com.avitam.bankloanapplication.repository.CustomerRepository;
import com.avitam.bankloanapplication.repository.LoanApplicationRepository;
import com.avitam.bankloanapplication.repository.LoanDetailsRepository;
import com.avitam.bankloanapplication.repository.LoanRepository;
import com.avitam.bankloanapplication.repository.LoanTypeRepository;
import com.avitam.bankloanapplication.service.LoanService;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
public class LoanServiceImpl implements LoanService {


    public static final String ADMIN_lOAN = "/loans/loan";
    @Autowired
    private LoanRepository loanRepository;
    @Autowired
    private LoanDetailsRepository loanDetailsRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private LoanTypeRepository loanTypeRepository;
    @Autowired
    private LoanApplicationRepository loanApplicationRepository;

    public LoanWsDto createLoan(LoanDto loanDto) {
        LoanWsDto request = new LoanWsDto();
        Loan loan = new Loan();
        List<Loan> loans = new ArrayList<>();
//            loanDto.setRecordId(null);
        if (loanDto.getRecordId() != null) {
            loan = loanRepository.findByRecordId(loanDto.getRecordId());
            modelMapper.map(loanDto, loan);
            loanRepository.save(loan);
            request.setMessage("Data updated successfully");
        } else {
            loan = modelMapper.map(loanDto, Loan.class);
            loan.setId(null);
            loan.setRecordId(null);
            loan.setStatus(true);
            loan.setCreationTime(new Date());
            LocalDate localDate = LocalDate.now();
            loan.setSanctionDate(localDate);
            loan.setLoanStatus("Active");
            //loan.setForeClosingCharges(loan.getDesiredLoan()*5/100);
            modelMapper.map(loanDto, loan);
            loanRepository.save(loan);
        }
        if (request.getRecordId() == null) {
            loan.setRecordId(String.valueOf(loan.getId().getTimestamp()));
        } else {
            checkLoanStatus(loan);
        }

        loanRepository.save(loan);
        loans.add(loan);
        getForeclosingCharges(loan);
        loanDto.setBaseUrl(ADMIN_lOAN);

        request.setMessage("Data added Successfully");
        List<LoanDto> loanDtoList = new ArrayList<>();
        Type listType = new TypeToken<List<LoanDto>>() {
        }.getType();
        //loanDtoList.add(modelMapper.map(loan, LoanDto.class));
        request.setLoanDtoList(modelMapper.map(loans, listType));
        //request.setLoanDtoList(loanDtoList);
        return request;
    }


    public void getForeclosingCharges(Loan loan) {
        BigDecimal foreClosingCharges = loan.getDesiredLoan().multiply(BigDecimal.valueOf(5 / 100));
        loan.setForeClosingCharges(foreClosingCharges);
        loanRepository.save(loan);
    }

    @Override
    public LoanDto getEmiStatusTillDate(LoanDto loanDto) {
        Loan loan = loanRepository.findByRecordId(loanDto.getRecordId());
        LocalDate sanctionDate = loan.getSanctionDate();
        LocalDate currentDate = LocalDate.now();
//        currentDate = currentDate.plusMonths(0);
//        currentDate = currentDate.plusDays(20);
        LocalDate baseDate = sanctionDate.withDayOfMonth(5);

        int noOfMonths = 0;
        for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
            if (loanEmiDetailDto.getPaymentStatus().equalsIgnoreCase("Paid")) {
                noOfMonths++;
            }
        }

        if (sanctionDate.getDayOfMonth() > 5) {
            baseDate = baseDate.plusMonths(noOfMonths + 1);
        } else {
            baseDate = baseDate.plusMonths(noOfMonths);
        }

        BigDecimal totalInterestAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalInstalmentAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalPayableAmount = BigDecimal.valueOf(0.0);
        BigDecimal pendingTotalEmiAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalPenalty = BigDecimal.valueOf(0.0);
        boolean currentDueHandled = false;

        for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
            if (loanEmiDetailDto.getPaymentStatus().equalsIgnoreCase("Paid")) {
                totalPayableAmount = totalPayableAmount.add(loanEmiDetailDto.getTotalPayable());
                totalInterestAmount = totalInterestAmount.add(loanEmiDetailDto.getInterestAmount());
                totalInstalmentAmount = totalInstalmentAmount.add(loanEmiDetailDto.getInstalment());
                totalPenalty = totalPenalty.add(loanEmiDetailDto.getPenalty());
                pendingTotalEmiAmount = pendingTotalEmiAmount.add(loanEmiDetailDto.getPendingEmiAmount());
            } else if (!currentDueHandled) {
                loanEmiDetailDto.setDueDate(baseDate);

                BigDecimal instalment;
                BigDecimal foreclosingCharges = BigDecimal.valueOf(0.0);

                if (loanDto.getForeClosing()) {
                    instalment = roundToTwoDecimal(loan.getPendingInstallmentAmount().setScale(2, RoundingMode.HALF_UP));
                    foreclosingCharges = roundToTwoDecimal(loan.getDesiredLoan().multiply(BigDecimal.valueOf(5.00 / 100.00)));
                    loan.setForeClosingCharges(foreclosingCharges);
                } else {
                    instalment = roundToTwoDecimal(loanEmiDetailDto.getInstalment());
                }

                BigDecimal interest = roundToTwoDecimal(loanEmiDetailDto.getInterestAmount());
                BigDecimal baseAmount = roundToTwoDecimal(instalment.add(interest));

                BigDecimal penalty = BigDecimal.valueOf(0.0);
                if (currentDate.isAfter(baseDate)) {
                    BigDecimal daysLate = BigDecimal.valueOf((int) ChronoUnit.DAYS.between(baseDate, currentDate));
                    if (loanEmiDetailDto.getPendingEmiAmount().equals(BigDecimal.valueOf(0.0))) {
                        penalty = roundToTwoDecimal(loanEmiDetailDto.getInstalment().multiply(BigDecimal.valueOf(0.05)).multiply(daysLate));
                    }
                }

                BigDecimal totalPayable = roundToTwoDecimal(baseAmount.add(penalty).add(foreclosingCharges)).add(pendingTotalEmiAmount);

                loanEmiDetailDto.setInstalment(instalment);
                loanEmiDetailDto.setPenalty(penalty);
                loanEmiDetailDto.setTotalPayable(totalPayable);
//                loanEmiDetailDto.setPendingEmiAmount(loanEmiDetailDto.getPendingEmiAmount().add(penalty));

                //loan.setPendingInstallmentAmount(roundToTwoDecimal(loan.getPendingInstallmentAmount() - loanEmiDetailDto.getInstalment()));
                currentDueHandled = true;
            }
        }

        loan.setTotalPayableAmount(roundToTwoDecimal(totalPayableAmount));
        loan.setTotalInterestAmount(roundToTwoDecimal(totalInterestAmount));
        loan.setTotalInstalmentAmount(roundToTwoDecimal(totalInstalmentAmount));
        loan.setTotalPenalty(roundToTwoDecimal(totalPenalty));
        loan.setLoanEmiDetailDtoList(loan.getLoanEmiDetailDtoList());
        loan.setPendingTotalEmiAmount(pendingTotalEmiAmount);

        //checkLoanStatus(loan);
        loanRepository.save(loan);

        modelMapper.map(loan, loanDto);
        return loanDto;
    }


    @Override
    public LoanDto getForeclosureCalculation(LoanDto loanDto) {
        Loan loan = loanRepository.findByRecordId(loanDto.getRecordId());
        LocalDate sanctionDate = loan.getSanctionDate();
        LocalDate currentDate = LocalDate.now();
        LocalDate baseDate = sanctionDate.withDayOfMonth(5);

        // Count number of months already paid
        int noOfMonthsPaid = 0;
        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
            if ("Paid".equalsIgnoreCase(emi.getPaymentStatus())) {
                noOfMonthsPaid++;
            }
        }

        if (sanctionDate.getDayOfMonth() > 5) {
            baseDate = baseDate.plusMonths(noOfMonthsPaid + 1);
        } else {
            baseDate = baseDate.plusMonths(noOfMonthsPaid);
        }

        // Calculate previous pending amounts
        BigDecimal totalPreviousPendingAmount = BigDecimal.ZERO;
        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
            if (!"Paid".equalsIgnoreCase(emi.getPaymentStatus()) && emi.getPendingEmiAmount() != null) {
                totalPreviousPendingAmount = totalPreviousPendingAmount.add(emi.getPendingEmiAmount());
            }
        }

        // Calculate total unpaid installments, interest, and penalties
        BigDecimal totalUnpaidInstalments = BigDecimal.ZERO;
        BigDecimal totalUnpaidInterest = BigDecimal.ZERO;
        BigDecimal totalPenalty = BigDecimal.ZERO;

        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
            if (!"Paid".equalsIgnoreCase(emi.getPaymentStatus())) {
                BigDecimal instalment = emi.getInstalment() != null ? emi.getInstalment() : BigDecimal.ZERO;
                BigDecimal interest = emi.getInterestAmount() != null ? emi.getInterestAmount() : BigDecimal.ZERO;

                totalUnpaidInstalments = totalUnpaidInstalments.add(instalment);
                totalUnpaidInterest = totalUnpaidInterest.add(interest);

                if (currentDate.isAfter(baseDate)) {
                    BigDecimal daysLate = BigDecimal.valueOf(ChronoUnit.DAYS.between(baseDate, currentDate));
                    totalPenalty = totalPenalty.add(instalment.multiply(BigDecimal.valueOf(0.05)).multiply(daysLate));
                }

                baseDate = baseDate.plusMonths(1);
            }
        }

        totalPenalty = roundToTwoDecimal(totalPenalty);

        // ✅ Foreclosure charges: only if foreClosing = true AND pending installments exist
        BigDecimal foreclosingCharges = BigDecimal.ZERO;
        if (loanDto.getForeClosing() != null && loanDto.getForeClosing()) {
            if (loan.getPendingInstallmentAmount() != null && loan.getPendingInstallmentAmount().compareTo(BigDecimal.ZERO) > 0) {
                foreclosingCharges = roundToTwoDecimal(
                        loan.getDesiredLoan() != null ? loan.getDesiredLoan().multiply(BigDecimal.valueOf(5.00 / 100.00))
                                : BigDecimal.ZERO
                );
            }
            loan.setForeClosingCharges(foreclosingCharges);
        }

        // Compute total foreclosure amount including charges
        BigDecimal totalForeclosingAmount = totalUnpaidInstalments
                .add(totalUnpaidInterest)
                .add(totalPenalty)
                .add(totalPreviousPendingAmount)
                .add(foreclosingCharges);

        totalForeclosingAmount = roundToTwoDecimal(totalForeclosingAmount);

        String message = "Foreclosure calculation completed.";

        LoanEmiDetailDto firstUnpaidEmi = loan.getLoanEmiDetailDtoList().stream()
                .filter(e -> !"Paid".equalsIgnoreCase(e.getPaymentStatus()))
                .findFirst()
                .orElse(null);

        LoanEmiDetailDto foreclosureEmi = null;
        if (firstUnpaidEmi != null) {
            foreclosureEmi = new LoanEmiDetailDto();
            foreclosureEmi.setRecordId(firstUnpaidEmi.getRecordId());
            foreclosureEmi.setPaymentStatus(firstUnpaidEmi.getPaymentStatus());
            foreclosureEmi.setMonth(firstUnpaidEmi.getMonth());
            foreclosureEmi.setPendingEmiAmount(firstUnpaidEmi.getPendingEmiAmount());
            foreclosureEmi.setInstalment(totalUnpaidInstalments);
            foreclosureEmi.setInterestAmount(totalUnpaidInterest);
            foreclosureEmi.setPenalty(totalPenalty);
            foreclosureEmi.setTotalPayable(totalForeclosingAmount); // includes charges if applicable
            foreclosureEmi.setDueDate(firstUnpaidEmi.getDueDate());
        }

        LoanDto response = new LoanDto();
        response.setLoanEmiDetailDtoList(Collections.singletonList(foreclosureEmi));
        response.setPendingInstallmentAmount(loan.getPendingInstallmentAmount());
        response.setForeClosingCharges(foreclosingCharges); // updated charges
        response.setForeClosing(loanDto.getForeClosing()); // keep user input flag
        response.setTotalForeclosingAmount(totalForeclosingAmount);
        response.setDueDate(firstUnpaidEmi != null ? firstUnpaidEmi.getDueDate() : null);
        response.setInterestAmount(totalUnpaidInterest);
        response.setPreviousMonthPendingAmount(totalPreviousPendingAmount);
        response.setMessage(message);

        return response;
    }


//    @Override
//    public LoanDto getForeclosureCalculation(LoanDto loanDto) {
//        Loan loan = loanRepository.findByRecordId(loanDto.getRecordId());
//        LocalDate sanctionDate = loan.getSanctionDate();
//        LocalDate currentDate = LocalDate.now();
//        LocalDate baseDate = sanctionDate.withDayOfMonth(5);
//
//        // Count the number of months already paid
//        int noOfMonthsPaid = 0;
//        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
//            if ("Paid".equalsIgnoreCase(emi.getPaymentStatus())) {
//                noOfMonthsPaid++;
//            }
//        }
//
//        // Adjust baseDate based on sanction date and months paid
//        if (sanctionDate.getDayOfMonth() > 5) {
//            baseDate = baseDate.plusMonths(noOfMonthsPaid + 1);
//        } else {
//            baseDate = baseDate.plusMonths(noOfMonthsPaid);
//        }
//
//        // Sum of all previous pending EMI amounts
//        BigDecimal totalPreviousPendingAmount = BigDecimal.ZERO;
//        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
//            if (!"Paid".equalsIgnoreCase(emi.getPaymentStatus())
//                    && emi.getPendingEmiAmount() != null) {
//                totalPreviousPendingAmount = totalPreviousPendingAmount.add(emi.getPendingEmiAmount());
//            }
//        }
//
//        // Sum of all unpaid EMIs + interest
//        BigDecimal totalUnpaidInstalments = BigDecimal.ZERO;
//        BigDecimal totalUnpaidInterest = BigDecimal.ZERO;
//        BigDecimal totalPenalty = BigDecimal.ZERO;
//
//        for (LoanEmiDetailDto emi : loan.getLoanEmiDetailDtoList()) {
//            if (!"Paid".equalsIgnoreCase(emi.getPaymentStatus())) {
//                BigDecimal instalment = emi.getInstalment();
//                BigDecimal interest = emi.getInterestAmount();
//
//                totalUnpaidInstalments = totalUnpaidInstalments.add(instalment);
//                totalUnpaidInterest = totalUnpaidInterest.add(interest);
//
//                // Penalty calculation for overdue
//                if (currentDate.isAfter(baseDate)) {
//                    BigDecimal daysLate = BigDecimal.valueOf(ChronoUnit.DAYS.between(baseDate, currentDate));
//                    totalPenalty = totalPenalty.add(instalment.multiply(BigDecimal.valueOf(0.05)).multiply(daysLate));
//                }
//
//                // Move baseDate to next EMI
//                baseDate = baseDate.plusMonths(1);
//            }
//        }
//
//        totalPenalty = roundToTwoDecimal(totalPenalty);
//
//        // Foreclosing charges (5% of loan amount if foreclosure is true)
//        BigDecimal foreclosingCharges = loanDto.getForeClosing()
//                ? loan.getDesiredLoan().multiply(BigDecimal.valueOf(0.05))
//                : BigDecimal.ZERO;
//
//        // Total foreclosure amount (includes foreclosing charges)
//        BigDecimal totalForeclosingAmount = totalUnpaidInstalments
//                .add(totalUnpaidInterest)
//                .add(totalPenalty)
//                .add(foreclosingCharges)
//                .add(totalPreviousPendingAmount);
//        totalForeclosingAmount = roundToTwoDecimal(totalForeclosingAmount);
//
//        // -------------------------------
//        // NEW LOGIC: If total foreclosing amount is fully paid
//        // -------------------------------
//        String message = "";
//        if (loanDto.getTotalForeclosingAmount() != null &&
//                loanDto.getTotalForeclosingAmount().compareTo(totalForeclosingAmount) >= 0) {
//
//            // When total foreclosure amount is fully paid, set charges to 0
//            foreclosingCharges = BigDecimal.ZERO;
//            totalForeclosingAmount = BigDecimal.ZERO;
//            message = "Loan foreclosed successfully.";
//        }
//        // -------------------------------
//
//        // Prepare first unpaid EMI DTO for response
//        LoanEmiDetailDto firstUnpaidEmi = loan.getLoanEmiDetailDtoList().stream()
//                .filter(e -> !"Paid".equalsIgnoreCase(e.getPaymentStatus()))
//                .findFirst()
//                .orElse(null);
//
//        LoanEmiDetailDto foreclosureEmi = null;
//        if (firstUnpaidEmi != null) {
//            foreclosureEmi = new LoanEmiDetailDto();
//            foreclosureEmi.setRecordId(firstUnpaidEmi.getRecordId());
//            foreclosureEmi.setPaymentStatus(firstUnpaidEmi.getPaymentStatus());
//            foreclosureEmi.setMonth(firstUnpaidEmi.getMonth());
//            foreclosureEmi.setPendingEmiAmount(firstUnpaidEmi.getPendingEmiAmount());
//            foreclosureEmi.setInstalment(totalUnpaidInstalments);
//            foreclosureEmi.setInterestAmount(totalUnpaidInterest);
//            foreclosureEmi.setPenalty(totalPenalty);
//            foreclosureEmi.setTotalPayable(totalForeclosingAmount);
//            foreclosureEmi.setDueDate(firstUnpaidEmi.getDueDate());
//        }
//
//        // Prepare response
//        LoanDto response = new LoanDto();
//        response.setLoanEmiDetailDtoList(Collections.singletonList(foreclosureEmi));
//        response.setPendingInstallmentAmount(loan.getPendingInstallmentAmount());
//        response.setForeClosingCharges(foreclosingCharges);
//        response.setTotalForeclosingAmount(totalForeclosingAmount);
//        response.setDueDate(firstUnpaidEmi != null ? firstUnpaidEmi.getDueDate() : null);
//        response.setInterestAmount(totalUnpaidInterest);
//        response.setPreviousMonthPendingAmount(totalPreviousPendingAmount);
//        response.setMessage(message); // ← add message in LoanDto
//
//        return response;
//    }
//
//
//



    public LoanDto updatePaymentStatus(LoanDto loanDto) {

        Loan loan = loanRepository.findByRecordId(loanDto.getRecordId());
        int loopCount = 0;

        BigDecimal totalInterestAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalInstalmentAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalPayableAmount = BigDecimal.valueOf(0.0);
        BigDecimal totalPenalty = BigDecimal.valueOf(0.0);

        for (LoanEmiDetailDto loanEmiDetail : loan.getLoanEmiDetailDtoList()) {
            LoanEmiDetailDto loanEmiDetailDto1 = loanDto.getLoanEmiDetailDtoList().get(0);
            if (loanEmiDetail.getPaymentStatus().equalsIgnoreCase("Unpaid")) {
                if (loanEmiDetailDto1.getRecordId().equalsIgnoreCase(loanEmiDetail.getRecordId())) {
                    loanEmiDetail.setPaymentStatus(loanEmiDetailDto1.getPaymentStatus());
                    loanEmiDetail.setRecordId(loanEmiDetailDto1.getRecordId());
//                    loan.setTotalInterestAmount(loan.getTotalInterestAmount() + loanEmiDetail.getInterestAmount());
//                    loan.setTotalInstalmentAmount(loan.getTotalInstalmentAmount() + loanEmiDetail.getInstalment());
//                    loan.setTotalPayableAmount(loan.getTotalPayableAmount() + loanEmiDetail.getTotalPayable());
//                    loan.setTotalPenalty(loan.getTotalPenalty() + loanEmiDetail.getPenalty());
                    loan.setPendingInstallmentAmount(roundToTwoDecimal(loan.getPendingInstallmentAmount().subtract(loanEmiDetail.getInstalment())));
                    loanDto.setMessage("Payment Done Successfully");
                    loopCount++;
                    break;
                }
            }
            loopCount++;
        }

        if (loan.getPendingInstallmentAmount().compareTo(BigDecimal.ZERO) == 0) {
            for (int i = loopCount; i < loan.getTenure().intValue(); i++) {
                LoanEmiDetailDto loanEmiDetailDto = loan.getLoanEmiDetailDtoList().get(i);
                loanEmiDetailDto.setPaymentStatus("Paid");
                loanEmiDetailDto.setDueDate(loan.getLoanEmiDetailDtoList().get(loopCount - 1).getDueDate());
                loanEmiDetailDto.setInstalment(BigDecimal.valueOf(0));
                loanEmiDetailDto.setInterestAmount(BigDecimal.valueOf(0));
                loanEmiDetailDto.setTotalPayable(BigDecimal.valueOf(0));
                loanEmiDetailDto.setPenalty(BigDecimal.valueOf(0));
            }
            if (BigDecimal.valueOf(loopCount).compareTo(loan.getTenure()) < 0) {
                loan.setForeClosing(true);
                loan.setLoanEmi(BigDecimal.valueOf(0));
                for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
                    totalInstalmentAmount = totalInstalmentAmount.add(loanEmiDetailDto.getInstalment());
                    totalInterestAmount = totalInterestAmount.add(loanEmiDetailDto.getInterestAmount());
                    totalPayableAmount = totalPayableAmount.add(loanEmiDetailDto.getTotalPayable());
                    totalPenalty = totalPenalty.add(loanEmiDetailDto.getPenalty());
                }
                loan.setTotalInstalmentAmount(totalInstalmentAmount);
                loan.setTotalInterestAmount(totalInterestAmount);
                loan.setTotalPayableAmount(totalPayableAmount);
                loan.setTotalPenalty(totalPenalty);
                LocalDate localDate = LocalDate.now();
                loan.setClosureDate(localDate);
            }
        }
        loan.setLoanEmiDetailDtoList(loan.getLoanEmiDetailDtoList());
        checkLoanStatus(loan);
        modelMapper.map(loan, loanDto);
        loanRepository.save(loan);

        int paidCount = 0;
        for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
            if (loanEmiDetailDto.getPaymentStatus().equalsIgnoreCase("Paid")) {
                paidCount++;
            }
        }

        for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
            int index = Integer.parseInt(loanEmiDetailDto.getRecordId());
            if (paidCount == index) {
                loan.setLoanEmi(loanEmiDetailDto.getTotalPayable());
                break;
            }
        }
        modelMapper.map(loan, loanDto);
        loanRepository.save(loan);

        return loanDto;
    }

    public void checkLoanStatus(Loan loan) {
        int paidCount = 0;
        for (LoanEmiDetailDto loanEmiDetailDto : loan.getLoanEmiDetailDtoList()) {
            if (loanEmiDetailDto.getPaymentStatus().equalsIgnoreCase("Paid")) {
                paidCount++;
            }
        }
        if (BigDecimal.valueOf(paidCount).equals(loan.getTenure())) {
            loan.setLoanStatus("Completed");
            LoanApplication loanApplication = loanApplicationRepository.findByLoanId(loan.getRecordId());
            loanApplication.setLoanStatus("Completed");
            loanApplicationRepository.save(loanApplication);
        } else {
            loan.setLoanStatus("Active");
        }
    }

    public void getLoanType(Loan loan) {

        LoanType loanType = loanTypeRepository.findByRecordId(loan.getLoanTypeDto().getRecordId());
        //loan.setLoanType(loanType.getRecordId());
        LoanTypeDto loanTypeDto = modelMapper.map(loanType, LoanTypeDto.class);
        loan.setLoanTypeDto(loanTypeDto);

    }

    public void getCustomer(Loan loan) {

        Customer customer = customerRepository.findByRecordId(loan.getCustomerDto().getRecordId());
        CustomerDto customerDto = modelMapper.map(customer, CustomerDto.class);
        loan.setCustomerDto(customerDto);
    }

//    private double roundToTwoDecimal(double value) {
//        return Math.round(value * 100.0) / 100.0;
//    }

    private BigDecimal roundToTwoDecimal(BigDecimal value) {
        return value.setScale(2, RoundingMode.HALF_UP);
    }


    @Override
    public LoanWsDto getTotalDesiredLoanByCustomerRecordId(LoanWsDto request) {
        LoanWsDto loanWsDto = new LoanWsDto();
        List<LoanDto> loanDtos = new ArrayList<>();
        for (LoanDto loanDto : request.getLoanDtoList()) {
            List<Loan> loans = loanRepository.findByCustomerIdAndLoanStatus(loanDto.getCustomerId(), "Active");
            BigDecimal total = BigDecimal.ZERO;

            for (Loan loan : loans) {
                total = total.add(loan.getDesiredLoan());
                loanDto.setDesiredLoan(total);
            }

            loanDtos.add(loanDto);

        }
        loanWsDto.setLoanDtoList(loanDtos);
        return loanWsDto;
    }
}


//                if(loanDto.getLoanEmiDetailDtoList()!=null) {
//                    for (LoanEmiDetailDto loanEmiDetailDto1 : loanDto.getLoanEmiDetailDtoList()) {
//                        if (loanEmiDetailDto1.getRecordId().equalsIgnoreCase(loanEmiDetailDto.getRecordId())) {
//                            if (loanEmiDetailDto1.getEmiPaid() != null) {
//                                if(loanEmiDetailDto.getEmiPaid()!=null) {
//                                    loanEmiDetailDto.setEmiPaid(loanEmiDetailDto.getEmiPaid().add(loanEmiDetailDto1.getEmiPaid().add(penalty)));
//                                }
//                                else{
//                                    loanEmiDetailDto.setEmiPaid(loanEmiDetailDto1.getEmiPaid().add(penalty));
//                                }
//                                loanEmiDetailDto.setPendingEmiAmount(loanEmiDetailDto.getTotalPayable().subtract(loanEmiDetailDto.getEmiPaid().add(penalty)));
//                            }
//                        }
//                    }
//                }