package digital.laboratory.platform.inspection.utils.datafile;

import cn.hutool.core.util.StrUtil;
import digital.laboratory.platform.inspection.constant.TestRecordSampleDataConstant;
import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct;
import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author xy
 * @version 1.0
 * @title NPSDataFile  文件是按 [ ] 分成不同的小节，我们只需要找到对应的小节进行数据读取即可
 * @description
 * @create 2024/1/9 11:59
 */
@Slf4j
public  class NPSDataFileUtil {
    //文件是按[]分成各小节，不同小节的解析不方式不同
    public static  List<NPSDataFileStruct> readDataFromText(String dataText) throws Exception{
        ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(dataText.getBytes());
        BufferedReader reader = new BufferedReader(new InputStreamReader(tInputStringStream));
        String currentLineContent="";//当前行
        String currentSectionContent="";//当前节点的内容
        int currentSectionIndex=0;//当前节点的序号
        List<NPSDataFileStruct> materialDataList=new ArrayList<>();
        NPSDataFileStruct npsDataFileStruct=null;//一个NPSDataFileStruct 对象代表一个检材样本
        //文件中，可能存在多个样本，因此应该生成多个对象
        while ((currentLineContent = reader.readLine()) != null) {
            if(StrUtil.isBlank(currentLineContent)) continue;
            String[] arrayLine = currentLineContent.split("\t");
            //如果当前行是以 [ 开始，以 ] 结束
            if (StrUtil.startWith(arrayLine[0], "[") && StrUtil.endWith(arrayLine[0], "]")) {
                // 开始新的 secion
                String tmp1= StrUtil.removePrefix(arrayLine[0], "[");//去掉左边中括号
                String tmp2= StrUtil.removeSuffix(tmp1, "]");//去掉右边中括号
                currentSectionContent=tmp2;
                npsDataFileStruct=handleSectionTitle(currentSectionContent,npsDataFileStruct);
                currentSectionIndex=npsDataFileStruct.getCurrentSection();
                if(currentSectionIndex==1){
                    materialDataList.add(npsDataFileStruct);
                }
            }else if(arrayLine.length>1){
                //如果不是空行且不是以 [ 开始，以 ] 结束，我们就解析数据
                //当然前提是知道他是哪个节点的数据，不同节点的数据，解析需求是不相同的。
                if(currentSectionIndex!=-1){
                    handleSectionContent(currentSectionIndex,arrayLine,npsDataFileStruct);
                }else{
                    System.out.println("对不起,未知的节点数据，请联系开发人员");
                }
            }
        }
        //输出结果
        log.info("此次一共解析样本{}条",materialDataList.size());
        log.info("解析内容如下：{}",materialDataList);
        return materialDataList;
    }
    private static NPSDataFileStruct handleSectionTitle(String lineSectionName, NPSDataFileStruct _npsDataFileStruct){
        //无论是一个检材还是几个检材，肯定先执行到的是header section
        if (StrUtil.equalsIgnoreCase(lineSectionName, "Header")) {
            _npsDataFileStruct=new NPSDataFileStruct();
            _npsDataFileStruct.setCurrentSection(1);
            return _npsDataFileStruct;
        }
        if (StrUtil.equalsIgnoreCase(lineSectionName, "File Information")) {
            _npsDataFileStruct.setCurrentSection(2);
            return _npsDataFileStruct;
        }
        if (StrUtil.equalsIgnoreCase(lineSectionName, "Sample Information")) {
            _npsDataFileStruct.setCurrentSection(3);
            return _npsDataFileStruct;
        }
        if (StrUtil.equalsIgnoreCase(lineSectionName, "Original Files")) {
            _npsDataFileStruct.setCurrentSection(4);
            return _npsDataFileStruct;
        }
        if (StrUtil.equalsIgnoreCase(lineSectionName, "File Description")) {
            _npsDataFileStruct.setCurrentSection(5);
            return _npsDataFileStruct;
        }
        if (StrUtil.equalsIgnoreCase(lineSectionName, "MS Quantitative Results")) {
            _npsDataFileStruct.setCurrentSection(6);
            return _npsDataFileStruct;
        }
        _npsDataFileStruct.setCurrentSection(-1);
        return _npsDataFileStruct;
    }

