package com.caliverse.admin.logs.logservice.indicators;

import com.caliverse.admin.Indicators.Indicatordomain.IndicatorsLog;
import com.caliverse.admin.Indicators.entity.DBCapacityInfo;
import com.caliverse.admin.Indicators.indicatorrepository.IndicatorDBCapacityRepository;
import com.caliverse.admin.domain.service.DynamoDBMetricsService;
import com.caliverse.admin.global.common.constants.DynamoDBConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.services.cloudwatch.model.GetMetricDataResponse;
import software.amazon.awssdk.services.cloudwatch.model.MetricDataResult;

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

@Slf4j
@Service
public class IndicatorsDBCapacityService {

    @Autowired private IndicatorDBCapacityRepository capacityRepository;
    @Autowired private DynamoDBMetricsService dynamoDBMetricsService;

    public void collectDBCapacity(String startTime, String endTime){
        GetMetricDataResponse response = dynamoDBMetricsService.getConsumedCapacityData(Instant.parse(startTime), Instant.parse(endTime));

        try {
            Map<String, Long> dailyReadCapacity = new HashMap<>();
            Map<String, Long> dailyWriteCapacity = new HashMap<>();

            for (MetricDataResult result : response.metricDataResults()) {
                for (int i = 0; i < result.timestamps().size(); i++) {
                    String date = result.timestamps().get(i)
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate()
                            .toString();

                    double value = result.values().get(i);

                    if (result.id().equals("readCapacity")) {
                        dailyReadCapacity.merge(date, Math.round(value), Long::sum);
                    } else if (result.id().equals("writeCapacity")) {
                        dailyWriteCapacity.merge(date, Math.round(value), Long::sum);
                    }
                }
            }

            dailyReadCapacity.forEach((date, readTotal) -> {
                var writeTotal = dailyWriteCapacity.getOrDefault(date, 0L);
                var capacityInfo = new DBCapacityInfo(date, DynamoDBConstants.NAMESPACE, readTotal, writeTotal);
                log.info("collectDBCapacity DBCapacity Log Save info: {}", capacityInfo);
                saveStatLogData(capacityInfo);
            });
        }catch (Exception e){
            log.error("collectUserPlayTime Error Message: {}", e.getMessage());
        }
    }

    public void saveStatLogData(IndicatorsLog indicatorsLog) {

        if (indicatorsLog instanceof DBCapacityInfo capacityInfo) {
            try {
                capacityRepository.save(capacityInfo);
            } catch (Exception e) {
                log.error("saveStatLogData: {}", e.getMessage());
            }
        } else {
            log.error("Not instanceof IndicatorsLog");
        }
    }
}
