package ru.soune.nocopy.repository;

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 ru.soune.nocopy.entity.tokenoperation.OperationType;
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;

import java.util.List;

@Repository
public interface TokenOperationRepository extends JpaRepository<TokenOperation, Long> {
    Page<TokenOperation> findAll(Pageable pageable);

    List<TokenOperation> findByUserId(Long userId);

    Page<TokenOperation> findByUserId(Long userId, Pageable pageable);

    Page<TokenOperation> findByOperationType(OperationType operationType, Pageable pageable);

    @Query("SELECT t FROM TokenOperation t WHERE " +
            "(:userId IS NULL OR t.userId = :userId) AND " +
            "(:operationType IS NULL OR t.operationType = :operationType) AND " +
            "(:minSpent IS NULL OR t.spent >= :minSpent) AND " +
            "(:maxSpent IS NULL OR t.spent <= :maxSpent)")
    Page<TokenOperation> findByFilters(
            @Param("userId") Long userId,
            @Param("operationType") OperationType operationType,
            @Param("minSpent") Long minSpent,
            @Param("maxSpent") Long maxSpent,
            Pageable pageable
    );

    @Query("SELECT SUM(t.spent) FROM TokenOperation t WHERE t.userId = :userId AND t.operationType = :operationType")
    Long sumSpentByUserAndType(@Param("userId") Long userId, @Param("operationType") OperationType operationType);

    Long countByUserId(Long userId);

    @Query("""
        SELECT COALESCE(SUM(t.spent), 0)
        FROM TokenOperation t
    """)
    Long getTotalTokensSpent();

    @Query("""
        SELECT 
            t.userId,
            COALESCE(SUM(t.spent), 0)
        FROM TokenOperation t
        GROUP BY t.userId
    """)
    List<Object[]> getTokensSpentPerUser();
}
