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

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.hdkj.hussar.ApiResponse;
import com.hdkj.lt.core.plugins.thread.MultiThreadExecuteService;
import com.hdkj.lt.feign.IPsrDeviceApiClient;
import com.hdkj.lt.job.service.IDealPsrDeviceService;
import com.hdkj.lt.job.service.IPsrDeviceSaveService;
import com.hdkj.lt.job.util.JobUtils;
import com.hdkj.lt.modle.dto.psrdevice.JoinEcTransformerDTO;
import com.hdkj.lt.modle.dto.psrdevice.PsrDeviceFilterDTO;
import com.hdkj.lt.modle.dto.psrdevice.PsrDeviceQueryDTO;
import com.hdkj.lt.modle.po.DistDeviceJoinEcPO;
import com.hdkj.lt.modle.po.JoinEcTransformerPO;
import com.hdkj.lt.modle.vo.psrdevice.PsrDeviceCommonVO;
import com.hdkj.lt.modle.vo.psrdevice.PsrDeviceResponseVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author wcx
 * @Date 2025/7/30 15:13
 * @Version 1.0
 */
@Service
@RequiredArgsConstructor
public class DealPsrDeviceServiceImpl implements IDealPsrDeviceService {

    private final IPsrDeviceApiClient psrDeviceApiClient;

    private final IPsrDeviceSaveService psrDeviceSaveService;

    private final MultiThreadExecuteService multiThreadExecute;

    @Value("${hussar.psr.device.max-query-size:500}")
    private Integer maxQuerySize; // 电网资源业务中台最大查询数
    @Value("${hussar.psr.device.max-save-size:100}")
    private Integer maxSaveSize; // 设备台账批量最大数

    @Override
    public void saveJoinEcTransformerInfo(String cityShort) {
        // 开启线程 处理保存中压接入点和专变数据，主要防止等待时间过程导致hussar-job报莫名错误
        CompletableFuture.runAsync(() -> {
            List<String> cityList = this.getCityListByShort(cityShort);
            // 先批量处理中压用户接入点的数据
            this.dealPsrDeviceJoinEcData(cityList, maxQuerySize);
            // 接入点和专变接口慢，这里单独处理中压接入点和专变，根据最大保存数设置查询数量
            this.saveJoinEcTransformerData(maxSaveSize);
        }, multiThreadExecute.getExecutor());
    }

    @Override
    public void dealFeederSpanSegmentBak() {
        // 先删后增DI同步之前的馈线和档距段台账信息
        psrDeviceSaveService.savePsrDeviceDIBeforeBak();
    }

    @Override
    public void dealFeederSpanSegmentSupply() {
        // 更新馈线台账信息转义字段信息
        psrDeviceSaveService.updateFeederDIAfter();
        // 更新T_PSR_DS_FEEDER拓扑解析需要的线段信息
        psrDeviceSaveService.updateFeederPsrDevice();
        // 更新档距段台账信息转义字段信息
        psrDeviceSaveService.updateSpanSegmentDIAfter();
    }

    @Override
    public void saveSegmentPsrDeviceInfo(String cityShort) {
        // 开启线程 处理导线和电缆段数据， 主要防止等待时间过程导致hussar-job报莫名错误
        CompletableFuture.runAsync(() -> {
            List<String> cityList = this.getCityListByShort(cityShort);
            // 处理电缆段台账信息
            this.dealPsrDeviceDataCommon(cityList, "0201", maxQuerySize);
            // 处理导线台账信息
            this.dealPsrDeviceDataCommon(cityList, "0101", maxQuerySize);
            // 更新T_PSR_DS_DX拓扑解析需要的线段信息, 数据量大时直接mysql执行不需要等待结果
            CompletableFuture.runAsync(() -> psrDeviceSaveService.updateSegmentPsrDevice());
        }, multiThreadExecute.getExecutor());
    }


    /**
     * 获取地市ID信息根据传递地市简称
     */
    private List<String> getCityListByShort(String cityShort) {
        // 定时任务参数 地市简称
        List<String> cityShortlist = Arrays.asList(cityShort.split("-"));
        List<String> cityList = psrDeviceSaveService.getConfigCityInfo(cityShortlist);
        return cityList;
    }

