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

import com.eactive.apim.portal.portalstatistics.entity.PortalStatistics;
import com.eactive.apim.portal.portalstatistics.entity.PortalStatisticsId;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.data.entity.onl.apim.portalstatistics.PortalStatisticsService;
import com.eactive.eai.rms.data.entity.onl.apim.portalstatistics.PortalStatisticsVO;
import com.eactive.eai.rms.data.entity.onl.logger.EAILogService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

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

    private final PortalStatisticsService portalStatisticsService;
    private final EAILogService eaiLogService;

    public PortalStatisticsManService(PortalStatisticsService portalStatisticsService, EAILogService eaiLogService) {
        this.portalStatisticsService = portalStatisticsService;
        this.eaiLogService = eaiLogService;
    }

    public Map<String, Object> createTenMinuteData(PortalStatisticsUI portalStatisticsUI) {
        DataSourceType apigwDataSourceType = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW);
        DataSourceContextHolder.setDataSourceType(apigwDataSourceType);

        HashMap<String, Object> logQueryParams = createLogQueryParams(portalStatisticsUI, apigwDataSourceType);
        List<PortalStatisticsVO> portalStatisticsData = eaiLogService.selectLogList(logQueryParams);

        if (portalStatisticsData.isEmpty()) {
            return createResultMap(true, "해당 기간에 로그 데이터가 존재하지 않습니다.", false, null);
        }

        DataSourceContextHolder.setDataSourceType(
            DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING));

        List<PortalStatistics> savedStatistics = convertAndSaveStatistics(portalStatisticsData);

        return createResultMap(true, "데이터가 성공적으로 저장되었습니다.", true, savedStatistics.size());
    }

    private HashMap<String, Object> createLogQueryParams(PortalStatisticsUI portalStatisticsUI, DataSourceType dataSourceType) {
        String startTime = portalStatisticsUI.getStartDate();
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
        LocalDateTime endDateTime = startDateTime.plusMinutes(10);
        String endTime = endDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
        String yyyymmdd = startTime.substring(0, 8);

        HashMap<String, Object> params = new HashMap<>();
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        params.put("tableName", CommonUtil.getLogTable(yyyymmdd, true));
        params.put("schemaId", dataSourceType.getSchema());

        return params;
    }

    private List<PortalStatistics> convertAndSaveStatistics(List<PortalStatisticsVO> portalStatisticsData) {
        List<PortalStatistics> portalStatistics = portalStatisticsData.stream()
            .map(this::convertToEntity)
            .collect(Collectors.toList());

        return portalStatisticsService.saveAll(portalStatistics);
    }

    public PortalStatistics convertToEntity(PortalStatisticsVO portalStatisticsVO) {
        PortalStatistics portalStatistics = new PortalStatistics();
        PortalStatisticsId portalStatisticsId = new PortalStatisticsId(
            portalStatisticsVO.getClientId(),
            portalStatisticsVO.getRequestUri(),
            portalStatisticsVO.getStatisticsTime(),
            portalStatisticsVO.getApiId());

        portalStatistics.setId(portalStatisticsId);
        portalStatistics.setRoutingUri(portalStatisticsVO.getRoutingUri());

        portalStatistics.setApiName(portalStatisticsVO.getApiName());

        portalStatistics.setAppId(portalStatisticsVO.getAppId());
        portalStatistics.setAppName(portalStatisticsVO.getAppName());
        portalStatistics.setOrgId(portalStatisticsVO.getOrgId());
        portalStatistics.setOrgName(portalStatisticsVO.getOrgName());

        portalStatistics.setRequestCount(portalStatisticsVO.getRequestCount());
        portalStatistics.setFailureCount(portalStatisticsVO.getFailureCount());

        return portalStatistics;
    }

    public List<PortalStatisticsVO> selectLogData(DataSourceType dt, PortalStatisticsUI portalStatisticsUI) {
        HashMap<String, Object> paramMap = new HashMap<>();
        String startTime = portalStatisticsUI.getStartDate();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = startDateTime.plusMinutes(10);

        String endTime = endDateTime.format(formatter);
        String yyyymmdd = startTime.substring(0, 8);

        paramMap.put("startTime", startTime);
        paramMap.put("endTime", endTime);

        String tableName = CommonUtil.getLogTable(yyyymmdd, true);
        paramMap.put("tableName", tableName);
        paramMap.put("schemaId", dt.getSchema());

        return eaiLogService.selectLogList(paramMap);
    }

    private Map<String, Object> createResultMap(boolean success, String message, boolean dataExists, Integer count) {
        Map<String, Object> result = new HashMap<>();
        result.put("success", success);
        result.put("message", message);
        result.put("dataExists", dataExists);
        if (count != null) {
            result.put("count", count);
        }
        return result;
    }

}
