package com.eactive.eai.rms.onl.apim.portalstatistics;

import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.data.entity.onl.apim.portalstatistics.ApiStatisticsVO;
import com.eactive.eai.rms.data.entity.onl.apim.portalstatistics.PortalStatisticsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(transactionManager = "transactionManagerForEMS")
public class PortalStatisticsApiTableManService extends BaseService {

    private final PortalStatisticsService portalStatisticsService;

    public PortalStatisticsApiTableManService(PortalStatisticsService portalStatisticsService) {
        this.portalStatisticsService = portalStatisticsService;
    }

    public Map<String, Object> selectStatisticsList(LocalDate startDate, LocalDate endDate) {
        List<ApiStatisticsVO> stats = portalStatisticsService.getDetailedApiStatistics(startDate, endDate);

        Map<String, Object> result = new HashMap<>();
        result.put("summary", calculateSummary(stats));
        result.put("apiStats", convertToApiStats(stats));

        return result;
    }

    private Map<String, Object> calculateSummary(List<ApiStatisticsVO> stats) {
        Map<String, Object> summary = new HashMap<>();

        summary.put("totalApis", stats.stream().map(ApiStatisticsVO::getApiId).distinct().count());

        long totalRequests = stats.stream().mapToLong(ApiStatisticsVO::getRequestCount).sum();
        long totalFailures = stats.stream().mapToLong(ApiStatisticsVO::getFailureCount).sum();
        summary.put("totalRequests", totalRequests);
        summary.put("totalFailures", totalFailures);
        summary.put("overallSuccessRate", totalRequests > 0 ? (double) (totalRequests - totalFailures) / totalRequests * 100 : 0);

        List<String> topApis = stats.stream()
                .collect(Collectors.groupingBy(ApiStatisticsVO::getApiName, Collectors.summingLong(ApiStatisticsVO::getRequestCount)))
                .entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .limit(5)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        summary.put("topApis", topApis);

        return summary;
    }

    private List<Map<String, Object>> convertToApiStats(List<ApiStatisticsVO> stats) {
        Map<String, Map<String, Object>> apiStats = new LinkedHashMap<>();

        for (ApiStatisticsVO stat : stats) {
            Map<String, Object> apiStat = apiStats.computeIfAbsent(stat.getApiId(), k -> new LinkedHashMap<>());
            apiStat.put("apiName", stat.getApiName());
            apiStat.put("totalRequests", ((Long) apiStat.getOrDefault("totalRequests", 0L)) + stat.getRequestCount());
            apiStat.put("totalFailures", ((Long) apiStat.getOrDefault("totalFailures", 0L)) + stat.getFailureCount());
            // 일자별 통계는 사용하지 않습니다.
        }

        return apiStats.values().stream()
                .map(apiStat -> {
                    long totalRequests = (Long) apiStat.get("totalRequests");
                    long totalFailures = (Long) apiStat.get("totalFailures");
                    double successRate = totalRequests > 0 ? (double) (totalRequests - totalFailures) / totalRequests * 100 : 0;
                    apiStat.put("successRate", String.format("%.2f", successRate));
                    return apiStat;
                })
                .collect(Collectors.toList());
    }
}