package digital.laboratory.platform.inspetion.api.entity;

import lombok.Data;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author xy
 * @version 1.0
 * @title IdentificationBookDTO  提供给文书系统的数据格式
 * @description
 * @create 2024/3/11 10:12
 */
@Data
public class IdentificationBookDTO {
    private EntrustInfo entrustInfo;//委托信息
    private List<SampleInfo> sampleInfoList;//对应的检材
    private String testMethod;//检验方法
    private String testProcessDes;//检验过程
    private String testResult;//检验结果
    private String testOptUser;//检验人
    private String testStartDate;//检验开始日期
    private String testFinishDate;//检验完成日期

    // eg:1号检材中未检出四氢大麻酚，检出合成大麻素类物质MDMB-4en-PINACA；
    //    2号检材中未检出四氢大麻酚，检出合成大麻素类物质MDMB-4en-PINACA。

    private static   String getNumberByMaterialNo(String materialNo){
        Pattern pattern = Pattern.compile("\\d+");

        Matcher matcher = pattern.matcher(materialNo);

        while (matcher.find()) {
            return matcher.group(0);
        }
        return "";
    }
    public static void main(String[] args) {
        List<TestResult> sampleList=new ArrayList<>();
        TestResult t1=new TestResult();
        t1.setMaterialNo("1号");
        t1.setCompoundName("化合物1");
        t1.setIsFind(1);
        t1.setOrderNo(1);
        TestResult t2=new TestResult();
        t2.setMaterialNo("1号");
        t2.setCompoundName("化合物2");
        t2.setIsFind(1);
        t2.setOrderNo(1);
        TestResult t3=new TestResult();
        t3.setMaterialNo("1号");
        t3.setCompoundName("化合物3");
        t3.setIsFind(0);
        t3.setOrderNo(1);
        sampleList.add(t1);
        sampleList.add(t2);
        sampleList.add(t3);
        TestResult t4=new TestResult();
        t4.setMaterialNo("2号");
        t4.setCompoundName("化合物1");
        t4.setIsFind(0);
        t4.setOrderNo(2);
        TestResult t5=new TestResult();
        t5.setMaterialNo("2号");
        t5.setCompoundName("化合物2");
        t5.setIsFind(0);
        t5.setOrderNo(2);
        TestResult t6=new TestResult();
        t6.setMaterialNo("2号");
        t6.setCompoundName("化合物3");
        t6.setIsFind(1);
        t6.setOrderNo(2);
        sampleList.add(t4);
        sampleList.add(t5);
        sampleList.add(t6);

        TestResult t7=new TestResult();
        t7.setMaterialNo("3号");
        t7.setCompoundName("化合物1");
        t7.setIsFind(0);
        t7.setOrderNo(3);
        TestResult t8=new TestResult();
        t8.setMaterialNo("3号");
        t8.setCompoundName("化合物2");
        t8.setIsFind(0);
        t8.setOrderNo(3);
        TestResult t9=new TestResult();
        t9.setMaterialNo("3号");
        t9.setCompoundName("化合物3");
        t9.setIsFind(1);
        t9.setOrderNo(3);
        sampleList.add(t7);
        sampleList.add(t8);
        sampleList.add(t9);

        //按照检材编号先分组，这样的话，如果有n个检材，m个化合物，那么就会分成n组,每组中就m条数据
        Map<String, List<TestResult>> collectMap = sampleList.stream().collect(Collectors.groupingBy(m -> m.getMaterialNo()));
        //我们把每组中的List 数据再次分组，分组按检出和未检出分，这样就会得到2个组，一个组是检出的，一个组是未检出的
        Map<String, Map<Integer, List<TestResult>>> ret=new HashMap<>();
        collectMap.forEach((k,v)->{
            Map<Integer, List<TestResult>> tmp1Map= v.stream().collect(Collectors.groupingBy(m -> m.getIsFind()));
            ret.put(k,tmp1Map);
        });

        //将3条合并为一条
        //将检出和未检出合并成一条，创建一个对象来存储
        List<TestResultDetail> testResultDetailList=new ArrayList<>();
        ret.forEach((k,v)->{
            StringBuffer sb1=new StringBuffer();
            StringBuffer sb2=new StringBuffer();
            v.forEach((k1,v1)->{
                //这个map中只有2个值，第一个表示未检出的化合物，第2个表示检出的化合物
                if(k1==0){
                    //未检出
                    v1.forEach(item->{
                        sb1.append(item.getCompoundName()).append(",");
                    });
                }
                if(k1==1){
                    //检出
                    v1.forEach(item->{
                        sb2.append(item.getCompoundName()).append(",");
                    });
                }
            });
            if(sb1.length()>0){
                sb1.delete(sb1.length()-1,sb1.length());//删除最后一个 ,
            }
            if(sb2.length()>0){
                sb2.delete(sb2.length()-1,sb2.length());//删除最后一个 ,
            }
            //
            TestResultDetail eg=new TestResultDetail();
            eg.setMaterialNo(k);
            eg.setFindCompounds(sb2.toString());
            eg.setNoFindCompounds(sb1.toString());
            testResultDetailList.add(eg);
        });
        testResultDetailList.forEach(item->{
                String str1=item.getMaterialNo()+"检材中检出了"+item.getFindCompounds();
                String str2=item.getMaterialNo()+"检材中未检出"+item.getNoFindCompounds();
            System.out.println(str1);
            System.out.println(str2);
            System.out.println("-----------------------------");
        });
        //现在对上面的数据进行从新分组，按检出+化合物的形式
        Map<String, List<TestResultDetail>> temp2 = testResultDetailList.stream().collect(
                Collectors.groupingBy(m -> m.getFindCompounds() + m.getNoFindCompounds()));
        //这里需要排一个序，检材编号小的应该放在前面，大的放在后面，所以使用values中的值来给map进行排序
        List<Map.Entry<String, List<TestResultDetail>>> targetList=new ArrayList<Map.Entry<String, List<TestResultDetail>>>(temp2.entrySet());
        targetList.sort(new Comparator<Map.Entry<String, List<TestResultDetail>>>() {
            @Override
            public int compare(Map.Entry<String, List<TestResultDetail>> mp1, Map.Entry<String, List<TestResultDetail>> mp2) {
                int materialNo1 = getMinMaterialNo(mp1.getValue());
                int materialNo2 = getMinMaterialNo(mp2.getValue());
                return materialNo1-materialNo2;
            }
        });
        targetList.forEach((target)->{

            StringBuffer sbNo=new StringBuffer();

            target.getValue().forEach(item->{
                sbNo.append(item.getMaterialNo()).append(",");
            });
            if(sbNo.length()>0){
                sbNo.delete(sbNo.length()-1,sbNo.length());//删除最后一个 ,
            }
            System.out.println(sbNo.toString()+"检材未检出"+target.getValue().get(0).getNoFindCompounds()+"--- 检出了"+target.getValue().get(0).getFindCompounds());
        });
    }

    //获取检材中最小的一个检材编号
    private static int getMinMaterialNo(List<TestResultDetail> materialList){
        materialList.sort(new Comparator<TestResultDetail>() {
            @Override
            public int compare(TestResultDetail t1, TestResultDetail t2) {
                int mNo1= Integer.parseInt(getNumberByMaterialNo(t1.getMaterialNo()));
                int mNo2= Integer.parseInt(getNumberByMaterialNo(t2.getMaterialNo()));
                return mNo1-mNo2;
            }
        });
        return  Integer.parseInt(getNumberByMaterialNo(materialList.get(0).getMaterialNo()));
    }


}
