package com.common.service;



import com.common.entity.AlarmVisit;
import com.common.entity.GroupedSyslogData;
import com.common.mapper.SyslogNormalDataMapper;
import com.common.mapper.SyslogNormalAlarmMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.common.entity.Alarm;
import java.time.LocalDateTime;
import java.util.List;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@Slf4j
@Component
public class DataExtractor {

    @Autowired
    private SyslogNormalDataMapper syslogNormalDataMapper;
    @Autowired
    private SyslogNormalAlarmMapper syslogNormalAlarmMapper;
    @Autowired
    private DataTransformer dataTransformer;

    @Autowired
    private DataLoader dataLoader;

    @Value("${etl.batch.page-size:1000}")
    private int pageSize;


    /**
     * 抽取并处理指定时间范围内的分组访问日志数据
     */
    public void extractAndProcessQueryHoursGroupedData( String  strStartTime ,String strEndTime  ) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalDateTime endTime = LocalDateTime.parse(strEndTime, formatter);
        LocalDateTime startTime = LocalDateTime.parse(strStartTime, formatter);

        log.info("开始处理指定时间范围内访问日志数据，时间范围: {} - {}", startTime, endTime);

        try {
            // 获取分组数据总量
            Long totalGroups = syslogNormalDataMapper.count24HoursGroupedData(startTime, endTime);
            log.info("指定时间范围分组数据量: {} 组", totalGroups);

            if (totalGroups == 0) {
                log.info("没有需要处理的数据");
                return;
            }

            int totalPages = (int) Math.ceil((double) totalGroups / pageSize);
            long totalProcessed = 0;

            for (int page = 1; page <= totalPages; page++) {
                int offset = (page - 1) * pageSize;
                syslogNormalDataMapper.select24HoursGroupedDataByPage(
                        startTime, endTime, offset, pageSize);
                // 分页查询分组数据
              List<GroupedSyslogData> groupedDataList =
                        syslogNormalDataMapper.select24HoursGroupedDataByPage(
                                startTime, endTime, offset, pageSize);

                if (!groupedDataList.isEmpty()) {
                    // 转换并加载数据
                    List<AlarmVisit> alarmList = dataTransformer.transformGroupedDataVisit(groupedDataList);
                    //dataLoader.batchInsertAlarms(alarmList);
                    dataLoader.batchInsertAlarmVisits(alarmList);
                    totalProcessed += groupedDataList.size();
                    double progress = (double) totalProcessed / totalGroups * 100;
                    log.info("分组数据处理进度: {}/{} ({}%)",
                            totalProcessed, totalGroups, String.format("%.2f", progress));
                }

                // 内存管理
                if (page % 50 == 0) {
                    System.gc();
                    log.debug("执行GC清理内存");
                }
            }

            log.info("分组数据处理完成，共处理 {} 组数据", totalProcessed);

        } catch (Exception e) {
            log.error("访问日志数据抽取处理失败", e);
            throw new RuntimeException("ETL处理失败", e);
        }
    }
    /**
     * 抽取并处理指定时间范围内的分组告警类型数据
     */
    public void extractAndProcessQueryHoursAlarm( String  strStartTime ,String strEndTime  ) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime endTime = LocalDateTime.parse(strEndTime, formatter);
        LocalDateTime startTime = LocalDateTime.parse(strStartTime, formatter);

        log.info("开始处理告警类型指定时间范围内数据，时间范围: {} - {}", startTime, endTime);

        try {
            // 获取分组数据总量
            Long totalGroups = syslogNormalAlarmMapper.count24HoursGroupedData(startTime, endTime);
            log.info("指定时间范围分组数据量: {} 组", totalGroups);
            if (totalGroups == 0) {
                log.info("没有需要处理的数据");
                return;
            }

            int totalPages = (int) Math.ceil((double) totalGroups / pageSize);
            long totalProcessed = 0;

            for (int page = 1; page <= totalPages; page++) {
                int offset = (page - 1) * pageSize;
                syslogNormalAlarmMapper.select24HoursGroupedDataByPage(
                        startTime, endTime, offset, pageSize);
                // 分页查询分组数据
                List<GroupedSyslogData> groupedDataList =
                        syslogNormalAlarmMapper.select24HoursGroupedDataByPage(
                                startTime, endTime, offset, pageSize);

                if (!groupedDataList.isEmpty()) {
                    // 转换并加载数据
                    List<Alarm> alarmList = dataTransformer.transformGroupedData(groupedDataList);
                    dataLoader.batchInsertAlarms(alarmList);

                    totalProcessed += groupedDataList.size();
                    double progress = (double) totalProcessed / totalGroups * 100;
                    log.info("分组数据处理进度: {}/{} ({}%)",
                            totalProcessed, totalGroups, String.format("%.2f", progress));
                }

                // 内存管理
                if (page % 50 == 0) {
                    System.gc();
                    log.debug("执行GC清理内存");
                }
            }

            log.info("分组数据处理完成，共处理 {} 组数据", totalProcessed);

        } catch (Exception e) {
            log.error("告警日志数据抽取处理失败", e);
            throw new RuntimeException("ETL处理失败", e);
        }
    }
    /**
     * 抽取并处理24小时内分组数据
     */
    public void extractAndProcess24HoursGroupedData() {

        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusHours(24);

        log.info("开始处理24小时内数据，时间范围: {} - {}", startTime, endTime);

        try {
            // 获取分组数据总量
            Long totalGroups = syslogNormalDataMapper.count24HoursGroupedData(startTime, endTime);
            log.info("24小时内分组数据量: {} 组", totalGroups);

            if (totalGroups == 0) {
                log.info("没有需要处理的数据");
                return;
            }

            int totalPages = (int) Math.ceil((double) totalGroups / pageSize);
            long totalProcessed = 0;

            for (int page = 1; page <= totalPages; page++) {
                int offset = (page - 1) * pageSize;

                // 分页查询分组数据
                List<GroupedSyslogData> groupedDataList =
                        syslogNormalDataMapper.select24HoursGroupedDataByPage(
                                startTime, endTime, offset, pageSize);

                if (!groupedDataList.isEmpty()) {
                    // 转换并加载数据
                    List<Alarm> alarmList = dataTransformer.transformGroupedData(groupedDataList);
                    dataLoader.batchInsertAlarms(alarmList);

                    totalProcessed += groupedDataList.size();
                    double progress = (double) totalProcessed / totalGroups * 100;
                    log.info("分组数据处理进度: {}/{} ({:.2f}%)",
                            totalProcessed, totalGroups, progress);
                }

                // 内存管理
                if (page % 50 == 0) {
                    System.gc();
                    log.debug("执行GC清理内存");
                }
            }

            log.info("分组数据处理完成，共处理 {} 组数据", totalProcessed);

        } catch (Exception e) {
            log.error("数据抽取处理失败", e);
            throw new RuntimeException("ETL处理失败", e);
        }
    }
}