package com.avitam.bankloanapplication.service.impl;

import com.avitam.bankloanapplication.model.dto.LoanLimitDto;
import com.avitam.bankloanapplication.model.dto.LoanLimitWsDto;
import com.avitam.bankloanapplication.model.entity.Customer;
import com.avitam.bankloanapplication.model.entity.LoanLimit;
import com.avitam.bankloanapplication.repository.CustomerRepository;
import com.avitam.bankloanapplication.repository.LoanLimitRepository;
import com.avitam.bankloanapplication.service.ImageConverterService;
import com.avitam.bankloanapplication.service.LoanLimitService;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class LoanLimitServiceImpl implements LoanLimitService {
    public static final String URL = "https://api.shreemeenakshifinance.com/images/";
    private static final String ADMIN_LOANLIMIT = "/loans/loanLimit";
    @Autowired
    private LoanLimitRepository loanLimitRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private ImageConverterService imageConverterService;

    public LoanLimitWsDto editLoanLimit(LoanLimitDto loanLimitDto) {
        LoanLimitWsDto request = new LoanLimitWsDto();
        LoanLimit loanLimit = new LoanLimit();
        List<LoanLimit> loanLimits = new ArrayList<>();

        if (loanLimitDto.getRecordId() != null) {
            loanLimit = loanLimitRepository.findByRecordId(loanLimitDto.getRecordId());
            modelMapper.map(loanLimitDto, loanLimit);
            loanLimitRepository.save(loanLimit);
            request.setMessage("Data updated successfully");
        } else {
            Customer customer = customerRepository.findByRecordId(loanLimitDto.getCustomerId());
            Double monthlyIncome = customer.getMonthlyIncome();
            if (loanLimitDto.getCibilScore() >= 750 & loanLimitDto.getCibilScore() <= 900) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 50 / 100));

            } else if (loanLimitDto.getCibilScore() >= 700 & loanLimitDto.getCibilScore() <= 749) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 40 / 100));

            } else if (loanLimitDto.getCibilScore() >= 650 & loanLimitDto.getCibilScore() <= 699) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 30 / 100));

            } else if (loanLimitDto.getCibilScore() >= 600 & loanLimitDto.getCibilScore() <= 649) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 20 / 100));

            } else if (loanLimitDto.getCibilScore() >= 300 & loanLimitDto.getCibilScore() <= 599) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 70 / 100));

            } else if (loanLimitDto.getCibilScore() == 0) {
                loanLimitDto.setEmi(BigDecimal.valueOf(monthlyIncome * 70 / 100));
            }

            loanLimitDto.setLoanLimitAmount(LoanLimitCalculator(loanLimitDto));
            //loanLimitDto.setLoanTypeList(eligibleLoanTypes(loanLimitDto));

            loanLimit = modelMapper.map(loanLimitDto, LoanLimit.class);
            loanLimit.setCreationTime(new Date());
            loanLimit.setStatus(true);
            loanLimitRepository.save(loanLimit);
            customer.setCibilScore(loanLimitDto.getCibilScore());
            String cibilPdf = loanLimitDto.getCibilPdf();
            if (StringUtils.isNotEmpty(cibilPdf)) {
                customer.setCibilPdf(URL + imageConverterService.saveImageUrlToPath(cibilPdf, customer.getRecordId() + "cibilpdf"));
            }
            customerRepository.save(customer);
        }
        if (request.getRecordId() == null) {
            loanLimit.setRecordId(String.valueOf(loanLimit.getId().getTimestamp()));
        }
        loanLimitRepository.save(loanLimit);
        loanLimits.add(loanLimit);
        request.setBaseUrl(ADMIN_LOANLIMIT);
        request.setMessage("Data added Successfully");
        request.setLoanLimitDtos(modelMapper.map(loanLimits, List.class));
        return request;
    }

//    public Double LoanLimitCalculator(LoanLimitDto loanLimitDto) {
//
//        Double emi = loanLimitDto.getEmi();
//        Double interestRate = (loanLimitDto.getInterestRate() / 100) / 12;
//
//        Integer tenure = loanLimitDto.getTenure() * 12;
//
//        Double numerator = emi * (Math.pow(1 + interestRate, tenure) - 1);
//        Double denominator = interestRate * Math.pow(1 + interestRate, tenure);
//
//        return Math.round((numerator / denominator) * 100.0) / 100.0;
//    }

    public BigDecimal LoanLimitCalculator(LoanLimitDto loanLimitDto) {
        BigDecimal emi = loanLimitDto.getEmi();
        BigDecimal interestRate = loanLimitDto.getInterestRate().divide(BigDecimal.valueOf(100 * 12), 10, RoundingMode.HALF_UP);
        int tenure = loanLimitDto.getTenure() * 12;

        BigDecimal onePlusRatePowerTenure = interestRate.add(BigDecimal.ONE).pow(tenure);
        BigDecimal numerator = emi.multiply(onePlusRatePowerTenure.subtract(BigDecimal.ONE));
        BigDecimal denominator = interestRate.multiply(onePlusRatePowerTenure);

        BigDecimal loanAmount = numerator.divide(denominator, 2, RoundingMode.HALF_UP);
        return loanAmount;
    }

}