    /**
     * 处理中压接入点的数据获取
     */
    private void dealPsrDeviceJoinEcData(List<String> cityList, Integer batchSize) {
        PsrDeviceQueryDTO psrDeviceQuery = new PsrDeviceQueryDTO();
        psrDeviceQuery.setPsrType("370000").setDistribution(0); // 设置中压接入点类型和主配网标识
        psrDeviceQuery.getParams().setSize(batchSize); // 设置分页大小
        if (ObjectUtils.isNotEmpty(cityList)) {
            // 添加过滤条件
            List<PsrDeviceFilterDTO> filters = psrDeviceQuery.getParams().getFilters();
            filters.add(PsrDeviceFilterDTO.builder().compare("in").fieldName("city")
                    .fieldValue(cityList.stream().collect(Collectors.joining(","))).build());
            // 设置查询的过滤条件
            psrDeviceQuery.getParams().setFilters(filters);
        }
        // 获取第一页的数据并且确定总页数
        ApiResponse<PsrDeviceResponseVO> psrDeviceResponse = psrDeviceApiClient.getPsrDeviceByCommonInterface(psrDeviceQuery);
        Optional.ofNullable(psrDeviceResponse).filter(e -> ObjectUtils.isNotEmpty(e.getData())).ifPresent(e -> {
            // 处理中压接入点和中压接入点专变的数据
            this.dealPsrDeviceJoinEcAndTransformerData(e.getData());
            Integer pages = e.getData().getPages(); // 中压接入点总页数
            // 分页获取剩余的数据（从第二页开始）
            for (int page = 2; page <= pages; page++) {
                psrDeviceQuery.getParams().setCurrent(page); // 设置当前页数
                ApiResponse<PsrDeviceResponseVO> deviceResponse = psrDeviceApiClient.getPsrDeviceByCommonInterface(psrDeviceQuery);
                Optional.ofNullable(deviceResponse).filter(en -> ObjectUtils.isNotEmpty(en.getData()))
                        .ifPresent(en -> this.dealPsrDeviceJoinEcAndTransformerData(en.getData()));
            }
        });
    }

    /**
     * 处理中压接入点和中压接入点专变的数据（接入点专变接口响应慢，弃用一个查询数量配置）
     */
    private void dealPsrDeviceJoinEcAndTransformerData(PsrDeviceResponseVO psrDeviceResponse) {
        List<PsrDeviceCommonVO> psrDeviceList = psrDeviceResponse.getRecords();
        if (ObjectUtils.isNotEmpty(psrDeviceList)) {
            try {
                // 处理中压接入点数据
                List<DistDeviceJoinEcPO> joinEcList = psrDeviceList.stream()
                        .filter(e -> ObjectUtils.isNotEmpty(e))
                        .map(e -> {
                            Map<String, Object> dataMap = e.getResource();
                            dataMap.putAll(Optional.ofNullable(e.getAssets()).map(en -> en.get(0)).orElse(MapUtil.newHashMap()));
                            DistDeviceJoinEcPO distDeviceJoinEcPO = JSON.parseObject(JSON.toJSONString(dataMap), DistDeviceJoinEcPO.class);
                            return distDeviceJoinEcPO;
                        }).collect(Collectors.toList());
                Optional.ofNullable(joinEcList).filter(e -> ObjectUtils.isNotEmpty(e))
                        .ifPresent(e -> JobUtils.saveBatchData(e, maxSaveSize, en -> psrDeviceSaveService.saveDistDeviceJoinEc(en)));
            } catch (Exception ex) {
                ex.printStackTrace(); // 定时任务不需要频繁执行，遇到异常可以继续，防止直接程序停止
            }
            /*// 处理中压接入点和专变数据，中压接入点和专变接口响应慢这里弃用和通用接口共用一个配置查询数
            List<String> psrIdList = psrDeviceList.stream().filter(en -> ObjectUtils.isNotEmpty(en.getResource()))
                    .map(en -> MapUtil.getStr(en.getResource(),"psrId")).collect(Collectors.toList());
            if (ObjectUtils.isNotEmpty(psrIdList)) {
                this.dealJoinEcTransformerData(psrIdList);
            }*/
        }
    }

    /**
     * 处理中压接入点和专变关联表数据
     */
    private void dealJoinEcTransformerData(List<String> queryPsrIdList) {
        // 处理中压接入点和专变关联表数据
        if (ObjectUtils.isNotEmpty(queryPsrIdList)) {
            try {
                JoinEcTransformerDTO joinEcTransformer = JoinEcTransformerDTO.builder().psrIds(queryPsrIdList).build();
                ApiResponse<List<JoinEcTransformerPO>> joinEcTransformerInfo = psrDeviceApiClient.getJoinEcTransformerInfo(joinEcTransformer);
                // 处理中压接入点和专变的数据：先删后增
                Optional.ofNullable(joinEcTransformerInfo).filter(e -> ObjectUtils.isNotEmpty(e.getData()))
                        .ifPresent(e -> JobUtils.saveBatchData(e.getData(), maxSaveSize, en -> psrDeviceSaveService.saveDistJoinEcTransformer(en)));
            } catch (Exception ex) {
                ex.printStackTrace(); // 定时任务不需要频繁执行，遇到异常可以继续，防止直接程序停止
            }
        }
    }

