package es.uv.dagarcos.master.service;

import es.uv.dagarcos.master.dto.DashboardSummaryDto;
import es.uv.dagarcos.master.dto.ShardEventTimeSeriesDto;
import es.uv.dagarcos.master.dto.ShardOverviewDto;
import es.uv.dagarcos.master.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ShardDashboardService {

    @Autowired
    private ShardRepository shardRepository;

    @Autowired
    private MasterEventRepository eventRepository;

    @Autowired
    private ShardPlayerStatsRepository statsRepository;

    @Autowired
    private PlayerGlobalRepository playerRepository;


    public List<ShardOverviewDto> getShardOverview() {

        Map<Long, Long> eventsByShard = new HashMap<>();
        for (Object[] row : eventRepository.countEventsPerShard()) {
            eventsByShard.put((Long) row[0], (Long) row[1]);
        }

        Map<Long, Long> playersByShard = new HashMap<>();
        for (Object[] row : statsRepository.countPlayersPerShard()) {
            playersByShard.put((Long) row[0], (Long) row[1]);
        }

        return shardRepository.findAll().stream()
                .map(shard -> new ShardOverviewDto(
                        shard.getExternalId(),
                        shard.getName(),
                        shard.getLocation(),
                        shard.getStatus().name(),
                        shard.getLastHeartbeat(),
                        eventsByShard.getOrDefault(shard.getId(), 0L),
                        playersByShard.getOrDefault(shard.getId(), 0L)
                ))
                .toList();
    }

    public DashboardSummaryDto getSummary() {

        Instant activeThreshold = Instant.now().minusSeconds(30);

        return new DashboardSummaryDto(
                shardRepository.count(),
                playerRepository.count(),
                eventRepository.count(),
                shardRepository.countActiveShards(activeThreshold)
        );
    }

    public List<ShardEventTimeSeriesDto> getEventTimeSeries(String shardId) {
            return eventRepository
                    .countEventsTimeSeries(shardId)
                    .stream()
                    .map(row -> new ShardEventTimeSeriesDto(
                            (Instant) row[0],
                            (Long) row[1]
                    ))
                    .toList();
        }
}