package digital.laboratory.platform.inspection.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.entity.TestRecordInstrument;
import digital.laboratory.platform.inspection.entity.TestRecordReagent;
import digital.laboratory.platform.inspection.entity.TestRecordSampleData;
import digital.laboratory.platform.inspection.entity.TestRecordSampleDataExpand;
import digital.laboratory.platform.inspection.enums.BusinessType;
import digital.laboratory.platform.inspection.enums.TestRecordFileUrl;
import digital.laboratory.platform.inspection.service.*;
import digital.laboratory.platform.inspection.vo.TestRecordSampleDataVO;
import digital.laboratory.platform.inspetion.api.entity.EntrustInfo;
import digital.laboratory.platform.inspetion.api.entity.SampleInfo;
import digital.laboratory.platform.inspetion.api.entity.TargetObject;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import digital.laboratory.platform.sys.enums.entrust.EntrustBiologyType;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ChenJiangBao
 * @version 1.0
 * @description: 生成检验记录相关接口实现类
 * @date 2025/3/18 14:50
 */
@Service
public class InspectRecordServiceImpl implements InspectRecordService {

    @Resource
    private OssFile ossFile;

    @Resource
    private EntrustInfoService entrustInfoService;

    @Resource
    private TestRecordService testRecordService;

    @Resource
    private TestRecordInstrumentService testRecordInstrumentService;

    @Resource
    private TestRecordSampleDataService testRecordSampleDataService;

    @Resource
    private TestRecordReagentService testRecordReagentService;

    @Resource
    private SampleInfoService sampleInfoService;

    @Resource
    private TestRecordSampledataExpandService testRecordSampledataExpandService;

