package ee.tuleva.onboarding.comparisons.overview;

import ee.tuleva.onboarding.auth.principal.Person;
import ee.tuleva.onboarding.epis.EpisService;
import ee.tuleva.onboarding.epis.cashflows.CashFlowStatementDto;
import ee.tuleva.onboarding.epis.cashflows.CashFlowValueDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class EpisAccountOverviewProvider implements AccountOverviewProvider {

    private static final BigDecimal EEK_TO_EUR_EXCHANGE_RATE = new BigDecimal("15.6466");

    private final EpisService episService;

    @Override
    public AccountOverview getAccountOverview(Person person, Instant startTime) {
        Instant endTime = Instant.now();
        CashFlowStatementDto cashFlowStatement = episService.getCashFlowStatement(person, startTime, endTime);
        return transformCashFlowStatementToAccountOverview(cashFlowStatement, startTime, endTime);
    }

    private AccountOverview transformCashFlowStatementToAccountOverview(CashFlowStatementDto cashFlowStatementDto, Instant startTime, Instant endTime) {
        BigDecimal beginningBalance = convertBalance(cashFlowStatementDto.getStartBalance());
        BigDecimal endingBalance = convertBalance(cashFlowStatementDto.getEndBalance());
        List<Transaction> transactions = convertTransactions(cashFlowStatementDto.getTransactions());

        return AccountOverview.builder()
                .beginningBalance(beginningBalance)
                .endingBalance(endingBalance)
                .transactions(transactions)
                .startTime(startTime)
                .endTime(endTime)
                .build();
    }

    private BigDecimal convertBalance(Map<String, CashFlowValueDto> balance) {
        return balance
                .values()
                .stream()
                .map(cashFlowValueDto -> convertCurrencyToEur(cashFlowValueDto.getAmount(), cashFlowValueDto.getCurrency()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private List<Transaction> convertTransactions(List<CashFlowValueDto> cashFlowValues) {
        return cashFlowValues
                .stream()
                .map(this::convertTransaction)
                .collect(Collectors.toList());
    }

    private Transaction convertTransaction(CashFlowValueDto cashFlowValue) {
        BigDecimal amount = convertCurrencyToEur(cashFlowValue.getAmount().negate(), cashFlowValue.getCurrency());
        return new Transaction(amount, cashFlowValue.getTime());
    }

    private BigDecimal convertCurrencyToEur(BigDecimal amount, String currency) {
        String uppercaseCurrency = currency.toUpperCase();
        if ("EUR".equals(uppercaseCurrency)) {
            return amount;
        } else if ("EEK".equals(uppercaseCurrency)) {
            return amount.divide(EEK_TO_EUR_EXCHANGE_RATE, MathContext.DECIMAL128);
        } else {
            log.error("Needed to convert currency other than EEK, statement will be invalid");
            return amount;
        }
    }
}

@@ -45,16 +45,127 @@
 rview;%0A%0A
+import com.fasterxml.jackson.core.JsonProcessingException;%0Aimport com.fasterxml.jackson.databind.ObjectMapper;%0A
 import e
@@ -1421,32 +1421,352 @@
 tant endTime) %7B%0A
+        log.info(%22Writing out balances%22); // TODO: remove this before prod release%0A        log.info(cashFlowStatementDto.toString());%0A        try %7B%0A            log.info(new ObjectMapper().writeValueAsString(cashFlowStatementDto));%0A        %7D catch (JsonProcessingException e) %7B%0A            e.printStackTrace();%0A        %7D%0A
         BigDecim

Add temp logging for account overview dto