package com.hdkj.lt.bf.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.esotericsoftware.minlog.Log;
import com.hdkj.fhzg.request.AutoTaskQueryPageRequest;
import com.hdkj.fhzg.request.AutoTaskQueryRequest;
import com.hdkj.fhzg.response.*;
import com.hdkj.hussar.ApiResponse;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.bf.entity.FhzgAutoTaskCountryInfo;
import com.hdkj.lt.bf.entity.FhzgAutoTaskFeederChange;
import com.hdkj.lt.bf.entity.FhzgAutoTaskPlan;
import com.hdkj.lt.bf.entity.FhzgAutoTaskPlanDetail;
import com.hdkj.lt.bf.service.*;
import com.hdkj.lt.core.bizms.modle.po.DwdShbDsFeederBase;
import com.hdkj.lt.feign.ISimulationPlatformApiClient;
import com.hdkj.lt.feign.IPlanCreateClient;
import com.hdkj.lt.modle.dto.plan.AcceptPlanPowerCutListRequest;
import com.hdkj.lt.modle.dto.simulation.ElectricalModelRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author rj
 * @date 2026/3/10 16:04
 * @description
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AutoTaskServiceImpl implements AutoTaskService {

    private final FhzgAutoTaskPlanService autoTaskPlanService;
    private final FhzgAutoTaskCountryInfoService autoTaskCountryInfoService;
    private final FhzgAutoTaskPlanDetailService autoTaskPlanDetailService;
    private final FhzgAutoTaskFeederChangeService autoTaskFeederChangeService;
    private final IPlanCreateClient planCreateClient;
    private final ISimulationPlatformApiClient simulationPlatformApiClient;
    private final FhzgElectricalModelSectionService electricalModelSectionService;

    // ==================== 电气模型采集线程池 ====================
    private static final ThreadPoolExecutor ELECTRICAL_MODEL_POOL = new ThreadPoolExecutor(
            10, 20, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(200),
            new ThreadFactory() {
                private int count = 0;
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "elec-model-" + (++count));
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    @Override
    public List<AutoTaskFeederResponse> getCountryStatistic(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskCountryInfo::getCityCode, request.getCityCode());
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskCountryInfo::getCountryCode, request.getCountryCode());
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        List<FhzgAutoTaskCountryInfo> list = autoTaskCountryInfoService.list(queryWrapper);
        List<AutoTaskFeederResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : list) {
            AutoTaskFeederResponse response = new AutoTaskFeederResponse();
            response.setCountryName(fhzgAutoTaskCountryInfo.getCountryName());
            response.setCountryCode(fhzgAutoTaskCountryInfo.getCountryCode());
            response.setFeederTotal(fhzgAutoTaskCountryInfo.getFeederTotal());
            response.setContactFeederTotal(fhzgAutoTaskCountryInfo.getContactFeederTotal());
            AutoTaskQueryRequest request1 = new AutoTaskQueryRequest();
            request1.setCountryCode(fhzgAutoTaskCountryInfo.getCountryCode());
            List<AutoTaskFeederChangeResponse> countryFeederChangeList = this.getCountryFeederChangeList(request1);
            response.setFeederTotalAdd((int) countryFeederChangeList.stream().filter(i -> i.getType() == 1).count());
            response.setFeederTotalDelete((int) countryFeederChangeList.stream().filter(i -> i.getType() == 0).count());
            response.setContactFeederTotalAdd((int) countryFeederChangeList.stream().filter(i -> i.getHaveContact() == 1 && i.getType() == 1).count());
            response.setContactFeederTotalDelete((int) countryFeederChangeList.stream().filter(i -> i.getHaveContact() == 1 && i.getType() == 0).count());
            responseList.add(response);
        }
        return responseList;
    }

    @Override
    public List<AutoTaskFeederChangeResponse> getCountryFeederChangeList(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskFeederChange> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskFeederChange::getCityCode, request.getCityCode());
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskFeederChange::getCountryCode, request.getCountryCode());
        queryWrapper.eq(request.getFeederType() != null && request.getFeederType() == 2, FhzgAutoTaskFeederChange::getType, 1);
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskFeederChange::getCreateTime, startTime, endTime);
        List<FhzgAutoTaskFeederChange> list = autoTaskFeederChangeService.list(queryWrapper);
        List<AutoTaskFeederChangeResponse> result = new ArrayList<>();
        for (FhzgAutoTaskFeederChange fhzgAutoTaskFeederChange : list) {
            AutoTaskFeederChangeResponse response = new AutoTaskFeederChangeResponse();
            response.setFeederId(fhzgAutoTaskFeederChange.getFeederId());
            response.setFeederName(fhzgAutoTaskFeederChange.getFeederName());
            response.setType(fhzgAutoTaskFeederChange.getType());
            response.setHaveContact(fhzgAutoTaskFeederChange.getIsHavaContact());
            result.add(response);
        }
        return result;
    }

    @Override
    public List<AutoTaskCityDetailResponse> getCityDetailList(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskCountryInfo::getCityCode, request.getCityCode());
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskCountryInfo::getCountryCode, request.getCountryCode());
        queryWrapper.orderByAsc(FhzgAutoTaskCountryInfo::getSimulationSuccessRate);
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        List<FhzgAutoTaskCountryInfo> list = autoTaskCountryInfoService.list(queryWrapper);
        List<AutoTaskCityDetailResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : list) {
            AutoTaskCityDetailResponse response = new AutoTaskCityDetailResponse();
            response.setCountryName(fhzgAutoTaskCountryInfo.getCountryName());
            response.setFeederTotal(fhzgAutoTaskCountryInfo.getFeederTotal());
            response.setContactFeederTotal(fhzgAutoTaskCountryInfo.getContactFeederTotal());
            response.setSimulationSuccess(fhzgAutoTaskCountryInfo.getSimulationSuccess());
            response.setSimulationSuccessRate(fhzgAutoTaskCountryInfo.getSimulationSuccessRate());
            response.setSchemeSuccess(fhzgAutoTaskCountryInfo.getSchemeSuccess());
            response.setSchemeSuccessRate(fhzgAutoTaskCountryInfo.getSchemeSuccessRate());
            response.setSvgSuccess(fhzgAutoTaskCountryInfo.getSvgSuccess());
            response.setSvgSuccessRate(fhzgAutoTaskCountryInfo.getSvgSuccessRate());
            responseList.add(response);
        }
        return responseList;
    }

    @Override
    public List<AutoTaskCountryDetailResponse> getCountryDetailList(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskPlanDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskPlanDetail::getCountryCode, request.getCountryCode());
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskPlanDetail::getCreateTime, startTime, endTime);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsHaveContact);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSimulationSuccess);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSchemeSuccess);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSvgSuccess);
        List<FhzgAutoTaskPlanDetail> list = autoTaskPlanDetailService.list(queryWrapper);
        List<AutoTaskCountryDetailResponse> result = new ArrayList<>();
        for (FhzgAutoTaskPlanDetail fhzgAutoTaskPlanDetail : list) {
            AutoTaskCountryDetailResponse response = new AutoTaskCountryDetailResponse();
            response.setFeederId(fhzgAutoTaskPlanDetail.getFeederId());
            response.setFeederName(fhzgAutoTaskPlanDetail.getFeederName());
            response.setCountryName(fhzgAutoTaskPlanDetail.getCountryName());
            response.setPlanNo(fhzgAutoTaskPlanDetail.getPlanNo());
            response.setCreateTime(fhzgAutoTaskPlanDetail.getCreateTime());
            response.setHaveContact(fhzgAutoTaskPlanDetail.getIsHaveContact());
            response.setSimulationSuccess(fhzgAutoTaskPlanDetail.getIsSimulationSuccess());
            response.setSchemeSuccess(fhzgAutoTaskPlanDetail.getIsSchemeSuccess());
            response.setSvgSuccess(fhzgAutoTaskPlanDetail.getIsSvgSuccess());
            result.add(response);
        }
        return result;
    }

    @Override
    public List<AutoTaskChartResponse> getCountryDetailChart(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskCountryInfo::getCountryCode, request.getCountryCode());
        if (request.getStartDate() == null || request.getEndDate() == null) {
            //如果没传时间就默认返回最近6个月的数据
            LocalDate startTime = LocalDate.now().minusMonths(6).withDayOfMonth(1);
            LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
            queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        } else {
            LocalDate startTime = request.getStartDate().atDay(1);
            LocalDate endTime = request.getEndDate().atEndOfMonth();
            queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        }

        queryWrapper.orderByAsc(FhzgAutoTaskCountryInfo::getUpdateTime);
        List<FhzgAutoTaskCountryInfo> list = autoTaskCountryInfoService.list(queryWrapper);
        List<AutoTaskChartResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : list) {
            AutoTaskChartResponse response = new AutoTaskChartResponse();
            response.setKey(fhzgAutoTaskCountryInfo.getUpdateTime().getYear() + "年" +
                    fhzgAutoTaskCountryInfo.getUpdateTime().getMonth().getValue() + "月");
            if (request.getChartType() == 1) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSimulationSuccessRate()));
            } else if (request.getChartType() == 2) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSchemeSuccessRate()));
            } else if (request.getChartType() == 3) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSvgSuccessRate()));
            }
            responseList.add(response);
        }
        return responseList;
    }


    @Override
    public List<AutoTaskChartResponse> getCityDetailChart(AutoTaskQueryRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskCountryInfo::getCityCode, request.getCityCode());
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskCountryInfo::getCountryCode, request.getCountryCode());
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        List<FhzgAutoTaskCountryInfo> list = autoTaskCountryInfoService.list(queryWrapper);
        List<AutoTaskChartResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : list) {
            AutoTaskChartResponse response = new AutoTaskChartResponse();
            response.setKey(fhzgAutoTaskCountryInfo.getCountryName());
            if (request.getChartType() == 1) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSimulationSuccessRate()));
            } else if (request.getChartType() == 2) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSchemeSuccessRate()));
            } else if (request.getChartType() == 3) {
                response.setValue(String.valueOf(fhzgAutoTaskCountryInfo.getSvgSuccessRate()));
            }
            responseList.add(response);
        }
        return responseList;
    }

    @Override
    public com.hdkj.fhzg.entity.Page<AutoTaskCityDetailResponse> getCityDetailPage(AutoTaskQueryPageRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskCountryInfo::getCityCode, request.getCityCode());
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
        queryWrapper.orderByAsc(FhzgAutoTaskCountryInfo::getSimulationSuccessRate);
        Page<FhzgAutoTaskCountryInfo> page = new Page<>();
        page.setCurrent(request.getCurrent());
        page.setSize(request.getSize());
        Page<FhzgAutoTaskCountryInfo> pageResult = autoTaskCountryInfoService.page(page, queryWrapper);
        List<AutoTaskCityDetailResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : pageResult.getRecords()) {
            AutoTaskCityDetailResponse response = new AutoTaskCityDetailResponse();
            response.setCountryName(fhzgAutoTaskCountryInfo.getCountryName());
            response.setFeederTotal(fhzgAutoTaskCountryInfo.getFeederTotal());
            response.setContactFeederTotal(fhzgAutoTaskCountryInfo.getContactFeederTotal());
            response.setSimulationSuccess(fhzgAutoTaskCountryInfo.getSimulationSuccess());
            response.setSimulationSuccessRate(fhzgAutoTaskCountryInfo.getSimulationSuccessRate());
            response.setSchemeSuccess(fhzgAutoTaskCountryInfo.getSchemeSuccess());
            response.setSchemeSuccessRate(fhzgAutoTaskCountryInfo.getSchemeSuccessRate());
            response.setSvgSuccess(fhzgAutoTaskCountryInfo.getSvgSuccess());
            response.setSvgSuccessRate(fhzgAutoTaskCountryInfo.getSvgSuccessRate());
            responseList.add(response);
        }
        com.hdkj.fhzg.entity.Page<AutoTaskCityDetailResponse> result = new com.hdkj.fhzg.entity.Page<>();
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        result.setRecords(responseList);
        result.setTotal(pageResult.getTotal());
        return result;
    }

    @Override
    public com.hdkj.fhzg.entity.Page<AutoTaskCountryDetailResponse> getCountryDetailPage(AutoTaskQueryPageRequest request) {
        LambdaQueryWrapper<FhzgAutoTaskPlanDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskPlanDetail::getCountryCode, request.getCountryCode());
        queryWrapper.eq(StringUtils.isNotBlank(request.getFeederId()), FhzgAutoTaskPlanDetail::getFeederId, request.getFeederId());
        queryWrapper.eq(StringUtils.isNotBlank(request.getPlanNo()), FhzgAutoTaskPlanDetail::getPlanNo, request.getPlanNo());
        queryWrapper.like(StringUtils.isNotBlank(request.getFeederName()), FhzgAutoTaskPlanDetail::getFeederName, request.getFeederName());
        LocalDateTime startTime = request.getStartTime() == null ? LocalDateTime.now().minusMonths(1) : request.getStartTime();
        LocalDateTime endTime = request.getEndTime() == null ? LocalDateTime.now() : request.getEndTime();
        queryWrapper.between(FhzgAutoTaskPlanDetail::getCreateTime, startTime, endTime);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsHaveContact);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSimulationSuccess);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSchemeSuccess);
        queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSvgSuccess);
        Page<FhzgAutoTaskPlanDetail> page = new Page<>();
        page.setCurrent(request.getCurrent());
        page.setSize(request.getSize());
        Page<FhzgAutoTaskPlanDetail> pageResult = autoTaskPlanDetailService.page(page, queryWrapper);
        List<AutoTaskCountryDetailResponse> responseList = new ArrayList<>();
        for (FhzgAutoTaskPlanDetail fhzgAutoTaskPlanDetail : pageResult.getRecords()) {
            AutoTaskCountryDetailResponse response = new AutoTaskCountryDetailResponse();
            response.setFeederId(fhzgAutoTaskPlanDetail.getFeederId());
            response.setFeederName(fhzgAutoTaskPlanDetail.getFeederName());
            response.setCountryName(fhzgAutoTaskPlanDetail.getCountryName());
            response.setPlanNo(fhzgAutoTaskPlanDetail.getPlanNo());
            response.setCreateTime(fhzgAutoTaskPlanDetail.getCreateTime());
            response.setHaveContact(fhzgAutoTaskPlanDetail.getIsHaveContact());
            response.setSimulationSuccess(fhzgAutoTaskPlanDetail.getIsSimulationSuccess());
            response.setSchemeSuccess(fhzgAutoTaskPlanDetail.getIsSchemeSuccess());
            response.setSvgSuccess(fhzgAutoTaskPlanDetail.getIsSvgSuccess());
            responseList.add(response);
        }
        com.hdkj.fhzg.entity.Page<AutoTaskCountryDetailResponse> result = new com.hdkj.fhzg.entity.Page<>();
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        result.setRecords(responseList);
        result.setTotal(pageResult.getTotal());
        return result;
    }

    @Override
    public void export(AutoTaskQueryPageRequest request, HttpServletResponse response) {
        if (!StringUtils.isEmpty(request.getCityCode())) {
            //导出地市统计数据
            LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(request.getCityCode()), FhzgAutoTaskCountryInfo::getCityCode, request.getCityCode());
            LocalDate startTime = LocalDate.now().minusMonths(1);
            LocalDate endTime = LocalDate.now();
            queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime, startTime, endTime);
            queryWrapper.orderByAsc(FhzgAutoTaskCountryInfo::getSimulationSuccessRate);
            List<FhzgAutoTaskCountryInfo> countryInfoList = autoTaskCountryInfoService.list(queryWrapper);
            List<AutoTaskCityDetailResponse> responseList = new ArrayList<>();
            for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : countryInfoList) {
                AutoTaskCityDetailResponse cityDetailResponse = new AutoTaskCityDetailResponse();
                cityDetailResponse.setCountryName(fhzgAutoTaskCountryInfo.getCountryName());
                cityDetailResponse.setFeederTotal(fhzgAutoTaskCountryInfo.getFeederTotal());
                cityDetailResponse.setContactFeederTotal(fhzgAutoTaskCountryInfo.getContactFeederTotal());
                cityDetailResponse.setSimulationSuccess(fhzgAutoTaskCountryInfo.getSimulationSuccess());
                cityDetailResponse.setSimulationSuccessRate(fhzgAutoTaskCountryInfo.getSimulationSuccessRate());
                cityDetailResponse.setSchemeSuccess(fhzgAutoTaskCountryInfo.getSchemeSuccess());
                cityDetailResponse.setSchemeSuccessRate(fhzgAutoTaskCountryInfo.getSchemeSuccessRate());
                cityDetailResponse.setSvgSuccess(fhzgAutoTaskCountryInfo.getSvgSuccess());
                cityDetailResponse.setSvgSuccessRate(fhzgAutoTaskCountryInfo.getSvgSuccessRate());
                responseList.add(cityDetailResponse);
            }
            String cityName = "";
            if (!countryInfoList.isEmpty()) {
                cityName = countryInfoList.get(0).getCityName();
            }
            try {
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("UTF-8");
                String fileName = cityName + "导出.xlsx";
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileName, "utf-8"));
                EasyExcel.write(response.getOutputStream(), AutoTaskCityDetailResponse.class)
                        .sheet()
                        .doWrite(responseList);
            } catch (Exception e) {
                Log.error("导出地市统计数据失败", e);
                throw new BusinessException("导出失败");
            }

        } else if (!StringUtils.isEmpty(request.getCountryCode())) {
            //导出区县数据
            LambdaQueryWrapper<FhzgAutoTaskPlanDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(request.getCountryCode()), FhzgAutoTaskPlanDetail::getCountryCode, request.getCountryCode());
            queryWrapper.eq(StringUtils.isNotBlank(request.getFeederId()), FhzgAutoTaskPlanDetail::getFeederId, request.getFeederId());
            queryWrapper.eq(StringUtils.isNotBlank(request.getPlanNo()), FhzgAutoTaskPlanDetail::getPlanNo, request.getPlanNo());
            queryWrapper.like(StringUtils.isNotBlank(request.getFeederName()), FhzgAutoTaskPlanDetail::getFeederName, request.getFeederName());
            queryWrapper.between(FhzgAutoTaskPlanDetail::getCreateTime, request.getStartTime(), request.getEndTime());
            queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsHaveContact);
            queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSimulationSuccess);
            queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSchemeSuccess);
            queryWrapper.orderByAsc(FhzgAutoTaskPlanDetail::getIsSvgSuccess);
            List<FhzgAutoTaskPlanDetail> detailList = autoTaskPlanDetailService.list(queryWrapper);
            List<AutoTaskCountryDetailResponse> responseList = new ArrayList<>();
            for (FhzgAutoTaskPlanDetail fhzgAutoTaskPlanDetail : detailList) {
                AutoTaskCountryDetailResponse detailResponse = new AutoTaskCountryDetailResponse();
                detailResponse.setFeederId(fhzgAutoTaskPlanDetail.getFeederId());
                detailResponse.setFeederName(fhzgAutoTaskPlanDetail.getFeederName());
                detailResponse.setCountryName(fhzgAutoTaskPlanDetail.getCountryName());
                detailResponse.setPlanNo(fhzgAutoTaskPlanDetail.getPlanNo());
                detailResponse.setCreateTime(fhzgAutoTaskPlanDetail.getCreateTime());
                detailResponse.setHaveContact(fhzgAutoTaskPlanDetail.getIsHaveContact());
                detailResponse.setSimulationSuccess(fhzgAutoTaskPlanDetail.getIsSimulationSuccess());
                detailResponse.setSchemeSuccess(fhzgAutoTaskPlanDetail.getIsSchemeSuccess());
                detailResponse.setSvgSuccess(fhzgAutoTaskPlanDetail.getIsSvgSuccess());
                responseList.add(detailResponse);
            }
            String countryName = "";
            if (!responseList.isEmpty()) {
                countryName = responseList.get(0).getCountryName();
            }
            try {
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("UTF-8");
                String fileName = countryName + "导出.xlsx";
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(fileName, "utf-8"));
                EasyExcel.write(response.getOutputStream(), AutoTaskCountryDetailResponse.class)
                        .sheet()
                        .doWrite(responseList);
            } catch (Exception e) {
                Log.error("导出地市统计数据失败", e);
                throw new BusinessException("导出失败");
            }
        } else {
            throw new BusinessException("地市编码为空");
        }
    }

    public String createTask(String cityCode) {
        //1.查询是否有对应的计划
        LocalDate startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        LocalDate endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        LambdaQueryWrapper<FhzgAutoTaskPlan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FhzgAutoTaskPlan::getCityCode, cityCode);
        queryWrapper.between(FhzgAutoTaskPlan::getCreateTime, startTime, endTime);
        List<FhzgAutoTaskPlan> list = autoTaskPlanService.list(queryWrapper);
        if (list.isEmpty()) {
            long snowflakeNextId = IdUtil.getSnowflakeNextId();
            FhzgAutoTaskPlan fhzgAutoTaskPlan = new FhzgAutoTaskPlan();
            fhzgAutoTaskPlan.setId(snowflakeNextId);
            fhzgAutoTaskPlan.setCityCode(cityCode);
            LocalDateTime now = LocalDateTime.now();
            fhzgAutoTaskPlan.setCreateTime(now);
            autoTaskPlanService.save(fhzgAutoTaskPlan);
            //查询对应地市的线路
            List<String> haveStartKgAndContactFeederList = autoTaskPlanService.getHaveStartKgAndContactFeederList(cityCode);
            List<DwdShbDsFeederBase> feederBaseList = autoTaskPlanService.getFeederInfoByCityCode(cityCode);
            Map<String, DwdShbDsFeederBase> feederSwitchBaseMap = feederBaseList.stream().collect(Collectors.toMap(DwdShbDsFeederBase::getPsrId, i -> i));
            List<FhzgAutoTaskPlanDetail> detailList = new ArrayList<>();
            haveStartKgAndContactFeederList.forEach(i -> {
                DwdShbDsFeederBase dwdShbDsFeederBase = feederSwitchBaseMap.get(i);
                FhzgAutoTaskPlanDetail fhzgAutoTaskPlanDetail = new FhzgAutoTaskPlanDetail();
                fhzgAutoTaskPlanDetail.setTaskId(snowflakeNextId);
                fhzgAutoTaskPlanDetail.setFeederId(i);
                fhzgAutoTaskPlanDetail.setFeederName(dwdShbDsFeederBase.getName());
                fhzgAutoTaskPlanDetail.setCityCode(dwdShbDsFeederBase.getCity());
                fhzgAutoTaskPlanDetail.setCityName(dwdShbDsFeederBase.getCityName());
                fhzgAutoTaskPlanDetail.setCountryCode(dwdShbDsFeederBase.getMaintOrg());
                fhzgAutoTaskPlanDetail.setCountryName(dwdShbDsFeederBase.getMaintOrgName());
                fhzgAutoTaskPlanDetail.setIsHaveContact(1);
                fhzgAutoTaskPlanDetail.setCreateTime(now);
                detailList.add(fhzgAutoTaskPlanDetail);
            });
            autoTaskPlanDetailService.saveBatch(detailList);
            return "创建成功";
        } else {
            return "已经创建";
        }
    }

    @Scheduled(cron = "0 0/2 * * * *")
    public void runTask() {
        LambdaQueryWrapper<FhzgAutoTaskPlanDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(FhzgAutoTaskPlanDetail::getPlanNo);
        List<FhzgAutoTaskPlanDetail> list = autoTaskPlanDetailService.list(queryWrapper);
        if (!list.isEmpty()) {
            FhzgAutoTaskPlanDetail fhzgAutoTaskPlanDetail = list.get(0);
            AcceptPlanPowerCutListRequest request = new AcceptPlanPowerCutListRequest();
            request.setStartTime(fhzgAutoTaskPlanDetail.getCreateTime());
            request.setEndTime(fhzgAutoTaskPlanDetail.getCreateTime().plusHours(2));
            request.setFeederList(Collections.singletonList(fhzgAutoTaskPlanDetail.getFeederId()));
            ApiResponse<String> stringApiResponse = planCreateClient.acceptPlanPowerCut(request);
            fhzgAutoTaskPlanDetail.setPlanNo(stringApiResponse.getMsg());
            autoTaskPlanDetailService.updateById(fhzgAutoTaskPlanDetail);
        }
    }

    @Scheduled(cron = "0 0 0 1 * ?")
    public void updateFeederStaticData(){
        List<FhzgAutoTaskCountryInfo> countryInfoList =  autoTaskCountryInfoService.getFeederStaticData();
        countryInfoList.forEach(i -> i.setUpdateTime(LocalDate.now()));
        autoTaskCountryInfoService.saveBatch(countryInfoList);
    }

    @Scheduled(cron = "0 0 0 * * ?")
    public void updatePlanStaticData(){
        LambdaQueryWrapper<FhzgAutoTaskCountryInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(FhzgAutoTaskCountryInfo::getUpdateTime,LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()),LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()));
        List<FhzgAutoTaskCountryInfo> list = autoTaskCountryInfoService.list(queryWrapper);
        for (FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo : list) {
            FhzgAutoTaskCountryInfo fhzgAutoTaskCountryInfo1 = autoTaskCountryInfoService.getPlanStaticData(fhzgAutoTaskCountryInfo.getCityCode(),fhzgAutoTaskCountryInfo.getCountryCode());
            fhzgAutoTaskCountryInfo.setSimulationSuccess(fhzgAutoTaskCountryInfo1.getSimulationSuccess());
            fhzgAutoTaskCountryInfo.setSimulationSuccessRate(fhzgAutoTaskCountryInfo1.getSimulationSuccessRate());
            fhzgAutoTaskCountryInfo.setSchemeSuccess(fhzgAutoTaskCountryInfo1.getSchemeSuccess());
            fhzgAutoTaskCountryInfo.setSchemeSuccessRate(fhzgAutoTaskCountryInfo1.getSchemeSuccessRate());
            fhzgAutoTaskCountryInfo.setSvgSuccess(fhzgAutoTaskCountryInfo1.getSvgSuccess());
            fhzgAutoTaskCountryInfo.setSvgSuccessRate(fhzgAutoTaskCountryInfo1.getSvgSuccessRate());
            fhzgAutoTaskCountryInfo.setUpdateTime(fhzgAutoTaskCountryInfo1.getUpdateTime());
            autoTaskCountryInfoService.updateById(fhzgAutoTaskCountryInfo);
        }
    }

    // ==================== 电气模型定时采集 ====================

    /** 最大重试次数 */
    private static final int MAX_RETRY = 3;
    /** 失败率阈值：超过此比例不触发后续计算 */
    private static final double FAIL_THRESHOLD = 1;

    /**
     * 定时采集电气模型数据（每15分钟）
     * 入口方法，可由定时任务或手动调用触发
     *
     * @param cityCode   地市编码
     * @param feederList 馈线ID列表
     */
    public void collectElectricalModel(String cityCode, List<String> feederList) {
        if (feederList == null || feederList.isEmpty()) {
            log.warn("电气模型采集-馈线列表为空, cityCode={}", cityCode);
            return;
        }

        log.info("电气模型采集-开始, cityCode={}, 馈线数={}", cityCode, feederList.size());
        long start = System.currentTimeMillis();

        // 1. 并发调用推演平台，每条馈线一个CompletableFuture
        List<CompletableFuture<String>> futures = new ArrayList<>();
        for (String feederId : feederList) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                return collectSingleFeederWithRetry(cityCode, feederId);
            }, ELECTRICAL_MODEL_POOL);
            futures.add(future);
        }

        // 2. 等待全部完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        // 3. 收集结果
        int successCount = 0;
        int failCount = 0;
        List<String> failedFeederIds = new ArrayList<>();

        for (int i = 0; i < futures.size(); i++) {
            String feederId = feederList.get(i);
            try {
                String jsonStr = futures.get(i).get();
                if (jsonStr != null) {
                    // 4. 入库
                    electricalModelSectionService.saveFromJson(jsonStr);
                    successCount++;
                } else {
                    failCount++;
                    failedFeederIds.add(feederId);
                }
            } catch (Exception e) {
                failCount++;
                failedFeederIds.add(feederId);
                log.error("电气模型采集-入库失败, feederId={}", feederId, e);
            }
        }

        long cost = System.currentTimeMillis() - start;
        double failRate = feederList.isEmpty() ? 0 : (double) failCount / feederList.size();

        log.info("电气模型采集-完成, cityCode={}, 成功={}, 失败={}, 耗时={}ms, 失败率={}",
                cityCode, successCount, failCount, cost, String.format("%.2f%%", failRate * 100));

        if (!failedFeederIds.isEmpty()) {
            log.warn("电气模型采集-失败馈线: {}", failedFeederIds);
        }

        // 5. 失败率过高则不触发后续计算
        if (failRate >= FAIL_THRESHOLD) {
            log.error("电气模型采集-失败率超过{}%, 不触发指标计算, cityCode={}", (int)(FAIL_THRESHOLD * 100), cityCode);
            return;
        }

        // 6. TODO: 发送MQ消息触发指标计算
        // rocketMQTemplate.sendAsyncMessage(...);
    }

    /**
     * 采集单条馈线（带重试）
     * @return 原始JSON字符串，失败返回null
     */
    private String collectSingleFeederWithRetry(String cityCode, String feederId) {
        for (int attempt = 1; attempt <= MAX_RETRY; attempt++) {
            try {
                ElectricalModelRequest request = new ElectricalModelRequest();
                request.setCityId(cityCode);
                request.setFeederList(Collections.singletonList(feederId));

                String jsonStr = simulationPlatformApiClient.getElectricalModel(request);
                if (jsonStr != null) {
                    log.debug("电气模型采集-成功, feederId={}, attempt={}", feederId, attempt);
                    return jsonStr;
                }
                log.warn("电气模型采集-返回null, feederId={}, attempt={}", feederId, attempt);
            } catch (Exception e) {
                log.warn("电气模型采集-调用异常, feederId={}, attempt={}/{}, error={}",
                        feederId, attempt, MAX_RETRY, e.getMessage());
            }
            // 递增等待: 1s, 3s, 5s
            if (attempt < MAX_RETRY) {
                try {
                    Thread.sleep(1000L * (2 * attempt - 1));
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    return null;
                }
            }
        }
        log.error("电气模型采集-重试耗尽, feederId={}", feederId);
        return null;
    }

}