    /**
     * 处理电网资源业务中台数据公共方法
     */
    private void dealPsrDeviceDataCommon(List<String> cityList, String psrType, Integer batchSize) {
        PsrDeviceQueryDTO psrDeviceQuery = new PsrDeviceQueryDTO();
        psrDeviceQuery.setPsrType(psrType).setDistribution(0); // 设置中压接入点类型和主配网标识
        psrDeviceQuery.getParams().setSize(batchSize); // 设置分页大小
        if (ObjectUtils.isNotEmpty(cityList)) {
            // 添加过滤条件
            List<PsrDeviceFilterDTO> filters = psrDeviceQuery.getParams().getFilters();
            filters.add(PsrDeviceFilterDTO.builder().compare("in").fieldName("city")
                    .fieldValue(cityList.stream().collect(Collectors.joining(","))).build());
            // 设置查询的过滤条件
            psrDeviceQuery.getParams().setFilters(filters);
        }
        // 获取第一页的数据并且确定总页数
        ApiResponse<PsrDeviceResponseVO> psrDeviceResponse = psrDeviceApiClient.getPsrDeviceByCommonInterface(psrDeviceQuery);
        Optional.ofNullable(psrDeviceResponse).filter(e -> ObjectUtils.isNotEmpty(e.getData())).ifPresent(e -> {
            // 保存电网资源业务中台的台账数据
            this.savePsrDeviceDataByPsrType(e.getData(), psrType);
            Integer pages = e.getData().getPages(); // 中压接入点总页数
            // 分页获取剩余的数据（从第二页开始）
            for (int page = 2; page <= pages; page++) {
                psrDeviceQuery.getParams().setCurrent(page); // 设置当前页数
                ApiResponse<PsrDeviceResponseVO> deviceResponse = psrDeviceApiClient.getPsrDeviceByCommonInterface(psrDeviceQuery);
                Optional.ofNullable(deviceResponse).filter(en -> ObjectUtils.isNotEmpty(en.getData()))
                        .ifPresent(en -> this.savePsrDeviceDataByPsrType(en.getData(), psrType));
            }
        });
    }

    /**
     * 保存电网资源业务中台的台账数据根据
     * 根据psrType更换不同表
     */
    private void savePsrDeviceDataByPsrType(PsrDeviceResponseVO psrDeviceResponse, String psrType) {
        List<PsrDeviceCommonVO> psrDeviceList = psrDeviceResponse.getRecords();
        if (ObjectUtils.isNotEmpty(psrDeviceList)) {
            try {
                // 保存电网资源业务中台的台账数据
                List<Map<String, Object>> psrDevices = psrDeviceList.stream()
                        .filter(e -> ObjectUtils.isNotEmpty(e))
                        .map(e -> {
                            Map<String, Object> dataMap = e.getResource();
                            dataMap.putAll(Optional.ofNullable(e.getAssets()).map(en -> en.get(0)).orElse(MapUtil.newHashMap()));
                            return dataMap;
                        }).collect(Collectors.toList());
                Optional.ofNullable(psrDevices).filter(e -> ObjectUtils.isNotEmpty(e)).ifPresent(e -> {
                    if (StringUtils.equals("0101", psrType)) { // 导线设备台账
                        JobUtils.saveBatchData(e, maxSaveSize, en -> psrDeviceSaveService.saveDistConductorSegment(en));
                    } else if (StringUtils.equals("0201", psrType)) { // 电缆段设备台账
                        JobUtils.saveBatchData(e, maxSaveSize, en -> psrDeviceSaveService.saveDistCableSegment(en));
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace(); // 定时任务不需要频繁执行，遇到异常可以继续，防止直接程序停止
            }
        }
    }

    /**
     * 获取中压接入点psrId,根据psrId获取接入点和专变信息存库
     */
    private void saveJoinEcTransformerData(Integer batchSize) {
        // 查询专变的数据, 后期有需要可以改成分页
        List<String> psrIdList = psrDeviceSaveService.getDistJoinEcBaseInfo();
        // 批量查询中压用户和专变的关联数据
        if (ObjectUtils.isNotEmpty(psrIdList)) {
            Integer totalSize = psrIdList.size();
            Integer length = (totalSize + batchSize - 1) / batchSize; // 批量获取电网业务中台的数据次数
            for (int i = 0; i < length; i++) {
                Integer startIndex = i * batchSize;
                Integer endIndex = Math.min((i + 1) * batchSize, totalSize);
                List<String> queryPsrIdList = psrIdList.subList(startIndex, endIndex);
                this.dealJoinEcTransformerData(queryPsrIdList);
            }
        }
    }
}
