package org.jeecg.modules.database.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.PathUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.MinioUtil;
import org.jeecg.modules.database.dto.RadiationDetailDTO;
import org.jeecg.modules.database.dto.RadiationMapDTO;
import org.jeecg.modules.database.entity.*;
import org.jeecg.modules.database.mapper.ExperimentDocMapper;
import org.jeecg.modules.database.service.*;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 试验文档
 * @Author: jeecg-boot
 * @Date: 2024-08-30
 * @Version: V1.0
 */
@Service
@Slf4j
public class ExperimentDocServiceImpl extends ServiceImpl<ExperimentDocMapper, ExperimentDoc> implements IExperimentDocService {

    static Map<String, String> docTempalteMap = new HashMap<>();

    static {
        //辐照试验计划表
        docTempalteMap.put("辐照试验计划表", "fzsyjhb.docx");
        docTempalteMap.put("试验报告评审表", "sybgpsb.docx");
        docTempalteMap.put("设备使用记录表", "sbsyjlb.docx");
        docTempalteMap.put("试验报告", "sybg.docx");
        docTempalteMap.put("辐照试验总结单", "fzsyzjd.docx");
    }

    @Value("${jeecg.template.path}")
    private String                               templatePath;
    @Value("${server.ip}")
    private String                               serverIp;
    @Autowired
    private IExperimentService                   experimentService;
    @Autowired
    private IExperimentReportService             experimentReportService;
    @Autowired
    private IExperimentDeviationEquipmentService experimentDeviationEquipmentService;
    @Autowired
    private ISysUserService                      sysUserService;
    @Autowired
    private IClientService                       clientService;
    @Autowired
    private IExperimentTestProcessService        experimentTestProcessService;
    @Autowired
    private IExperimentRadiationProcessService   experimentRadiationProcessService;
    @Autowired
    private ITestStandardsService                testStandardsService;

    public static void main(String[] args) throws IOException {
        //The core API uses a minimalist design, only one line of code is required
        TestStandards testStandards = new TestStandards();
        testStandards.setAttachment("");
        Path lastPathEle = PathUtil.getLastPathEle(Path.of(Optional.ofNullable(testStandards).map(TestStandards::getAttachment).orElse(""))
                .getFileName());
        System.out.println(lastPathEle.toString());
        //generateExperimentDoc("20241028号实验", "辐照试验计划表", maps);
    }

    private static void addPageNumberToHeader(String left, XWPFHeader header) {

        // 创建一个新的段落用于页码
        XWPFParagraph paragraph = header.createParagraph();

        // 设置段落右对齐
        CTPPr pPr = paragraph.getCTP().addNewPPr();
        pPr.addNewJc().setVal(STJc.BOTH);

        // 添加页码文本
        // 添加文本“第”
        XWPFRun run = paragraph.createRun();
        run.setText(left);
        // 添加制表符（用于分隔左侧固定字符串和右侧页码）
        run.addTab();

        run = paragraph.createRun();
        run.setText("第 ");

        // 插入当前页码字段
        run = paragraph.createRun();
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
        run.getCTR().addNewInstrText().setStringValue("PAGE");
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);

        // 添加文本“页，共”
        run = paragraph.createRun();
        run.setText(" 页，共 ");