    /**
     * 生成检验记录-贵阳禁毒
     *
     * @param entrustId    委托id
     * @param materialType 标注当前委托的检材是尿液还是毛发
     * @return
     * @throws Exception
     */
    @Override
    public R buildInspectionRecord(String entrustId, String materialType) throws Exception {
        EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);
        if (entrustInfo == null) {
            return R.ok(false, "委托信息不存在！");
        }
        if (entrustInfo.getBusinessType().equals(BusinessType.BOINT_CASE.getBusinessType())) {
            return R.ok(this.buildInVivoDocFile(entrustInfo, materialType), "生成成功!");
        }
        return R.ok(this.generateCommonDrugInpectRecord(entrustId));
    }

    /**
     * 生成生物样本检验记录数据map
     *
     * @param entrustInfo  委托实体信息
     * @param materialType 检材类型
     * @return
     * @throws Exception
     */
    public Map<String, Object> buildInVivoRecordData(EntrustInfo entrustInfo, String materialType) throws Exception {


        // 获取检验记录信息
        TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId());

        if (testRecord == null) {
            throw new Exception("未找到检验记录信息");
        }

        // 生成基础数据
        HashMap<String, Object> data = buildCommonInspectRecordDocMap(entrustInfo, testRecord, materialType);

        // 获取仪器设备数据（批量查询，减少数据库压力）
        List<String> deviceIdList = testRecord.getDeviceIdList();
        List<TestRecordInstrument> instruments = CollectionUtils.isEmpty(deviceIdList)
                ? Collections.emptyList()
                : testRecordInstrumentService.list(Wrappers.<TestRecordInstrument>lambdaQuery()
                .in(TestRecordInstrument::getId, deviceIdList));

        data.put("instrumentName", CollectionUtils.isEmpty(instruments)
                ? "未找到仪器设备数据!"
                : instruments.stream().map(TestRecordInstrument::getInstrumentName)
                .collect(Collectors.joining("\n")));

        // 获取样品数据
        List<TestRecordSampleData> dataList = testRecordSampleDataService.list(
                Wrappers.<TestRecordSampleData>lambdaQuery().eq(TestRecordSampleData::getTestId, testRecord.getId()));

        if (CollectionUtils.isEmpty(dataList)) {
            data.put("dataDtos", Collections.emptyList());
            data.put("sampleSize", 0);
            data.put("vo", testRecord);
            return data;
        }

        // 批量查询所有样品扩展数据，避免多次查询数据库
        Map<String, List<TestRecordSampleDataExpand>> dataExpandMap = testRecordSampledataExpandService.list(
                Wrappers.<TestRecordSampleDataExpand>lambdaQuery()
                        .in(TestRecordSampleDataExpand::getTestDataId, dataList.stream().map(TestRecordSampleData::getId).collect(Collectors.toList()))
        ).stream().collect(Collectors.groupingBy(TestRecordSampleDataExpand::getTestDataId));

        // 根据化合物名称分组
        Map<String, List<TestRecordSampleData>> dataMap = dataList.stream()
                .collect(Collectors.groupingBy(TestRecordSampleData::getCompoundName));

        List<TestRecordSampleDataVO> dataDtos = new ArrayList<>();

        // 遍历化合物组
        for (Map.Entry<String, List<TestRecordSampleData>> entry : dataMap.entrySet()) {
            String compoundName = entry.getKey();
            List<TestRecordSampleData> list = entry.getValue();

            // 添加空白数据
            TestRecordSampleDataVO blankVo = new TestRecordSampleDataVO();
            blankVo.setName("空白");
            blankVo.setCompoundName(compoundName);
            dataDtos.add(blankVo);

            // 根据样品类型分组
            Map<String, List<TestRecordSampleData>> map = list.stream()
                    .collect(Collectors.groupingBy(TestRecordSampleData::getSampleType));

            // 处理标准样品（STD）
            if (map.containsKey("STD")) {
                TestRecordSampleData std = map.get("STD").get(0);
                TestRecordSampleDataVO stdVo = new TestRecordSampleDataVO();
                BeanUtils.copyProperties(std, stdVo);
                stdVo.setName("空白添加");
                stdVo.setIsDetected(1);

                List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(std.getId());
                if (expandList != null) {
                    for (TestRecordSampleDataExpand expand : expandList) {
                        if (!expand.getBasePeak()) {
                            stdVo.setIonAbundanceRatio(expand.getIonAbundanceRatio());
                            stdVo.setIonAbundanceRatioError(expand.getIonAbundanceRatioError());
                            stdVo.setIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
                            break; // 只取第一个符合条件的扩展数据
                        }
                    }
                }
                dataDtos.add(stdVo);
            }

            // 处理检材样品（Analyte）
            if (map.containsKey("Analyte")) {
                List<TestRecordSampleData> analyte = map.get("Analyte");
                analyte.sort(testRecordSampleDataService.getSortBySampleNo());

                List<TestRecordSampleDataVO> dataVOS = new ArrayList<>();
                for (int i = 0; i < analyte.size(); i++) {
                    TestRecordSampleData item = analyte.get(i);
                    TestRecordSampleDataVO vo = new TestRecordSampleDataVO();
                    BeanUtils.copyProperties(item, vo);

                    List<TestRecordSampleDataExpand> expandList = dataExpandMap.get(item.getId());
                    if (expandList != null) {
                        for (TestRecordSampleDataExpand expand : expandList) {
                            if (!expand.getBasePeak()) {
                                vo.setIonAbundanceRatio(expand.getIonAbundanceRatio());
                                vo.setIonAbundanceRatioError(expand.getIonAbundanceRatioError());
                                vo.setIonAbundanceRatioWithinError(expand.getIonAbundanceRatioWithinError());
                                break; // 只取第一个符合条件的扩展数据
                            }
                        }
                    }

                    // 重新命名样品
                    vo.setName((analyte.size() == 1) ? "检材样品" : (i + 1) + "号检材样品");
                    dataVOS.add(vo);
                }
                dataDtos.addAll(dataVOS);
            }
        }

        // 返回处理后的数据
        data.put("dataDtos", dataDtos);
        data.put("sampleSize", dataDtos.size());
        data.put("inspectOpinion", this.buildInspectOpinion(dataList));
        return data;
    }


    /**
     * 根据委托信息和样本类型生成生物样本检验记录文件。
     *
     * @param entrustInfo  委托信息对象
     * @param materialType 样本类型（如"毛发"、"尿液"等）
     * @return 生成的生物样本检验记录文件的路径
     * @throws Exception 如果文件生成过程中出现错误，抛出异常
     */
    public String buildInVivoDocFile(EntrustInfo entrustInfo, String materialType) throws Exception {
        // 获取文件数据map
        Map<String, Object> data = this.buildInVivoRecordData(entrustInfo, materialType);
        // 调用模板生成检验记录
        String templatePath = "";
        if (materialType.equals("毛发")) {
            templatePath = "/template" + "/贵阳生物样本毛发检验记录模板.docx";
        } else {
            templatePath = "/template" + "/贵阳生物样本尿液检验记录模板.docx";
        }
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder().
                bind("dataDtos", policy).build();
        return buildDocFileAndUploadToOss(entrustInfo.getId(), templatePath, config, data);
    }

    /**
     * 根据委托信息、模板路径、配置和数据构建文档文件并上传到OSS
     *
     * @param entrustId    委托id
     * @param templatePath 模板文件路径
     * @param config       配置信息
     * @param data         要填充到模板中的数据
     * @return 上传后的文件路径
     * @throws Exception 可能抛出的异常
     */
    private String buildDocFileAndUploadToOss(String entrustId, String templatePath, Configure config, Map<String, Object> data) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ossFile.fileGet(templatePath, bos);
        byte[] templateArray = bos.toByteArray();
        ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
        bos.close();

        XWPFTemplate template = XWPFTemplate.compile(bis, config).render(data);
        NiceXWPFDocument document = template.getXWPFDocument();

