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

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

	private final PortalStatisticsService portalStatisticsService;

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

	public Map<String, Object> getInitialComboData() {
		Map<String, Object> result = new HashMap<>();
		result.put("appList", portalStatisticsService.getAppList());
		return result;
	}

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

		Map<String, Object> result = new HashMap<>();
		result.put("summary", calculateSummary(stats));
		result.put("dailyStats", convertToDailyStats(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());

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

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

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

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

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

		List<String> topApiNames = topApiIds.stream()
				.map(apiId -> stats.stream()
						.filter(s -> s.getApiId().equals(apiId))
						.findFirst()
						.map(ApiStatisticsVO::getApiName)
						.orElse("Unknown"))
				.collect(Collectors.toList());

		summary.put("topApis", topApiNames);

		return summary;
	}

	private List<Map<String, Object>> convertToDailyStats(List<ApiStatisticsVO> stats) {
		Map<String, Map<String, Object>> apiStats = new LinkedHashMap<>();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM.dd");

		for (ApiStatisticsVO stat : stats) {
			String apiName = stat.getApiName() != null ? stat.getApiName() : "Unknown";
			String date = LocalDate.parse(stat.getStatisticsTime(), DateTimeFormatter.ofPattern("yyyyMMdd")).format(formatter);

			Map<String, Object> apiStat = apiStats.computeIfAbsent(stat.getApiId(), k -> new LinkedHashMap<>());
			apiStat.putIfAbsent("apiName", apiName);
			apiStat.put(date, stat.getRequestCount());
		}

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