package es.uv.dagarcos.master.repository;

import es.uv.dagarcos.master.domain.MasterEvent;
import es.uv.dagarcos.master.domain.PlayerGlobal;
import es.uv.dagarcos.master.domain.Shard;

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 java.time.Instant;
import java.util.List;

public interface MasterEventRepository extends JpaRepository<MasterEvent, Long> {

    List<MasterEvent> findByShard(Shard shard);

    List<MasterEvent> findByPlayer(PlayerGlobal player);

    List<MasterEvent> findByShardAndTimestampBetween(
            Shard shard,
            Instant from,
            Instant to
    );

    long count();

    long countByShard(Shard shard);

    @Query("""
        SELECT e.shard.id, COUNT(e)
        FROM MasterEvent e
        GROUP BY e.shard.id
    """)
    List<Object[]> countEventsPerShard();

    @Query("""
    SELECT 
        FUNCTION('date_trunc', 'minute', e.timestamp),
        COUNT(e)
    FROM MasterEvent e
    WHERE e.shard.externalId = :shardId
    GROUP BY FUNCTION('date_trunc', 'minute', e.timestamp)
    ORDER BY FUNCTION('date_trunc', 'minute', e.timestamp)
    """)
    List<Object[]> countEventsTimeSeries(@Param("shardId") String shardId);

    @Query(
        value = """
            SELECT e
            FROM MasterEvent e
            WHERE (:shard IS NULL OR e.shard.externalId = :shard)
              AND (:player IS NULL OR e.player.externalPlayerId = :player)
              AND (:action IS NULL OR e.action = :action)
        """,
        countQuery = """
            SELECT COUNT(e)
            FROM MasterEvent e
            WHERE (:shard IS NULL OR e.shard.externalId = :shard)
              AND (:player IS NULL OR e.player.externalPlayerId = :player)
              AND (:action IS NULL OR e.action = :action)
        """)
    Page<MasterEvent> findFiltered(@Param("shard") String shard, @Param("player") String player,
                                   @Param("action") String action, Pageable pageable);

}