    /**
     * 处理不同节点的数据
     * @param sectionNo
     * @param arrayLine
     * @param _npsDataFileStruct
     */
    private static void handleSectionContent(int sectionNo,String[] arrayLine,NPSDataFileStruct _npsDataFileStruct){

        switch (sectionNo){
            case 1:
            {
                //如果是1，则表明是新的一份检材数据的开始
                if (StrUtil.equalsIgnoreCase(arrayLine[0], "Data File Name")) {
                    _npsDataFileStruct.setHeader_DataFileName((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Output Date")) {
                    _npsDataFileStruct.setHeader_OutputDate((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Output Time")) {
                    _npsDataFileStruct.setHeader_OutputTime((arrayLine.length > 1) ? arrayLine[1] : "");
                }
            }
            break;
            case 2:{
                if (StrUtil.equalsIgnoreCase(arrayLine[0], "Type")) {
                    _npsDataFileStruct.setFi_FileType((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Generated")) {
                    _npsDataFileStruct.setFi_FileGenerated((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Generated by")) {
                    _npsDataFileStruct.setFi_FileGeneratedBy((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Modified")) {
                    _npsDataFileStruct.setFi_FileModified((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Modified by")) {
                    _npsDataFileStruct.setFi_FileModifiedBy((arrayLine.length > 1) ? arrayLine[1] : "");
                }
            }
            break;
            case 3:{
                if (StrUtil.equalsIgnoreCase(arrayLine[0], "Operator Name")) {
                    _npsDataFileStruct.setSi_SampleOperatorName((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Analyzed")) {
                    _npsDataFileStruct.setSi_SampleAnalyzed((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Type")) {
                    _npsDataFileStruct.setSi_SampleType((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Level")) {
                    _npsDataFileStruct.setSi_SampleLevel((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Sample Name")) {
                    _npsDataFileStruct.setSi_SampleName(arrayLine[1]);
                }else if(StrUtil.equalsIgnoreCase(arrayLine[0], "Sample ID")) {
                    _npsDataFileStruct.setSi_SampleId((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Dilution Factor")) {
                    _npsDataFileStruct.setSi_SampleDilutionFactor((arrayLine.length > 1) ? arrayLine[1] : "");
                }
            }
            break;
            case 4:{
                if (StrUtil.equalsIgnoreCase(arrayLine[0], "Data File")) {
                    _npsDataFileStruct.setOf_DataFile((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Method File")) {
                    _npsDataFileStruct.setOf_MethodFile((arrayLine.length > 1) ? arrayLine[1] : "");
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Batch File")) {
                    _npsDataFileStruct.setOf_BatchFile((arrayLine.length > 1) ? arrayLine[1] : "");
                }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Tuning File")) {
                    _npsDataFileStruct.setOf_TuningFile((arrayLine.length > 1) ? arrayLine[1] : "");
                }
            }
            break;
            case 5:
            {
                System.out.println("这个节点没有数据");
            }
            break;
            case 6:
            {
                int dataNum = 0;
                //如果是该节下面的第一行，则表示的是数据条数
                if (StrUtil.equalsIgnoreCase(arrayLine[0], "# of IDs")) {
                    if (arrayLine.length > 1) {
                        dataNum = Integer.parseInt(arrayLine[1]);
                        _npsDataFileStruct.setMqr_DataCount(dataNum);
                    }
                }
                else if (StrUtil.equalsIgnoreCase(arrayLine[0], "ID#")) {
                    // 如果第一个值是“ID#”,那么这行就是表数据的表头
                    //_npsDataFileStruct.getMqrDataMap().
                    List<String> dataHeaderFieldList=Arrays.asList(arrayLine);
                    _npsDataFileStruct.setMqrDataHeaderList(dataHeaderFieldList);
                }
                else {
                    NPSTestDetailDataStruct dataObj=generateQuantitativeObj(arrayLine);
                    _npsDataFileStruct.getChildDataList().add(dataObj);
                }
            }
            break;
        }

    }
    //构建定量结果表对象
    private static NPSTestDetailDataStruct  generateQuantitativeObj(String[] rowData){
        NPSTestDetailDataStruct npsDataFileStructChild=new NPSTestDetailDataStruct();
        npsDataFileStructChild.setId(rowData[0]);
        npsDataFileStructChild.setName(rowData[1]);
        npsDataFileStructChild.setType(rowData[2]);
        npsDataFileStructChild.setMass(rowData[4]);
        if (rowData[5].equals("Not Identified")) {
            // 如果文件中存在这个信息，则证明这条数据是未检出的, 下面的值都默认设置为0
            npsDataFileStructChild.setNotIdentified(true);
            npsDataFileStructChild.setRetTime(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setStartTime(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setEndTime(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setArea(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setStdRetTime(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setSn(TestRecordSampleDataConstant.INVALID_VALUE);
            npsDataFileStructChild.setAbundanceRatio(TestRecordSampleDataConstant.INVALID_VALUE);//设置检材丰度比
            npsDataFileStructChild.setAbundanceRatio_std(TestRecordSampleDataConstant.INVALID_VALUE);//设置标准物质丰度比
            npsDataFileStructChild.setErrorRange(TestRecordSampleDataConstant.INVALID_VALUE);//设置丰度比偏差
            npsDataFileStructChild.setAbundanceRatioError(TestRecordSampleDataConstant.INVALID_VALUE);//设置偏差范围
            npsDataFileStructChild.setWithinError("/");//设置是否在误差范围内
            npsDataFileStructChild.setIsBasePeak(1);//设置他是基峰
        } else {
            npsDataFileStructChild.setRetTime(Double.parseDouble(rowData[5]));
            npsDataFileStructChild.setStartTime(Double.parseDouble(rowData[6]));
            npsDataFileStructChild.setEndTime(Double.parseDouble(rowData[7]));
            npsDataFileStructChild.setArea(Double.parseDouble(rowData[9]));
            npsDataFileStructChild.setStdRetTime(Double.parseDouble(rowData[14]));
            npsDataFileStructChild.setSn(Double.parseDouble(rowData[52]));
        }

        return npsDataFileStructChild;
    }
    //构建定性结果表对象
    private  void generateQualitativeObj(){

    }
    //构造定性结果表
}
