package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.CompanyBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.jg.api.enums.CompanyTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.EquipSourceEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.PipelineEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgVehicleInformationMapper;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgProjectContraptionService;
import com.yeejoin.amos.boot.module.ymt.api.dto.IdxBizJgProjectContraptionDto;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgProjectContraptionMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.alibaba.fastjson.JSON.toJSONString;
/**
 * 管道工程装置表服务实现类
 *
 * @author system_generator
 * @date 2024-12-11
 */
@Slf4j
@Service
public class IdxBizJgProjectContraptionServiceImpl extends BaseService<IdxBizJgProjectContraptionDto, IdxBizJgProjectContraption, IdxBizJgProjectContraptionMapper> implements IIdxBizJgProjectContraptionService {

    public static final String[] jsonFields = {"PRODUCT_PHOTO", "OTHER_ACCESSORIES", "PRODUCT_QUALIFICATION_CERTIFICATE", "START_LATITUDE_LONGITUDE",
            "END_LATITUDE_LONGITUDE"};
    public static final String IS_INTO_MANAGEMENT = "isIntoManagement";
    public static final String USE_REGISTRATION_CODE = "useRegistrationCode";
    public static final String REG_CODE_IS_NULL = "regCodeIsNull";
    public static final String PROJECT_CONTRAPTION = "projectContraption";
    public static final String EQU_CATEGORY = "equCategory";
    public static final String EQU_DEFINE = "equDefine";
    public static final String PROJECT_CONTRAPTION_NO = "projectContraptionNo";
    public static final String ORG_BRANCH_CODE = "orgBranchCode";
    // 设备基本信息表单id
    private static final String EQUIP_INFO_FORM_ID = "equipInfo";
    @Resource
    private IdxBizJgUseInfoServiceImpl useInfoService;
    @Resource
    private IdxBizJgRegisterInfoServiceImpl registerInfoService;
    @Autowired
    private CommonServiceImpl commonServiceImpl;
    @Autowired
    private IdxBizJgInspectionDetectionInfoServiceImpl detectionInfoService;
    @Autowired
    private TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;
    @Autowired
    private CommonServiceImpl commonService;
    @Autowired
    private JgVehicleInformationMapper jgVehicleInformationMapper;
    @Autowired
    private JgInstallationNoticeServiceImpl jgInstallationNoticeService;
    @Autowired
    private IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;
    @Autowired
    private IdxBizJgDesignInfoServiceImpl idxBizJgDesignInfoService;
    @Autowired
    private IdxBizJgFactoryInfoServiceImpl idxBizJgFactoryInfoService;
    @Autowired
    private IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;
    @Autowired
    private IdxBizJgSupervisionInfoServiceImpl idxBizJgSupervisionInfoService;
    @Autowired
    private IdxBizJgOtherInfoServiceImpl idxBizJgOtherInfoService;
    @Autowired
    private IdxBizJgTechParamsPipelineServiceImpl idxBizJgTechParamsPipelineService;
    @Autowired
    private IdxBizJgInspectionDetectionInfoServiceImpl idxBizJgInspectionDetectionInfoService;
    @Autowired
    private IdxBizJgConstructionInfoServiceImpl idxBizJgConstructionInfoService;
    @Autowired
    private ESEquipmentCategory esEquipmentCategory;
    @Autowired
    private DataDictionaryServiceImpl dataDictionaryServiceImpl;

    @Override
    public boolean saveOrUpdateData(IdxBizJgProjectContraption projectContraption) {
        return this.saveOrUpdate(projectContraption);
    }

