package com.example.FinanceTracker.Services;

import java.time.LocalDate;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;

import com.example.FinanceTracker.DTOs.Investments.CurrRate;
import com.example.FinanceTracker.DTOs.Investments.Currency;
import com.example.FinanceTracker.DTOs.Investments.ExchangeRate;

@Service
public class InvestmentService {

    @Autowired
    private RestClient restClient;

    private final int WEEK = 1;
    private final int MONTH = 2;
    private final int YEAR = 3;

    public List<CurrRate> getCurrRates() {
        return List.of("EUR", "USD", "JPY", "GBP", "CAD", "AUD").stream()
                .map(code -> {
                    Double rate = restClient.get()
                            .uri(uriBuilder -> uriBuilder
                                    .path("/exchangeRate/pair")
                                    .queryParam("from", code)
                                    .queryParam("to", "ZAR")
                                    .build())
                            .retrieve()
                            .body(Double.class);

                    return new CurrRate(code, rate.toString(), getChange(code, "ZAR"));
                })
                .toList();
    }

    private String getChange(String targetCurr, String desiredCurrency) {

        final String effectiveTargetCurr = targetCurr.toUpperCase().contains("USD") ? "ZAR" : targetCurr;

        List<ExchangeRate> exchangeRate = restClient.get()
                .uri(uriBuilder -> uriBuilder
                        .path("exchangeRate/historical")
                        .queryParam("targetCurrency", effectiveTargetCurr)
                        .queryParam("desiredCurrency", desiredCurrency)
                        .queryParam("fromDate", LocalDate.now().minusDays(1))
                        .queryParam("toDate", LocalDate.now().plusDays(1))
                        .build())
                .retrieve()
                .body(new ParameterizedTypeReference<List<ExchangeRate>>() {
                });

        int changeFactor = exchangeRate.get(0).getRate().compareTo(exchangeRate.get(1).getRate());

        if (changeFactor > 0) {
            return "UP";
        } else if (changeFactor < 0) {
            return "DOWN";
        }else {
            return "NEUTRAL";
        }

    }

    public List<ExchangeRate> getHistoricalRates(String targetCurr, int duration) {

        LocalDate toDate = LocalDate.now().plusDays(1);
        LocalDate fromDate;

        switch (duration) {
            case WEEK:
                fromDate = LocalDate.now().minusWeeks(1);
                break;
            case MONTH:
                fromDate = LocalDate.now().minusMonths(1);
                break;
            case YEAR:
                fromDate = LocalDate.now().minusYears(1);
                break;
            default:
                fromDate = LocalDate.now().minusWeeks(1);
        }

        List<ExchangeRate> historicalRates = restClient.get()
                .uri(uriBuilder -> uriBuilder
                        .path("exchangeRate/historical")
                        .queryParam("targetCurrency", targetCurr)
                        .queryParam("desiredCurrency", "ZAR")
                        .queryParam("fromDate", fromDate.toString())
                        .queryParam("toDate", toDate.toString())
                        .build())
                .retrieve()
                .body(new ParameterizedTypeReference<List<ExchangeRate>>() {
                });

        

        return historicalRates;
    }

    public List<Currency> getAllCurrencies() {

        return restClient.get()
                .uri("/currency/currencies")
                .retrieve()
                .body(new ParameterizedTypeReference<List<Currency>>() {
                });
    }

}