//        XWPFTable table = document.getTables().get(3);
//        int sampleSize = (int) data.get("sampleSize");
//        //合并单元格
//
//        TableTools.mergeCellsVertically(table, 1, 1, sampleSize);

        bis.close();
        ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
        template.write(fosWord);
        template.close();
        ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
        fosWord.close();
        document.close();
        String path = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + entrustId + "/" + "贵阳生物样本检验记录.docx";
        ossFile.fileSave(path, fisWord);
        return path;
    }


    /**
     * 生成常规毒品的检验记录（贵阳禁毒）
     */
    public String generateCommonDrugInpectRecord(String entrustId) throws Exception {
        Map<String, Object> docMap = buildCommonDrugDocMap(entrustId);
        String templatePath = "/template" + "/贵阳禁毒常规毒品检验记录模板.docx";
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder().
                bind("dataDtos", policy).build();
        return buildDocFileAndUploadToOss(entrustId, templatePath, config, docMap);
    }

    /**
     * 构建常规毒品的检验记录数据
     *
     * @return
     */
    private Map<String, Object> buildCommonDrugDocMap(String entrustId) {
        EntrustInfo entrustInfo = entrustInfoService.getById(entrustId);

        // 这里因为检验记录实体并未关联业务id, 只能先查询实验数据，在通过实验数据获取到检验记录信息
        TestRecord testRecord = testRecordService.getTestRecordByBusinessId(entrustInfo.getId());

        // 封装数据到map中
        Map<String, Object> docMap = buildCommonInspectRecordDocMap(entrustInfo, testRecord, "");

        return docMap;
    }


    /**
     * 构建通用的检验记录文档映射
     *
     * @param entrustInfo  委托信息对象
     * @param materialType
     * @return 包含委托信息和检验记录信息的HashMap对象
     */
    private HashMap<String, Object> buildCommonInspectRecordDocMap(EntrustInfo entrustInfo, TestRecord testRecord, String materialType) {
        HashMap<String, Object> data = new HashMap<>();

        data.put("entrustDepartment", entrustInfo.getEntrustDepartment());
        data.put("deliver1Name", entrustInfo.getDeliver1Name());
        data.put("deliver2Name", entrustInfo.getDeliver2Name());
        // 受理日期
        data.put("acceptYear", entrustInfo.getAcceptDate().getYear());
        data.put("acceptMonth", entrustInfo.getAcceptDate().getMonthValue());
        data.put("acceptDay", entrustInfo.getAcceptDate().getDayOfMonth());

        // 检验日期
        data.put("inspectYear", testRecord.getTestStartDate().getYear());
        data.put("inspectMonth", testRecord.getTestStartDate().getMonthValue());
        data.put("inspectDay", testRecord.getTestStartDate().getDayOfMonth());

        data.put("acceptNo", entrustInfo.getAcceptNo());

        // 检材性状描述和检验要求成分
        List<SampleInfo> sampleInfoList = getSampleInfosByMaterialType(entrustInfo, materialType);
        String materialCharacterDesc = buildMaterialCharacterDesc(sampleInfoList);
        String targetObjectStr = sampleInfoList
                .stream()
                .flatMap(
                        sampleInfo -> {
                            String toJSONString = JSONArray.toJSONString(sampleInfo.getTargetObject());
                            List<TargetObject> drugLiteList = JSONArray.parseArray(toJSONString, TargetObject.class);
                            return drugLiteList.stream();
                        })
                .collect(Collectors.toList()) // 得到转换好的筛查物对象
                .stream()
                .map(TargetObject::getName)
                .collect(Collectors.toSet()) // 区筛查物对象名称并去重
                .stream()
                .collect(Collectors.joining("、")); // 拼接筛查物名称
        data.put("materialCharacterDesc", materialCharacterDesc);
        data.put("materialIngredient", targetObjectStr);

        // 设置使用的标准物质和试剂
        List<TestRecordReagent> references = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
                .in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
                .eq(TestRecordReagent::getCategory, "标准物质"));

        if (references == null || references.isEmpty()) {
            data.put("referenceMaterialName", "未找到试剂耗材数据!");
        } else {

            String referenceMaterialName = references.stream()
                    .map(reagent -> "\u2611" + " " + reagent.getReagentConsumableName())
                    .collect(Collectors.joining("\n"));

            data.put("referenceMaterialName", referenceMaterialName);
        }

        List<TestRecordReagent> reagents = testRecordReagentService.list(Wrappers.<TestRecordReagent>lambdaQuery()
                .in(TestRecordReagent::getId, testRecord.getReagentConsumablesList())
                .eq(TestRecordReagent::getCategory, "试剂"));

        if (reagents == null || reagents.isEmpty()) {
            data.put("reagentConsumableName", "未找到试剂耗材数据!");
        } else {
            String reagentConsumableName = reagents.stream()
                    .map(TestRecordReagent::getReagentConsumableName)
                    .collect(Collectors.joining("、"));
            data.put("reagentConsumableName", reagentConsumableName);
        }
        return data;
    }

    /**
     * 根据委托信息和检材类型获取检材信息列表
     *
     * @param entrustInfo  委托信息对象
     * @param materialType 检材类型, 毛发或尿液
     * @return 检材信息列表
     */
    private List<SampleInfo> getSampleInfosByMaterialType(EntrustInfo entrustInfo, String materialType) {
        List<SampleInfo> sampleInfoList = sampleInfoService.list(Wrappers.<SampleInfo>lambdaQuery().eq(SampleInfo::getBusinessId, entrustInfo.getId()));
        // 对检材进行筛选，如果materialType 不为空则进行操作
        if (StrUtil.isNotBlank(materialType)) {
            if (materialType.equals("毛发")) {
                sampleInfoList = sampleInfoList.stream()
                        .filter(o -> EntrustBiologyType.HAIR.equals(EntrustBiologyType.isExist(o.getForm())))
                        .collect(Collectors.toList());

            } else {
                // 尿液
                sampleInfoList = sampleInfoList.stream()
                        .filter(o -> EntrustBiologyType.URINE.equals(EntrustBiologyType.isExist(o.getForm())))
                        .collect(Collectors.toList());
            }
        }
        return sampleInfoList;
    }


    /**
     * 构建检材性状描述
     *
     * @param sampleInfoList 样本信息列表
     * @return 物料特性描述，如果无法构建则返回null
     */
    private String buildMaterialCharacterDesc(List<SampleInfo> sampleInfoList) {
        if (CollUtil.isEmpty(sampleInfoList)) {
            return StrUtil.EMPTY;
        }

        // 仅有一个样本时，直接返回
        if (sampleInfoList.size() == 1) {
            return "检材为" + sampleInfoList.get(0).getForm() + "。";
        }

        // 按 form 分组
        Map<String, List<SampleInfo>> sampleMapGroupByForm = sampleInfoList.stream()
                .collect(Collectors.groupingBy(SampleInfo::getForm));

        // 所有样本 form 相同
        if (sampleMapGroupByForm.size() == 1) {
            String form = sampleMapGroupByForm.keySet().iterator().next(); // 取唯一的 key
            String orderNoStr = sampleInfoList.stream()
                    .map(sample -> sample.getOrderNo() + "号")
                    .collect(Collectors.joining("、"));
            return orderNoStr + "检材均为" + form + "。";
        }

        // 存在多个 form 的情况
        List<String> descriptions = new ArrayList<>();
        sampleMapGroupByForm.forEach((form, value) -> {
            String orderNoStr = value.stream()
                    .map(sample -> sample.getOrderNo() + "号")
                    .collect(Collectors.joining("、"));
            descriptions.add(orderNoStr + "检材均为" + form);
        });

        return String.join("；", descriptions) + "。"; // 用分号连接不同类型的描述
    }

    public String buildInspectOpinion(List<TestRecordSampleData> dataList) {
        // 1. 检查输入的dataList是否为空，如果为空直接返回当前数据。
        if (dataList == null || dataList.isEmpty()) {
            return "";
        }

        // 2. 初始化数据结构，用于分类和记录检出与未检出的物质
        // - detectedMap 用来存储检出物质的样本信息，key为样本编号，value为检出的物质列表
        // - notDetectedMap 用来存储未检出物质的样本信息，key为样本编号，value为未检出的物质列表
        // - allCompoundNames 用来存储所有物质名称的集合，方便后续处理
        Map<String, List<String>> detectedMap = new LinkedHashMap<>();
        Map<String, List<String>> notDetectedMap = new LinkedHashMap<>();
        Set<String> allCompoundNames = new HashSet<>();

        // 3. 遍历dataList，按每个样本的检出状态（是否检出）对物质进行分类
        for (TestRecordSampleData record : dataList) {
            String sampleNo = record.getSampleNo(); // 获取样本编号
            String compoundName = record.getCompoundName(); // 获取化合物名称
            allCompoundNames.add(compoundName); // 将化合物名称添加到所有化合物名称集合中

            // 根据isDetected值将物质添加到相应的Map中
            if (record.getIsDetected() == 1) {
                detectedMap.computeIfAbsent(sampleNo, k -> new ArrayList<>()).add(compoundName); // 如果检出，将物质加入到检测的Map中
            } else {
                notDetectedMap.computeIfAbsent(sampleNo, k -> new ArrayList<>()).add(compoundName); // 如果未检出，将物质加入到未检测的Map中
            }
        }

        // 4. 定义一个lambda函数，提取样本编号中的流水号（例如："S001" -> "1号"）
        // 目的是生成以“号”结尾的样本编号格式。
        Function<String, String> extractSampleNumber = sampleNo -> sampleNo.substring(sampleNo.lastIndexOf('-') + 1) + "号";

        // 5. 处理“检出”数据
        // 先根据样本编号分组相同的检出物质，之后生成相应的语句描述
        List<String> detectedSentences = new ArrayList<>(); // 存储“检出”物质的描述
        Map<Set<String>, List<String>> groupedDetectedSamples = new LinkedHashMap<>(); // 用来存储按物质分组的样本编号

        // 遍历检测到的物质，将相同物质的样本编号进行分组
        for (Map.Entry<String, List<String>> entry : detectedMap.entrySet()) {
            Set<String> compoundSet = new HashSet<>(entry.getValue()); // 去重，保证每个物质只记录一次
            groupedDetectedSamples.computeIfAbsent(compoundSet, k -> new ArrayList<>()).add(extractSampleNumber.apply(entry.getKey())); // 根据物质的组合来分组样本编号
        }

        // 遍历每个分组，生成对应的描述
        for (Map.Entry<Set<String>, List<String>> entry : groupedDetectedSamples.entrySet()) {
            String sampleNumbers = String.join("、", entry.getValue()); // 将所有样本编号合并为字符串
            String compounds = String.join("、", entry.getKey()); // 将所有检出的物质合并为字符串

            // 如果多个样本检出相同的物质，描述中使用“均检出”，否则使用“检出”
            if (entry.getValue().size() > 1) {
                detectedSentences.add(String.format("从%s检材样品中均检出%s成分", sampleNumbers, compounds)); // 多个样本检出
            } else {
                detectedSentences.add(String.format("从%s检材样品中检出%s成分", sampleNumbers, compounds)); // 单个样本检出
            }
        }

        // 6. 处理“未检出”数据
        // 先根据未检出的物质及样本编号进行分组，然后生成相应的描述
        List<String> notDetectedSentences = new ArrayList<>(); // 存储“未检出”物质的描述
        Map<Set<String>, List<String>> groupedNotDetectedSamples = new LinkedHashMap<>(); // 用来存储按物质分组的样本编号

        // 遍历未检出的物质，找到未检出的样本并将其分组
        for (Map.Entry<String, List<String>> entry : notDetectedMap.entrySet()) {
            String sampleNo = entry.getKey(); // 获取样本编号
            if (detectedMap.containsKey(sampleNo)) {
                continue; // 如果该样本已经出现在检出组中，跳过，不再处理
            }

            Set<String> compoundSet = new HashSet<>(entry.getValue()); // 获取未检出的物质，去重
            groupedNotDetectedSamples.computeIfAbsent(compoundSet, k -> new ArrayList<>()).add(extractSampleNumber.apply(sampleNo)); // 将未检出的物质分组
        }

        // 遍历每个未检出物质的分组，生成描述
        for (Map.Entry<Set<String>, List<String>> entry : groupedNotDetectedSamples.entrySet()) {
            String sampleNumbers = String.join("、", entry.getValue()); // 将未检出的样本编号合并为字符串
            String compounds = String.join("、", entry.getKey()); // 将未检出的物质合并为字符串

            // 如果多个样本未检出相同的物质，描述中使用“均未检出”，否则使用“未检出”
            if (entry.getValue().size() > 1) {
                notDetectedSentences.add(String.format("从%s检材样品中均未检出%s成分", sampleNumbers, compounds)); // 多个样本未检出
            } else {
                notDetectedSentences.add(String.format("从%s检材样品中未检出%s成分", sampleNumbers, compounds)); // 单个样本未检出
            }
        }

        // 7. 将“检出”和“未检出”描述合并到最终结果中
        List<String> finalSentences = new ArrayList<>(detectedSentences); // 先将检出物质的描述加入
        finalSentences.addAll(notDetectedSentences); // 将未检出的描述添加到末尾

        // 8. 将最终的描述字符串添加到结果数据Map中，字段名为"detectionStr"返回结果
        return String.join("；", finalSentences);
    }


    public static void main(String[] args) {
        List<TestRecordSampleData> list = Arrays.asList(
                new TestRecordSampleData("1", "Sample1", "2025-1-1", "T1", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("2", "Sample1", "2025-1-1", "T1", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("3", "Sample1", "2025-1-1", "T1", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),

                new TestRecordSampleData("4", "Sample2", "2025-1-2", "T2", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("5", "Sample2", "2025-1-2", "T2", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 1, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("6", "Sample2", "2025-1-2", "T2", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),

                new TestRecordSampleData("7", "Sample3", "2025-1-3", "T3", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 1, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("8", "Sample3", "2025-1-3", "T3", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("9", "Sample3", "2025-1-3", "T3", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 1, "Analyte", "{}", "{}", 1, "THC"),

                new TestRecordSampleData("10", "Sample4", "2025-1-4", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("11", "Sample4", "2025-1-4", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("12", "Sample4", "2025-1-4", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),

                new TestRecordSampleData("10", "Sample4", "2025-1-5", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 0, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("11", "Sample4", "2025-1-5", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 1, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("12", "Sample4", "2025-1-5", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"),

                new TestRecordSampleData("10", "Sample4", "2025-1-6", "T4", "10", "5", "羟考酮", "0.5", 1.2, 5.5, 5.0, 1, "Analyte", "{}", "{}", 1, "Oxycodone"),
                new TestRecordSampleData("11", "Sample4", "2025-1-6", "T4", "10", "4", "海洛因", "0.4", 1.1, 5.4, 5.0, 0, "Analyte", "{}", "{}", 1, "Heroin"),
                new TestRecordSampleData("12", "Sample4", "2025-1-6", "T4", "10", "3", "四氢大麻酚", "0.6", 1.3, 5.6, 5.0, 0, "Analyte", "{}", "{}", 1, "THC"));

        String detectionStr = new InspectRecordServiceImpl().buildInspectOpinion(list);
        System.out.println(detectionStr);
    }
}
