package de.cannamanage.service.repository;

import de.cannamanage.domain.entity.LedgerEntry;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

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

@Repository
public interface LedgerEntryRepository extends JpaRepository<LedgerEntry, UUID> {

    Page<LedgerEntry> findByClubIdAndTransactionDateBetween(UUID clubId, LocalDate from, LocalDate to, Pageable pageable);

    List<LedgerEntry> findByClubIdAndTransactionDateBetween(UUID clubId, LocalDate from, LocalDate to);

    @Query("SELECT COALESCE(SUM(le.amountCents), 0) FROM LedgerEntry le " +
           "WHERE le.clubId = :clubId AND le.category = :category " +
           "AND le.transactionDate >= :from AND le.transactionDate <= :to")
    Long sumByClubIdAndCategoryAndDateRange(@Param("clubId") UUID clubId,
                                            @Param("category") String category,
                                            @Param("from") LocalDate from,
                                            @Param("to") LocalDate to);

    @Query("SELECT COALESCE(SUM(CASE WHEN le.transactionType = 'INCOME' THEN le.amountCents ELSE 0 END), 0) " +
           "FROM LedgerEntry le WHERE le.clubId = :clubId " +
           "AND le.transactionDate >= :from AND le.transactionDate <= :to")
    Long sumIncomeByClubAndDateRange(@Param("clubId") UUID clubId,
                                     @Param("from") LocalDate from,
                                     @Param("to") LocalDate to);

    @Query("SELECT COALESCE(SUM(CASE WHEN le.transactionType = 'EXPENSE' THEN le.amountCents ELSE 0 END), 0) " +
           "FROM LedgerEntry le WHERE le.clubId = :clubId " +
           "AND le.transactionDate >= :from AND le.transactionDate <= :to")
    Long sumExpensesByClubAndDateRange(@Param("clubId") UUID clubId,
                                       @Param("from") LocalDate from,
                                       @Param("to") LocalDate to);

    @Query("SELECT COALESCE(SUM(CASE WHEN le.transactionType = 'INCOME' THEN le.amountCents " +
           "ELSE -le.amountCents END), 0) FROM LedgerEntry le " +
           "WHERE le.clubId = :clubId AND le.transactionDate <= :asOf")
    Long calculateBalance(@Param("clubId") UUID clubId, @Param("asOf") LocalDate asOf);
}
