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.DailyAppStatisticsVO;
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.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

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

    private final PortalStatisticsService portalStatisticsService;

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

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

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

        return result;
    }

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

        summary.put("totalApps", stats.stream().map(DailyAppStatisticsVO::getAppId).distinct().count());

        LocalDate today = LocalDate.now();
        LocalDate sevenDaysAgo = today.minusDays(7);

        long totalRequests = stats.stream().mapToLong(DailyAppStatisticsVO::getRequestCount).sum();
        summary.put("monthlyRequests", totalRequests);

        long weeklyRequests = stats.stream()
                .filter(stat -> {
                    LocalDate statDate = LocalDate.parse(stat.getStatisticsDate(), DateTimeFormatter.ofPattern("yyyyMMdd"));
                    return !statDate.isBefore(sevenDaysAgo) && !statDate.isAfter(today);
                })
                .mapToLong(DailyAppStatisticsVO::getRequestCount)
                .sum();
        summary.put("weeklyRequests", weeklyRequests);

        long dailyRequests = stats.stream()
                .filter(stat -> stat.getStatisticsDate().equals(today.format(DateTimeFormatter.ofPattern("yyyyMMdd"))))
                .mapToLong(DailyAppStatisticsVO::getRequestCount)
                .sum();
        summary.put("dailyRequests", dailyRequests);

        List<String> topApps = stats.stream()
                .collect(Collectors.groupingBy(
                        stat -> Optional.ofNullable(stat.getAppName()).orElse("N/A"),
                        Collectors.summingLong(stat -> Optional.ofNullable(stat.getRequestCount()).orElse(0L))
                ))
                .entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .limit(5)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        summary.put("topApps", topApps);

        return summary;
    }

    private List<Map<String, Object>> convertToDailyStats(List<DailyAppStatisticsVO> stats) {
        Map<String, Map<String, Object>> appStats = new LinkedHashMap<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM.dd");

        for (DailyAppStatisticsVO stat : stats) {
            String date = LocalDate.parse(stat.getStatisticsDate(), DateTimeFormatter.ofPattern("yyyyMMdd")).format(formatter);

            Map<String, Object> appStat = appStats.computeIfAbsent(stat.getAppId(), k -> new LinkedHashMap<>());
            appStat.put("appName", Optional.ofNullable(stat.getAppName()).orElse("N/A"));
            appStat.put(date, stat.getRequestCount());
        }

        return new ArrayList<>(appStats.values());
    }
}