package com.example.FinanceTracker.Services;

import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.example.FinanceTracker.DTOs.GroupedTransaction;
import com.example.FinanceTracker.DTOs.QuartlyTotals;
import com.example.FinanceTracker.Models.Transaction;
import com.example.FinanceTracker.Repo.TransactionRepo;

@Service
public class TransactionService {

    @Autowired
    private TransactionRepo transactionRepo;

    public List<Transaction> findAll() {
        return transactionRepo.findAll();
    }

    public Page<Transaction> findAllPaged(int pageNum, int pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return transactionRepo.findAllPaged(pageable);
    }

    public void save(Transaction transaction) {
        transactionRepo.save(transaction);
    }

    public void saveAll(List<Transaction> transactions) {
        transactions.forEach(t -> save(t));
    }

    public Transaction findById(UUID id) {
        return transactionRepo.findById(id).orElseThrow(() -> new RuntimeException("no transaction with id " + id));
    }

    public Page<Transaction> getTransactionsBetween(int pageNum, int pageSize, LocalDate fromDate, LocalDate toDate) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return transactionRepo.getTransactionsBetween(pageable, fromDate, toDate);
    }

    // Search
    public Page<Transaction> searchTransactions(String searchValue, int pageNum, int pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return transactionRepo.searchTransactions(pageable, searchValue);
    }

    public double getLatestBalance(){
        return transactionRepo.getLatestBalance();
    }

    // =============================================================
    // MONEY IN
    // =============================================================
    public double getTotalMoneyIn() {
        return transactionRepo.getTotalMoneyIn();
    }

    public double getTotalMoneyInByYear(int year) {
        return transactionRepo.getTotalMoneyInByYear(year);
    }

    public double getAverageMonthlyMoneyIn(int year) {
        return transactionRepo.getAverageMonthlyMoneyIn(year);
    }

    public List<GroupedTransaction> getIncomeGroupedTransactions() {
        return transactionRepo.getIncomeGroupedTransactions();
    }

    // =============================================================
    // MONEY OUT
    // =============================================================

    public double getTotalMoneyOut() {
        return transactionRepo.getTotalMoneyIn();
    }

    public double getTotalMoneyOutByYear(int year) {
        return transactionRepo.getTotalMoneyInByYear(year);
    }

    public double getAverageMonthlyMoneyOut(int year) {
        return transactionRepo.getAverageMonthlyMoneyOut(year);
    }

    public List<GroupedTransaction> getExpenditureGroupedTransactions() {
        return transactionRepo.getExpenditureGroupedTransactions();
    }

    // =============================================================
    // INTEREST
    // =============================================================
    public double averageMonthlyInterest(int year) {
        return transactionRepo.averageMonthlyInterest(year);
    }

    // Interest
    public double getTotalInterest() {
        return transactionRepo.getTotalInterest();
    }

    // =============================================================
    // FEES
    // =============================================================
    public double getTotalFeesByYear(int year) {
        return transactionRepo.getTotalFeesByYear(year);
    }

    public double getTotalFees(){
        return transactionRepo.getTotalFees();
    }

    // =============================================================
    // Other
    // =============================================================


    public List<Object[]> getTotals() {
        return transactionRepo.getTotals();
    }

    public List<QuartlyTotals> getQuarterlyTotals(int year){
        return transactionRepo.getQuarterlyTotals(year);
    }

    public double getNetCashflow(){
        return transactionRepo.getNetCashflow();
    }

    public double getSavingRate(){
        return transactionRepo.getSavingRate();
    }

}