        // 插入总页数字段
        run = paragraph.createRun();
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
        run.getCTR().addNewInstrText().setStringValue("NUMPAGES");
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
        run.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);

        // 添加文本“页（含封面）”
        run = paragraph.createRun();
        run.setText(" 页（含封面）");

        // 设置制表符的对齐方式为右对齐
        CTTabs tabs = pPr.addNewTabs();
        CTTabStop tabStop = tabs.addNewTab();
        tabStop.setVal(STTabJc.RIGHT); // 右对齐
        tabStop.setPos(BigInteger.valueOf(8000)); // 设置制表符位置（单位：twips，1 cm = 567 twips）

    }

    private static String formatDate(String date) {
        if (StringUtils.isBlank(date)) {
            return "";
        }
        return StringUtils.contains(date, " ") ? StringUtils.substringBefore(date, " ") : date;
    }

    private static String formatDate(Date date) {
        if (Objects.isNull(date)) {
            return "";
        }
        return DateUtils.formatDate(date, "yyyy-MM-dd HH:mm");
    }

    public String generateExperimentDoc(String experimentId, String fileName, String version) {
        String absolutePath = templatePath + File.separator + docTempalteMap.get(fileName);
        log.info("doc template path: " + absolutePath);
        if (!FileUtil.exist(absolutePath)) {
            throw new RuntimeException("模板文件不存在！");
        }
        try {
            Experiment experiment = experimentService.getById(experimentId);
            if (Objects.isNull(experiment)) {
                throw new RuntimeException("实验数据不存在！");
            }
            String tmpDirPath = FileUtil.getTmpDirPath();

            String path = generateUpload(experimentId, fileName, version, tmpDirPath);
            return path;
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private String generateUpload(String experimentId, String type, String version, String tmpDirPath) throws Exception {
        String absolutePath = templatePath + File.separator + docTempalteMap.get(type);
        Experiment experiment = experimentService.getById(experimentId);
        switch (type) {
            case "辐照试验计划表":
                Map<String, Object> jhparams = assembleFzsyjhb(experimentId);
                XWPFTemplate jhrender = XWPFTemplate.compile(absolutePath).render(jhparams);
                String outputFile1 = tmpDirPath + File.separator + type + "-" + experimentId + "-" + version + ".docx";
                if (FileUtil.exist(outputFile1)) {
                    FileUtil.del(outputFile1);
                }
                jhrender.writeToFile(outputFile1);
                return MinioUtil.upload(FileUtil.getInputStream(outputFile1),
                        "experiment_doc/" + experimentId + "/" + version + "/" + experiment.getName() + "-" + type + ".docx");
            case "试验报告评审表":
                Map<String, Object> psparams = assembleSybgpsb(experimentId);
                XWPFTemplate psrender = XWPFTemplate.compile(absolutePath).render(psparams);
                String outputFile2 = tmpDirPath + File.separator + type + "-" + experimentId + "-" + version + ".docx";
                if (FileUtil.exist(outputFile2)) {
                    FileUtil.del(outputFile2);
                }
                psrender.writeToFile(outputFile2);
                return MinioUtil.upload(FileUtil.getInputStream(outputFile2),
                        "experiment_doc/" + experimentId + "/" + version + "/" + experiment.getName() + "-" + type + ".docx");
            case "设备使用记录表":
                Map<String, Object> sbParams = assembleSbsyjlb(experimentId);
                LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
                Configure config = Configure.builder().bind("equipment", policy).build();
                XWPFTemplate template = XWPFTemplate.compile(absolutePath, config).render(sbParams);
                String outputFile3 = tmpDirPath + File.separator + type + "-" + experimentId + "-" + version + ".docx";
                if (FileUtil.exist(outputFile3)) {
                    FileUtil.del(outputFile3);
                }
                template.writeToFile(outputFile3);
                return MinioUtil.upload(FileUtil.getInputStream(outputFile3),
                        "experiment_doc/" + experimentId + "/" + version + "/" + experiment.getName() + "-" + type + ".docx");
            case "试验报告":
                List<ExperimentReport> reportList = experimentReportService.getPassedByExperimentId(experimentId);
                List<String> pathList = new ArrayList<>();

                String outputDir = tmpDirPath + type + File.separator + experimentId + File.separator + version;
                if (FileUtil.exist(outputDir)) {
                    FileUtil.del(outputDir);
                }
                if (!FileUtil.exist(outputDir)) {
                    FileUtil.mkdir(outputDir);
                }
                for (ExperimentReport experimentReport : reportList) {
                    Map<String, Object> params = assembleSybg(experimentId, experimentReport);
                    XWPFTemplate render = XWPFTemplate.compile(absolutePath).render(params);
                    String filePath = outputDir + File.separator + experimentReport.getReportName() + ".docx";
                    render.writeToFile(filePath);
                    String reportPath = MinioUtil.upload(FileUtil.getInputStream(filePath),
                            "experiment_doc/" + experimentId + "/" + version + "/" + experimentReport.getReportName() + ".docx");
                    pathList.add(reportPath);
                }
                File zip = ZipUtil.zip(outputDir);
                String zipPath = MinioUtil.upload(FileUtil.getInputStream(zip),
                        "experiment_doc/" + experimentId + "/" + version + "/" + type + "-" + experiment.getName() + ".zip");

                return zipPath;
            case "辐照试验总结单":
                Map<String, Object> zjdParams = assembleFzsyzjd(experimentId);
                LoopRowTableRenderPolicy zjdpolicy = new LoopRowTableRenderPolicy();
                Configure zjdconfig = Configure.builder().bind("sample", zjdpolicy).build();
                XWPFTemplate zjdtemplate = XWPFTemplate.compile(absolutePath, zjdconfig).render(zjdParams);
                String outputFile5 = tmpDirPath + File.separator + type + "-" + experimentId + "-" + version + ".docx";
                if (FileUtil.exist(outputFile5)) {
                    FileUtil.del(outputFile5);
                }
                zjdtemplate.writeToFile(outputFile5);
                return MinioUtil.upload(FileUtil.getInputStream(outputFile5),
                        "experiment_doc/" + experimentId + "/" + version + "/" + experiment.getName() + "-" + type + ".docx");
        }
        return null;
    }

    private Map<String, Object> assembleFzsyzjd(String experimentId) {
        Experiment experiment = experimentService.getById(experimentId);
        experimentService.fetchExperimentDetail(experiment);
        if (Objects.isNull(experiment)) {
            return new HashMap<>();
        }
        Map<String, Object> root = new HashMap<>();
        root.put("试验编号", experiment.getExperimentNo());
        Client client = clientService.getOne(new LambdaQueryWrapper<Client>().eq(Client::getName, experiment.getClientName()), false);
        root.put("委托方单位名称", Optional.ofNullable(client).map(Client::getName).orElse(""));
        String startDate = formatDate(experiment.getStartDate());
        String endDate = formatDate(experiment.getEndDate());
        root.put("试验时间", StringUtils.joinWith(" ~ ", startDate, endDate));
        List<ExperimentRadiationProcess> radiationProcessList = experimentRadiationProcessService.getByExperimentId(experimentId);
        String collect = radiationProcessList.stream().map(v -> v.getRadiationSource()).collect(Collectors.joining(","));
        root.put("辐射源", collect);
        String temp = radiationProcessList.stream().map(v -> v.getEnvironmentalTemperature()).collect(Collectors.joining(","));
        root.put("温度", temp);
        ExperimentReport latestReport = experimentReportService.getLatestReport(experimentId);
        root.put("批准人员姓名", Optional.ofNullable(latestReport).map(v -> sysUserService.getById(v.getConfirmer()))
                .map(SysUser::getRealname).orElse(""));
        root.put("编制人员姓名", Optional.ofNullable(sysUserService.getUserByName(experiment.getCreateBy())).map(SysUser::getRealname)
                .orElse(""));
        List<Map<String, Object>> sampleList = new ArrayList<>();

        for (ExperimentRadiationProcess radiationProcess : radiationProcessList) {
            List<ExperimentSampleInfo> sampleInfoList = radiationProcess.getSampleInfoList();
            String radiationDetailJson = radiationProcess.getRadiationDetail();
            OptionalDouble maxPoint = OptionalDouble.empty();
            OptionalDouble maxRate = OptionalDouble.empty();
            if (StringUtils.isNotBlank(radiationDetailJson)) {
                RadiationMapDTO radiationMap = JSON.parseObject(radiationDetailJson, RadiationMapDTO.class);
                List<RadiationDetailDTO> detailDTOList = radiationMap.assembleDetails();
                maxPoint = detailDTOList.stream().map(obj -> obj.getPoint()) // 获取point字段
                        .filter(point -> StringUtils.isNotBlank(point))
                        .filter(str -> str.matches("-?\\d+(\\.\\d+)?")) // 只保留数字格式的字符串
                        .mapToDouble(Double::parseDouble) // 转换为double
                        .max();
                maxRate = detailDTOList.stream().map(obj -> obj.getActualMeasurementRate()) // 获取point字段
                        .filter(point -> StringUtils.isNotBlank(point))
                        .filter(str -> str.matches("-?\\d+(\\.\\d+)?")) // 只保留数字格式的字符串
                        .mapToDouble(Double::parseDouble) // 转换为double
                        .max();
            }
            for (int i = 0; i < sampleInfoList.size(); i++) {
                ExperimentSampleInfo sampleInfo = sampleInfoList.get(i);
                Map<String, Object> sample = new HashMap<>();
                sample.put("index", i + 1);
                sample.put("样品名称", sampleInfo.getSampleName());
                sample.put("样品型号", sampleInfo.getSampleModel());
                sample.put("样品类型", sampleInfo.getSampleType());
                sample.put("样品批次", sampleInfo.getSampleBatch());
                sample.put("样品编号", sampleInfo.getModelBatch());
                sample.put("注量率", maxRate.orElse(0));
                sample.put("总剂量", maxPoint.orElse(0));
                sampleList.add(sample);
            }
        }
        root.put("sample", sampleList);

        return root;
    }

    private Map<String, Object> assembleSybg(String experimentId, ExperimentReport experimentReport) {
        Experiment experiment = experimentService.getById(experimentId);
        experimentService.fetchExperimentDetail(experiment);
        if (Objects.isNull(experiment)) {
            return new HashMap<>();
        }
        Map<String, Object> params = new HashMap<>();
        if (Objects.nonNull(experimentReport)) {
            params.put("审核人员姓名", Optional.ofNullable(sysUserService.getById(experimentReport.getAuditor())).map(SysUser::getRealname)
                    .orElse(""));
            params.put("校对人员姓名", Optional.ofNullable(sysUserService.getById(experimentReport.getProofreader()))
                    .map(SysUser::getRealname)
                    .orElse(""));
            params.put("批准人员姓名", Optional.ofNullable(sysUserService.getById(experimentReport.getConfirmer()))
                    .map(SysUser::getRealname)
                    .orElse(""));
            params.put("报告生成日期", formatDate(experimentReport.getCreateTime()));
            params.put("批准日期", experimentReport.getConfirmerTime());
            params.put("校对日期", experimentReport.getProofreaderTime());
            params.put("审核日期", experimentReport.getAuditorTime());

        }
        params.put("试验报告名称", experiment.getName());
        params.put("试验编号", experiment.getExperimentNo());
        params.put("编制人员姓名", Optional.ofNullable(sysUserService.getUserByName(experiment.getCreateBy())).map(SysUser::getRealname)
                .orElse(""));
        Client client = clientService.getOne(new LambdaQueryWrapper<Client>().eq(Client::getName, experiment.getClientName()), false);
        params.put("委托方单位名称", Optional.ofNullable(client).map(Client::getName).orElse(""));
        params.put("委托方单位地址", Optional.ofNullable(client).map(Client::getAddress).orElse(""));
        List<ExperimentTestProcess> experimentTestProcesses = experimentTestProcessService.getByExperimentId(experiment.getId());
        if (CollUtil.isNotEmpty(experimentTestProcesses)) {
            ExperimentTestProcess experimentTestProcess = experimentTestProcesses.get(0);
            String testStandardsId = experimentTestProcess.getTestStandardsId();
            Optional<TestStandards> testStandards = Optional.ofNullable(testStandardsService.getById(testStandardsId));
            params.put("标准代号", testStandards.map(TestStandards::getCode).orElse(""));
            params.put("标准名称", testStandards.map(TestStandards::getName).orElse(""));
            Path lastPathEle = PathUtil.getLastPathEle(Path.of(testStandards.map(TestStandards::getAttachment).orElse("")).getFileName());
            params.put("依据的文件名称", lastPathEle.toString());

            String testParameters = experimentTestProcess.getTestParameters();
            if (StringUtils.isNotBlank(testParameters)) {
                JSONArray jsonObject = JSON.parseArray(testParameters);
                String collect = jsonObject.stream().map(v -> ((JSONObject) v).getString("name")).collect(Collectors.joining(","));
                params.put("测试参数", collect);
            }
            params.put("测试环境温度", experimentTestProcess.getEnvironmentalTemperature());
            params.put("测试环境湿度", experimentTestProcess.getEnvironmentalHumidity());
        }
        if (Objects.nonNull(experimentReport)) {
            String sampleInfo = experimentReport.getSampleInfo();
            if (StringUtils.isNotBlank(sampleInfo)) {
                List<JSONObject> sampleInfoList = JSON.parseArray(sampleInfo, JSONObject.class);
                if (CollUtil.isNotEmpty(sampleInfoList)) {
                    for (int i = 0; i < sampleInfoList.size(); i++) {
                        JSONObject info = sampleInfoList.get(i);
                        params.put("table" + i, Tables.of(
                                new String[][] {new String[] {"试验样品名称", getStringOrDefault(info, "sampleName"), "试验样品型号",
                                        getStringOrDefault(info, "sampleModel")},
                                        new String[] {"批     次", getStringOrDefault(info, "sampleBatch"), "试验样品编号",
                                                getStringOrDefault(
                                                        info,
                                                        "sampleType")},
                                        new String[] {"生产厂家", getStringOrDefault(info, "sampleManufacturer"), "试验样品数量",
                                                sampleInfoList.size() + ""},
                                        new String[] {"放置地点", "", "接收日期", ""},}).border(BorderStyle.DEFAULT).create());
                        String imgUrls = info.getString("picture");
                        if (StringUtils.isNotBlank(imgUrls)) {
                            if (!StringUtils.startsWith(imgUrls, "http")) {
                                imgUrls = "http://" + serverIp + imgUrls;
                            }
                            params.put("偏置原理图" + i, imgUrls);
                        }
                    }
                }
            }
        }
        params.put("试验日期", formatDate(experiment.getStartDate()) + " ~ " + formatDate(experiment.getEndDate()));
        params.put("负责人名称", experiment.getSupervisorName());
        params.put("剂量管理员名称", "");
        String operatorName = experiment.getExperimentUserList().stream().map(v -> v.getUserName()).collect(Collectors.joining(","));
        params.put("操作员名称", operatorName);
        List<ExperimentRadiationProcess> radiationProcessList = experimentRadiationProcessService.getByExperimentId(experimentId);
        if (CollUtil.isNotEmpty(radiationProcessList)) {
            radiationProcessList.forEach(radiationProcess -> {
                String radiationDetail = radiationProcess.getRadiationDetail();
                if (StringUtils.isNotBlank(radiationDetail)) {
                    RadiationMapDTO radiationMap = JSON.parseObject(radiationDetail, RadiationMapDTO.class);
                    List<RadiationDetailDTO> xgy = radiationMap.getXgy();
                    if (CollUtil.isNotEmpty(xgy)) {
                        extractDetail("小钴源", params, xgy, radiationProcess.getEnvironmentalTemperature());
                    }
                    List<RadiationDetailDTO> dgy = radiationMap.getDgy();
                    if (CollUtil.isNotEmpty(dgy)) {
                        extractDetail("大钴源", params, dgy, radiationProcess.getEnvironmentalTemperature());
                    }
                    List<RadiationDetailDTO> x = radiationMap.getX();
                    if (CollUtil.isNotEmpty(x)) {
                        extractDetail("X光机", params, x, radiationProcess.getEnvironmentalTemperature());
                    }
                    List<RadiationDetailDTO> electronics = radiationMap.getElectronics();
                    if (CollUtil.isNotEmpty(electronics)) {
                        extractDetail("电子加速器", params, electronics, radiationProcess.getEnvironmentalTemperature());
                    }
                    List<RadiationDetailDTO> proton = radiationMap.getProton();
                    if (CollUtil.isNotEmpty(proton)) {
                        extractDetail("质子加速器", params, proton, radiationProcess.getEnvironmentalTemperature());
                    }

                }
            });
        }
        params.put("辐照总注量", experiment.getExperimentNo());
        params.put("实际能量", experiment.getExperimentNo());

        if (Objects.nonNull(experimentReport)) {
            String imgUrls = experimentReport.getImgUrls();
            if (!StringUtils.startsWith(imgUrls, "http")) {
                imgUrls = "http://" + serverIp + imgUrls;
            }
            params.put("偏置原理图", imgUrls);
        }

        List<ExperimentDeviationEquipment> deviationEquipmentList = experiment.getDeviationEquipmentList();
        String[][] strings = new String[deviationEquipmentList.size() + 1][5];
        strings[0] = new String[] {"序号", "名称", "编号", "计量有效期", "备注"};

        if (CollUtil.isNotEmpty(deviationEquipmentList)) {
            for (int i = 0; i < deviationEquipmentList.size(); i++) {
                ExperimentDeviationEquipment deviationEquipment = deviationEquipmentList.get(i);
                strings[i + 1] = new String[] {(i + 1) + "", Optional.ofNullable(deviationEquipment.getEquipmentName()).orElse(""),
                        Optional.ofNullable(deviationEquipment.getEquipmentNo()).orElse(""), Optional.ofNullable(
                        deviationEquipment.getMeasurementValidity()).orElse(""), Optional.ofNullable(deviationEquipment.getRoomNo()).orElse(
                        ""),};
            }
        }
        params.put("装置表格", Tables.of(strings).border(BorderStyle.DEFAULT).create());
        return params;
    }

    private static void extractDetail(String name, Map<String, Object> params, List<RadiationDetailDTO> list, String temperature) {
        params.put("辐射源_" + name, "辐射源：" + name);
        String actualMeasurementRate = list.stream().map(x -> x.getActualMeasurementRate()).filter(point -> StringUtils.isNotBlank(point))
                .collect(Collectors.joining(","));
        String actualInjectionRate = list.stream().map(x -> x.getActualInjectionRate()).filter(point -> StringUtils.isNotBlank(point))
                .collect(Collectors.joining(","));
        String actualMeasurementPoint = list.stream().map(x -> x.getPoint()).filter(point -> StringUtils.isNotBlank(point)).collect(
                Collectors.joining(","));
        OptionalDouble maxMeasurementPoint = list.stream().map(obj -> obj.getPoint()) // 获取point字段
                .filter(point -> StringUtils.isNotBlank(point))
                .filter(str -> str.matches("-?\\d+(\\.\\d+)?")) // 只保留数字格式的字符串
                .mapToDouble(Double::parseDouble) // 转换为double
                .max();

        String electronEnergy = list.stream().map(x -> x.getElectronEnergy()).filter(point -> StringUtils.isNotBlank(point)).collect(
                Collectors.joining(","));
        params.put("辐射源_" + name + "_实际辐照剂量率",
                "实际辐照剂量率/实际辐照注量率：" + chooseStr(actualMeasurementRate, actualInjectionRate));
        params.put("辐射源_" + name + "_实际累积剂量点", "实际累积剂量点/实际累积注量点：" + chooseStr(actualMeasurementPoint, ""));
        params.put("辐射源_" + name + "_实际辐照总剂量",
                "实际辐照总剂量/实际辐照总注量：" + chooseStr(maxMeasurementPoint.getAsDouble() + "", ""));
        params.put("辐射源_" + name + "_实际辐射环境温度", "实际辐射环境温度：" + temperature + " ℃");
        if (StringUtils.equals(name, "电子加速器")) {
            params.put("辐射源_" + name + "_实际能量", "实际能量：" + chooseStr(electronEnergy, "") + " MeV");
        }
    }

    private static String chooseStr(String str1, String str2) {
        if (StringUtils.isNotBlank(str1) && !StringUtils.equals(str1, "null")) {
            return str1;
        }
        if (StringUtils.isNotBlank(str2) && !StringUtils.equals(str2, "null")) {
            return str2;
        }
        return "";
    }

    private Map<String, Object> assembleSbsyjlb(String experimentId) {
        List<ExperimentDeviationEquipment> equipmentList = experimentDeviationEquipmentService.getByExperimentId(experimentId);
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < equipmentList.size(); i++) {
            ExperimentDeviationEquipment v = equipmentList.get(i);
            Map<String, Object> params = new HashMap<>();
            params.put("index", i + 1);
            params.put("设备名称", Optional.ofNullable(v.getEquipmentName()).orElse(""));
            params.put("管理编号", Optional.ofNullable(v.getEquipmentNo()).orElse(""));
            String measurementValidity = v.getMeasurementValidity();
            params.put("使用日期", "");
            params.put("归还日期", "");
            params.put("计量有效期", Optional.ofNullable(measurementValidity).orElse(""));
            params.put("异常记录", "");
            list.add(params);
        }

        Experiment experiment = experimentService.getById(experimentId);
        Map<String, Object> root = new HashMap<>();
        root.put("equipment", list);
        root.put("试验编号", experiment.getExperimentNo());
        return root;
    }

    private Map<String, Object> assembleSybgpsb(String experimentId) {
        Experiment experiment = experimentService.getById(experimentId);
        experimentService.fetchExperimentDetail(experiment);
        if (Objects.isNull(experiment)) {
            return new HashMap<>();
        }
        ExperimentReport latestReport = experimentReportService.getLatestReport(experimentId);
        Map<String, Object> params = new HashMap<>();
        params.put("批准人员姓名", Optional.ofNullable(latestReport).map(v -> sysUserService.getById(v.getConfirmer()))
                .map(SysUser::getRealname).orElse(""));
        params.put("审核人名称", Optional.ofNullable(latestReport).map(v -> sysUserService.getById(v.getAuditor()))
                .map(SysUser::getRealname).orElse(""));
        params.put("校对人名称", Optional.ofNullable(latestReport).map(v -> sysUserService.getById(v.getProofreader()))
                .map(SysUser::getRealname).orElse(""));
        params.put("负责人名称", experiment.getSupervisorName());

        params.put("试验报告名称", experiment.getName());
        params.put("试验编号", experiment.getExperimentNo());
        params.put("校对驳回意见", Optional.ofNullable(latestReport).map(ExperimentReport::getProofreaderMemo).orElse(""));
        params.put("审核驳回意见", Optional.ofNullable(latestReport).map(ExperimentReport::getAuditorMemo).orElse(""));
        params.put("批准驳回意见", Optional.ofNullable(latestReport).map(ExperimentReport::getConfirmerMemo).orElse(""));

        return new HashMap<>();
    }

    private Map<String, Object> assembleFzsyjhb(String experimentId) {
        Experiment experiment = experimentService.getById(experimentId);
        Map<String, Object> root = new HashMap<>();
        root.put("试验编号", experiment.getExperimentNo());
        root.put("能量", "");
        root.put("束流", "");
        root.put("X能量", "");
        root.put("管电流", "");
        root.put("管电压", "");
        root.put("质子能量", "");
        root.put("面积", "");
        root.put("均衡性", "");
        return root;
    }

    @Override
    public ExperimentDoc generate(String experimentId, String type) {
        String version = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
        String filePath = generateExperimentDoc(experimentId, type, version);
        if (StringUtils.isNotBlank(filePath)) {
            ExperimentDoc experimentDoc = new ExperimentDoc();
            experimentDoc.setDocType(type);
            experimentDoc.setExperimentId(experimentId);
            experimentDoc.setFilePath(filePath);
            experimentDoc.setVersion(version);
            this.save(experimentDoc);
            return experimentDoc;
        }
        return null;
    }

    @Override
    public List<ExperimentDoc> getHistoryByExperimentId(String experimentId, String type) {
        return list(new LambdaQueryWrapper<ExperimentDoc>().eq(ExperimentDoc::getExperimentId, experimentId)
                .eq(ExperimentDoc::getDocType, type).orderByDesc(ExperimentDoc::getVersion));
    }

    @Override
    public ExperimentDoc getByExperimentId(String experimentId, String type) {
        return getOne(new LambdaQueryWrapper<ExperimentDoc>().eq(ExperimentDoc::getExperimentId, experimentId)
                .eq(ExperimentDoc::getDocType, type).orderByDesc(ExperimentDoc::getVersion), false);
    }

    private String getStringOrDefault(JSONObject jsonObject, String key) {
        String string = jsonObject.getString(key);
        if (StringUtils.isBlank(string)) {
            return "";
        }
        return string;
    }
}