    /**
     * 根据工程装置seq物理删除装置表数据和对应设备信息（数据库+es）
     *
     * @param sequenceNbr 工程装置表seq
     * @return result
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProjectAndEquInfoBySeq(Long sequenceNbr) {
        List<IdxBizJgUseInfo> useInfos = useInfoService.lambdaQuery().select(IdxBizJgUseInfo::getRecord).eq(IdxBizJgUseInfo::getProjectContraptionId, sequenceNbr).list();
        // 删除idx设备表信息 + 删除对应es数据
        List<String> records = useInfos.stream().map(IdxBizJgUseInfo::getRecord).collect(Collectors.toList());
        if (records.isEmpty()) return Boolean.TRUE;
        Map<String, Object> map = new HashMap<>();
        map.put("recordList", records);
        map.put("equList", PipelineEnum.PRESSURE_PIPELINE.getCode());
        registerInfoService.batchDeleteByRecord(map);
        // 删除装置表信息
        this.removeById(sequenceNbr);
        return Boolean.TRUE;
    }

    private String getCompanyLevel(CompanyBo company) {
        if (BaseController.COMPANY_TYPE_COMPANY.equals(company.getLevel())) {
            return BaseController.COMPANY_TYPE_COMPANY;
        } else {
            return BaseController.COMPANY_TYPE_SUPERVISION;
        }
    }

    /**
     * 根据入参 分页查询（当前）单位下的工程管道
     *
     * @param params      查询参数 Map
     * @param page        分页
     * @param reginParams 当前登录人信息
     * @return result
     */
    @Override
    public IPage<IdxBizJgProjectContraption> proConPageByParams(Map<String, String> params, Page<IdxBizJgProjectContraption> page, ReginParams reginParams) {
        CompanyBo company = reginParams.getCompany();
        String companyType = company.getCompanyType();
        String companyCode = company.getCompanyCode();
        // 是否是否纳管：true - 已纳管 false-未纳管
        boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
        // 使用登记编号
        String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
        // 使用登记编号是否为空 true/false
        String regCodeIsNull = params.get(REG_CODE_IS_NULL);
        // 工程装置名称
        String projectContraption = params.get(PROJECT_CONTRAPTION);
        // 工程装置编号
        String projectContraptionNo = params.get(PROJECT_CONTRAPTION_NO);
        //属地监管部门code
        String orgBranchCode = params.get(ORG_BRANCH_CODE);
        // 设备类别code
        String equCategory = params.get(EQU_CATEGORY);
        // 设备类品种code
        String equDefine = params.get(EQU_DEFINE);
        // 证详情-查询标识
        String useRegDetail = params.get("useRegDetail");
        // 登录人公司类型：企业，监管
        String companyLevel = this.getCompanyLevel(company);
        IPage<IdxBizJgProjectContraption> pageList = lambdaQuery()
                // 企业按照公司类型进行过滤
                .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                .eq(BaseController.COMPANY_TYPE_COMPANY.equals(companyLevel) && CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                // 监管机构按照属地监管部门orgCode进行过滤
                .likeRight(ValidationUtil.isEmpty(useRegDetail) && BaseController.COMPANY_TYPE_SUPERVISION.equals(companyLevel), IdxBizJgProjectContraption::getOrgCode, company.getOrgCode())
                .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                .eq(!ValidationUtil.isEmpty(equCategory), IdxBizJgProjectContraption::getEquCategory, equCategory)
                .eq(!ValidationUtil.isEmpty(equDefine), IdxBizJgProjectContraption::getEquDefine, equDefine)
                .like(!ValidationUtil.isEmpty(projectContraption), IdxBizJgProjectContraption::getProjectContraption, projectContraption)
                .like(!ValidationUtil.isEmpty(orgBranchCode), IdxBizJgProjectContraption::getOrgCode, orgBranchCode)
                .like(!ValidationUtil.isEmpty(projectContraptionNo), IdxBizJgProjectContraption::getProjectContraptionNo, projectContraptionNo)
                .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNull(IdxBizJgProjectContraption::getProjectContraptionParentId)
                .orderByDesc(IdxBizJgProjectContraption::getRecDate)
                .page(page);
        if (!ValidationUtil.isEmpty(pageList.getRecords())) {
            pageList.getRecords().forEach(record -> {
                BigDecimal pipelineLength = BigDecimal.valueOf(record.getPipelineLength());
                BigDecimal roundedValue = pipelineLength.setScale(3, RoundingMode.HALF_UP);
                BigDecimal strippedValue = roundedValue.stripTrailingZeros();
                record.setPipelineLength(Double.valueOf(strippedValue.toPlainString()));
                record.setDataSourceName(EquipSourceEnum.getDataSourceName(record.getDataSource()));
                record.setFullAddress(
                        Stream.of(record.getProvinceName(), record.getCityName(), record.getCountyName(), record.getStreetName(), record.getAddress())
                                .map(value -> value == null ? "" : value)
                                .collect(Collectors.joining())
                );
            });

            List<Long> projectContraptionIdList = pageList.getRecords().stream().map(IdxBizJgProjectContraption::getSequenceNbr).collect(Collectors.toList());
            Map<String, Boolean> canEditMap = this.checkContraptionIsCanEdit(projectContraptionIdList);
            pageList.getRecords().forEach(record -> record.setCanEdit(canEditMap.get(record.getSequenceNbr())));
            Map<String, Boolean> canDeleteMap = this.checkContraptionIsCanDelete(projectContraptionIdList, isIntoManagement);
            pageList.getRecords().forEach(record -> record.setCanDelete(canDeleteMap.get(record.getSequenceNbr())));
            //判断是否有检验结果录入
            judgeCheckResult(pageList.getRecords());
        }
        return pageList;
    }

    /**
     * 此处判断是否有检验结果 所有的管道信息都需要有检验结果才可以展示
     * @param records
     */
    private void judgeCheckResult(List<IdxBizJgProjectContraption> records) {
        List<IdxBizJgProjectContraption> pipelineList = records.stream().filter(record -> PipelineEnum.PRESSURE_PIPELINE.getCode().equals(record.getEquList())).collect(Collectors.toList());
        if (!ValidationUtil.isEmpty(pipelineList)) {
            StopWatch watch1 = new StopWatch();
            List<Long> projectContraptionIdList = pipelineList.stream().map(IdxBizJgProjectContraption::getSequenceNbr).collect(Collectors.toList());
            watch1.start();
            List<Map<String, Integer>> notNullCountList = this.baseMapper.selectCheckCountByNotNull(projectContraptionIdList);
            watch1.stop();
            System.out.println("watch1:" + watch1.getTotalTimeMillis());
            StopWatch watch2 = new StopWatch();
            watch2.start();
            List<Map<String, Integer>> totalList = this.baseMapper.selectEquipCount(projectContraptionIdList);
            watch2.stop();
            System.out.println("watch2:" + watch2.getTotalTimeMillis());
            for (IdxBizJgProjectContraption record : pipelineList) {
                Map<String, Integer> totalMap = totalList.stream().filter(item -> String.valueOf(record.getSequenceNbr()).equals(item.get("project_contraption_id"))).findFirst().orElse(new HashMap<>());
                Map<String, Integer> notNullCountMap = notNullCountList.stream().filter(item -> String.valueOf(record.getSequenceNbr()).equals(item.get("project_contraption_id"))).findFirst().orElse(new HashMap<>());
                Integer total = totalMap.get("count");
                Integer notNullCount = notNullCountMap.get("count");
                if(total != null && total.equals(notNullCount) && total != 0){
                    record.setDisableBasicButton(false);
                }
            }
        }
    }

    private Map<String, Boolean> checkContraptionIsCanEdit(List<Long> projectContraptionIdList) {
    Map<String, Boolean> resultMap = new HashMap<>();
    if (ValidationUtil.isEmpty(projectContraptionIdList)) {
        return resultMap;
    }

    List<Map<String, Integer>> inUseTimeMap = this.baseMapper.countContraptionInUseTimesForEdit(projectContraptionIdList);

        return getCheckResultMap(projectContraptionIdList, resultMap, inUseTimeMap);
    }


    private Map<String, Boolean> checkContraptionIsCanDelete(List<Long> projectContraptionIdList, Boolean isIntoManagement) {
        Map<String, Boolean> resultMap = new HashMap<>();
        if (ValidationUtil.isEmpty(projectContraptionIdList)) {
            return resultMap;
        }
        List<Map<String, Integer>> inUseTimeMap;
        if(isIntoManagement) {
            inUseTimeMap = this.baseMapper.countContraptionInUseTimesForDeleteByIntoManagementBatch(projectContraptionIdList);
        } else {
            inUseTimeMap = this.baseMapper.countContraptionInUseTimesForDelete(projectContraptionIdList);
        }
        return getCheckResultMap(projectContraptionIdList, resultMap, inUseTimeMap);
    }

    private Map<String, Boolean> getCheckResultMap(List<Long> projectContraptionIdList, Map<String, Boolean> resultMap, List<Map<String, Integer>> inUseTimeMap) {
        for (Long projectContraptionId : projectContraptionIdList) {
            Optional<Integer> inUseCountOpt = inUseTimeMap.stream()
                    .filter(map -> projectContraptionId.toString().equals(map.get("project_contraption_id")))
                    .map(map -> map.get("inUseNumber"))
                    .filter(Objects::nonNull)
                    .findFirst();

            Integer inUseCount = inUseCountOpt.orElse(0);
            resultMap.put(String.valueOf(projectContraptionId), inUseCount <= 0);
        }
        return resultMap;
    }

    @Override
    public List<IdxBizJgProjectContraption> proConListByParams(Map<String, String> params, ReginParams reginParams) {
        CompanyBo company = reginParams.getCompany();
        String companyType = company.getCompanyType();
        String companyCode = company.getCompanyCode();
        // 是否是否纳管：true - 已纳管 false-未纳管
        boolean isIntoManagement = Boolean.parseBoolean(params.get(IS_INTO_MANAGEMENT));
        // 使用登记编号
        String useRegistrationCode = params.get(USE_REGISTRATION_CODE);
        // 使用登记编号是否为空 true/false
        String regCodeIsNull = params.get(REG_CODE_IS_NULL);

        return lambdaQuery()
                .eq(CompanyTypeEnum.CONSTRUCTION.getName().equals(companyType), IdxBizJgProjectContraption::getUscUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.USE.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode)
                .eq(CompanyTypeEnum.INDIVIDUAL.getName().equals(companyType), IdxBizJgProjectContraption::getUseUnitCreditCode, companyCode.split("_").length > 1 ? companyCode.split("_")[1] : companyCode)
                .eq(!ValidationUtil.isEmpty(params.get(IS_INTO_MANAGEMENT)), IdxBizJgProjectContraption::getIsIntoManagement, isIntoManagement)
                .eq(!ValidationUtil.isEmpty(useRegistrationCode), IdxBizJgProjectContraption::getUseRegistrationCode, useRegistrationCode)
                .isNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.TRUE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .isNotNull(!ValidationUtil.isEmpty(regCodeIsNull) && Boolean.FALSE.equals(Boolean.valueOf(regCodeIsNull)), IdxBizJgProjectContraption::getUseRegistrationCode)
                .list();
    }

    /**
     * 分页查询
     */
    public Page<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionPage(Page<IdxBizJgProjectContraptionDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<IdxBizJgProjectContraptionDto> queryForIdxBizJgProjectContraptionList() {
        return this.queryForList("", false);
    }

    public Map<String, Map<String, Object>> details(String sequenceNbr) {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        if (ObjectUtils.isEmpty(sequenceNbr)) {
            resultMap.put(EQUIP_INFO_FORM_ID, Collections.emptyMap());
            return resultMap;
        }
        var baseMapper = this.getBaseMapper();
        Map<String, Object> projectContraptionMap = Optional.ofNullable(baseMapper.getDetail(sequenceNbr))
                .map(map -> {
                    commonServiceImpl.convertStringToJsonobject(map, jsonFields);
                    map.put("pipelineList", baseMapper.selectEquipList((String) map.get("SEQUENCE_NBR")));
                    return map;
                })
                .orElse(Collections.emptyMap());

        resultMap.put(EQUIP_INFO_FORM_ID, projectContraptionMap);
        return resultMap;
    }

    public Page<Map<String, Object>> techParamsPipelinePage(String sequenceNbr,int current, int size) {
        Page<Map<String, Object>> page=new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        page.setRecords(baseMapper.selectEquipListPage(sequenceNbr, (current - 1) * size, size));
        Map<String, Integer> totalMap = baseMapper.selectEquipCount(new ArrayList<>(Collections.singletonList(Long.parseLong(sequenceNbr)))).get(0);
        page.setTotal(totalMap.get("count"));
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateDetectionInfo(IdxBizJgInspectionDetectionInfo detectionInfo) {
        detectionInfo.setRecDate(new Date());
        detectionInfoService.saveOrUpdateData(detectionInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateDetectionInfoBatch(JSONObject jsonObject) {
        if(Objects.nonNull(jsonObject)){
            JSONArray records = jsonObject.getJSONArray("records");
            if(CollectionUtil.isNotEmpty(records)){
                List<IdxBizJgInspectionDetectionInfo> jgInspectionDetectionInfos= new ArrayList<>();
                for (Object record : records) {
                    IdxBizJgInspectionDetectionInfo detectionInfo = JSON.parseObject(JSONObject.toJSONString(record), IdxBizJgInspectionDetectionInfo.class);
                    if(Objects.nonNull(detectionInfo)){
                        if (record instanceof LinkedHashMap){
                          Map map = (LinkedHashMap)record;
                          detectionInfo.setRecDate(new Date());
                          detectionInfo.setSequenceNbr((String) map.get("detectionInfoSequenceNbr"));
                          detectionInfo.setInspectConclusion((String)map.get("inspectConclusionCode"));
                          jgInspectionDetectionInfos.add(detectionInfo);
                        }
                    }
                }
                if(CollUtil.isNotEmpty(jgInspectionDetectionInfos)){
                    detectionInfoService.saveOrUpdateBatch(jgInspectionDetectionInfos);
                }
            }
        }

    }

    public IdxBizJgInspectionDetectionInfo getDetectionInfoDetail(String sequenceNbr) {
        return detectionInfoService.getById(sequenceNbr);
    }

    public void exportSummaryBasicInfo(String sequenceNbr, HttpServletResponse response, String category) {
        // 长输/公共管道/工业管道汇总
        if ("8200".equals(category) || "8100".equals(category) || "8300".equals(category)) {
            // 总数
            double total;
            // 每页显示条数，默认 10
            int size = 10;
            IdxBizJgProjectContraption idxBizJgProjectContraption = baseMapper.selectById(sequenceNbr);
            if (ValidationUtil.isEmpty(idxBizJgProjectContraption)) {
                throw new BadRequest("没有查询到汇总信息！");
            }
            List<Map<String, Object>> allEquipment = baseMapper.selectEquipListByExport(sequenceNbr);
            total = allEquipment.size();
            AgencyUserModel result = new AgencyUserModel();
            if (!ValidationUtil.isEmpty(idxBizJgProjectContraption.getRecUserId())) {
                result = Privilege.agencyUserClient.queryByUserId(idxBizJgProjectContraption.getRecUserId()).getResult();
            }
            // 模板
            String wordPath = "PressurePipeBasicInformationSummary.ftl";
            // 文件名前缀
            String filePrefix = "压力管道基本信息汇总表_";
            // 压力包名称
            String customFileName = filePrefix + idxBizJgProjectContraption.getProjectContraptionNo() + ".zip";
            // 总页数
            int page = (int) Math.ceil(total / size);
            // 异步获取数据
            List<CompletableFuture<byte[]>> futures = pressurePipeDataPreparation(page, idxBizJgProjectContraption, size, total, allEquipment, wordPath, filePrefix, result,category);
            // byte[]压缩zip
            toZipFile(response, futures, filePrefix, customFileName);
        }
    }

    /**
     * 压力管道数据
     *
     * @return
     */
    private List<CompletableFuture<byte[]>> pressurePipeDataPreparation(int page,  IdxBizJgProjectContraption idxBizJgProjectContraption, int size, double total,  List<Map<String, Object>> equipmentLists, String wordPath, String filePrefix, AgencyUserModel result,String category) {
        Map<String, Object> exportParamsMap = new HashMap<>();
        exportParamsMap.put("page", page);
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String formattedDate = currentDate.format(formatter);
        exportParamsMap.put("printDate", formattedDate);
        //获取分类名称
        exportParamsMap.put("categoryName", PipelineEnum.getMessage(category));
        // 使用单位
        exportParamsMap.put("useUnitName", idxBizJgProjectContraption.getUseUnitName());
        // 使用单位地址
        String useUnitCreditCode = String.valueOf(idxBizJgProjectContraption.getUseUnitCreditCode());
        TzBaseEnterpriseInfo enterpriseInfo = tzBaseEnterpriseInfoMapper.selectOne(new LambdaQueryWrapper<TzBaseEnterpriseInfo>().eq(TzBaseEnterpriseInfo::getUseCode, useUnitCreditCode));
        exportParamsMap.put("fullAddress", enterpriseInfo.getAddress());
        exportParamsMap.put("nameOfProjectDevice", idxBizJgProjectContraption.getProjectContraption());
        // 安全管理部门
        exportParamsMap.put("orgBranchName", "");
        // 安全管理员
        exportParamsMap.put("safetyManager", "");
        // 联系电话
        exportParamsMap.put("phone", ValidationUtil.isEmpty(result.getMobile()) ? "" : result.getMobile());
        // 经办人
        exportParamsMap.put("agent", ValidationUtil.isEmpty(result.getRealName()) ? "" : result.getRealName());
        // 电子邮箱
        exportParamsMap.put("email", ValidationUtil.isEmpty(result.getEmail()) ? "" : result.getEmail());

        List<CompletableFuture<byte[]>> futures = IntStream.rangeClosed(1, page)
                .mapToObj(current -> CompletableFuture.supplyAsync(() -> {
                    // 创建独立的参数副本
                    Map<String, Object> currentExportParamsMap = new HashMap<>(exportParamsMap);
                    currentExportParamsMap.put("current", current);
                    // 数据分页
                    int start = (current - 1) * size;
                    int end = ((current - 1) * size + size) < total ? (current - 1) * size + size : (int) total;
                    // 数据截取
                    List<Map<String, Object>> equData = equipmentLists.subList(start, end);
                    // 设备数据填充
                    this.pressurePipeEquData(currentExportParamsMap, equData, current, size);
                    return commonService.generateSummaryOfCylinderInfo(currentExportParamsMap, wordPath, filePrefix);
                })).collect(Collectors.toList());
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[page])).join();
        return futures;
    }

    /**
     * 压力管道设备数据填充
     */
    public void pressurePipeEquData(Map<String, Object> exportParamsMap, List<Map<String, Object>> equData, int current, int size) {

        String[] fieldNames = {"productName", "pipelineNumber", "deviceLevel", "designUnitName", "uscUnitName",
                "uscDate", "useDate", "nominalDiameter", "wallThickness", "pipeLength", "pressure", "temperature",
                "medium", "inspectConclusion", "inspectOrgName", "nextInspectDate", "remarks"};
        // 填充有效数据
        for (int curr = 0; curr < equData.size(); curr++) {
            Map<String, Object> map = equData.get(curr);

            int serialNum = curr + 1;
            for (String fieldName : fieldNames) {
                exportParamsMap.put("num" + serialNum, (current - 1) * size + (curr + 1));
                exportParamsMap.put(fieldName + serialNum, setSpecialParamFields(fieldName, map));
            }
        }

        // 填充剩余空白项至指定总页数
        for (int curr = equData.size(); curr < size; curr++) {
            int serialNum = curr + 1;
            for (String fieldName : fieldNames) {
                exportParamsMap.put("num" + serialNum, "");
                exportParamsMap.put(fieldName + serialNum, ""); // 使用空字符串填充空白项
            }
        }
    }

    private Object trimIfEmpty(Object obj) {
        return ValidationUtil.isEmpty(obj) ? "" : obj;
    }

    private Object setSpecialParamFields(String fieldName, Map<String, Object> equip){
        switch (fieldName) {
            case "pressure":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workPressure"));
            case "temperature":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workTemperature"));
            case "medium":
                return trimIfEmpty(equip.get(fieldName)) + "/" + trimIfEmpty(equip.get("workMedium"));
            default:
                return ValidationUtil.isEmpty(equip.get(fieldName)) ? "" : equip.get(fieldName);
        }
    }

    private static void toZipFile(HttpServletResponse response, List<CompletableFuture<byte[]>> futures, String filePrefix, String customFileName) {
        // 打包zip
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
             ZipOutputStream zip = new ZipOutputStream(outputStream)) {

            for (int i = 0; i < futures.size(); i++) {
                try {
                    zip.putNextEntry(new ZipEntry(filePrefix + "第" + (i + 1) + "页" + ".pdf"));
                    IOUtils.write(futures.get(i).join(), zip);
                    zip.closeEntry(); // 每个条目结束后关闭
                } catch (IOException e) {
                    log.error("打包zip失败：" + e.getMessage());
                    throw new BadRequest("打包zip失败");
                }
            }
            // 所有条目写入完成后关闭 ZipOutputStream
            zip.finish();
            // 设置响应头并将压缩文件写入 HttpServletResponse
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/zip");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(customFileName, "UTF-8"));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("导出异常：", e);
        }
    }

    public IdxBizJgProjectContraption saveFirstMergeProjectContraption(IdxBizJgProjectContraptionDto model) {
        // 单位类型
        Map<String, Object> companyInfoMap = jgInstallationNoticeService.getCompanyType();
        IdxBizJgProjectContraption projectContraption = JSON.parseObject(toJSONString(model), IdxBizJgProjectContraption.class);
        String equListName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquListCode());
        String equCategoryName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquCategoryCode());
        String equDefineName = jgVehicleInformationMapper.getEquCategoryNameByCode(model.getEquDefineCode());
        projectContraption.setDataSource("jg");
        projectContraption.setIsIntoManagement(false);
        projectContraption.setProvinceName("陕西省");
        projectContraption.setEquList(model.getEquListCode());
        projectContraption.setEquCategory(model.getEquCategoryCode());
        projectContraption.setEquDefine(model.getEquDefineCode());
        projectContraption.setEquListName(equListName);
        projectContraption.setEquCategoryName(equCategoryName);
        projectContraption.setEquDefineName(equDefineName);
        projectContraption.setPipelineLength(0.0);
        projectContraption.setUseUnitName(companyInfoMap.get("companyName").toString());
        projectContraption.setUseUnitCreditCode(companyInfoMap.get("creditCode").toString());
        this.saveOrUpdateData(projectContraption);
        return projectContraption;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByHisGdPl(Long sequenceNbr) {
        IdxBizJgProjectContraption idxBizJgProjectContraption = baseMapper.selectById(sequenceNbr);
        if(Objects.nonNull(idxBizJgProjectContraption)){
            String dataSource = idxBizJgProjectContraption.getDataSource();
            if(!"jg_his_gd_pl".equals(dataSource)){
                throw new BadRequest("数据源不是导入类型禁止删除");
            }
            // 删除管道对应的idx表数据
            this.deletePipInfoToIdxTables(idxBizJgProjectContraption);

            // 删除工程装置表信息
            removeById(idxBizJgProjectContraption.getSequenceNbr());

        }
        return Boolean.TRUE;
    }


    private void deletePipInfoToIdxTables(IdxBizJgProjectContraption idxBizJgProjectContraption) {
        Long jgProjectContraptionSequenceNbr = idxBizJgProjectContraption.getSequenceNbr();
        LambdaQueryWrapper<IdxBizJgUseInfo> jgUseInfoWrapper = new LambdaQueryWrapper<>();
        jgUseInfoWrapper.eq(IdxBizJgUseInfo::getProjectContraptionId,jgProjectContraptionSequenceNbr);
        List<IdxBizJgUseInfo> useInfos = idxBizJgUseInfoService.list(jgUseInfoWrapper);
        //获取records
        List<String> records = new ArrayList<>();

        if(CollectionUtil.isNotEmpty(useInfos)){
            for (IdxBizJgUseInfo useInfo : useInfos) {
                records.add(useInfo.getRecord());
            }
        }

        if(CollectionUtil.isNotEmpty(records)){
            // 删除检验检测信息
            LambdaQueryWrapper<IdxBizJgInspectionDetectionInfo> inspectionDetectionInfoWrapper = new LambdaQueryWrapper<>();
            inspectionDetectionInfoWrapper.in(IdxBizJgInspectionDetectionInfo::getRecord,records);
            idxBizJgInspectionDetectionInfoService.remove(inspectionDetectionInfoWrapper);
            // 删除设计信息
            LambdaQueryWrapper<IdxBizJgDesignInfo> designInfoWrapper = new LambdaQueryWrapper<>();
            designInfoWrapper.in(IdxBizJgDesignInfo::getRecord,records);
            idxBizJgDesignInfoService.remove(designInfoWrapper);
            // 删除制造信息
            LambdaQueryWrapper<IdxBizJgFactoryInfo> factoryInfoWrapper = new LambdaQueryWrapper<>();
            factoryInfoWrapper.in(IdxBizJgFactoryInfo::getRecord,records);
            idxBizJgFactoryInfoService.remove(factoryInfoWrapper);
            // 删除施工信息
            LambdaQueryWrapper<IdxBizJgConstructionInfo> constructionInfoWrapper = new LambdaQueryWrapper<>();
            constructionInfoWrapper.in(IdxBizJgConstructionInfo::getRecord,records);
            idxBizJgConstructionInfoService.remove(constructionInfoWrapper);
            // 删除注册登记信息
            LambdaQueryWrapper<IdxBizJgRegisterInfo> registerInfoWrapper = new LambdaQueryWrapper<>();
            registerInfoWrapper.in(IdxBizJgRegisterInfo::getRecord,records);
            idxBizJgRegisterInfoService.remove(registerInfoWrapper);
            // 删除监督管理
            LambdaQueryWrapper<IdxBizJgSupervisionInfo> supervisionInfoWrapper = new LambdaQueryWrapper<>();
            supervisionInfoWrapper.in(IdxBizJgSupervisionInfo::getRecord,records);
            idxBizJgSupervisionInfoService.remove(supervisionInfoWrapper);
            // 删除其他信息
            LambdaQueryWrapper<IdxBizJgOtherInfo> otherInfoWrapper = new LambdaQueryWrapper<>();
            otherInfoWrapper.in(IdxBizJgOtherInfo::getRecord,records);
            idxBizJgOtherInfoService.remove(otherInfoWrapper);
            // 删除管道技术参数
            LambdaQueryWrapper<IdxBizJgTechParamsPipeline> techParamsPipelineWrapper = new LambdaQueryWrapper<>();
            techParamsPipelineWrapper.in(IdxBizJgTechParamsPipeline::getRecord,records);
            idxBizJgTechParamsPipelineService.remove(techParamsPipelineWrapper);
            //删除es数据
            for (String record : records) {
                esEquipmentCategory.deleteById(record);
            }
            // 删除使用信息
            idxBizJgUseInfoService.remove(jgUseInfoWrapper);

        }
    }

    public Map<String, Object> getNewInspectionDetailByRecord(String record) {
        IdxBizJgInspectionDetectionInfo info = detectionInfoService.queryNewestDetailByRecord(record);
        if (info == null) return Collections.emptyMap();
        Map<String, Object> result = new HashMap<>(Bean.BeantoMap(info));
        result.put("inspectReport", JSON.parseArray(info.getInspectReport()));
        result.put("inspectConclusionCode", info.getInspectConclusion());
        result.put("inspectConclusion", Optional.ofNullable(dataDictionaryServiceImpl.getByCode(info.getInspectConclusion(), "JYJL"))
                .map(DataDictionary::getName).orElse(""));
        return result;
    }
}