package cn.cslg.report.service.business;

import cn.cslg.report.common.model.PatentRightParams;
import cn.cslg.report.common.model.dto.FeaturesDTO;
import cn.cslg.report.common.model.dto.invalidReReport.CheckReFeaturesDTO;
import cn.cslg.report.common.model.vo.PatentRightVo;
import cn.cslg.report.common.model.vo.PatentVO;
import cn.cslg.report.common.model.vo.PersonnelVO;
import cn.cslg.report.common.model.vo.SplitVO;
import cn.cslg.report.common.model.vo.invalidReReport.QueryAllFeaturesVO;
import cn.cslg.report.common.utils.CacheUtils;
import cn.cslg.report.common.utils.PatentRightUtils;
import cn.cslg.report.common.utils.Response;
import cn.cslg.report.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.report.entity.*;
import cn.cslg.report.entity.asso.AssoRecordsFeature;
import cn.cslg.report.entity.asso.AssoTaskPatentSplit;
import cn.cslg.report.entity.asso.AssoTaskPersonel;
import cn.cslg.report.entity.invalidReReport.Arguments;
import cn.cslg.report.entity.invalidReReport.ProofStr;
import cn.cslg.report.entity.invalidReReport.AssoPositionFeatures;
import cn.cslg.report.mapper.FeatureMapper;
import cn.cslg.report.service.OutInterfaceService;
import cn.cslg.report.service.business.InvalidReReport.ArgumentsService;
import cn.cslg.report.service.business.InvalidReReport.AssoPositionFeaturesService;
import cn.cslg.report.service.business.InvalidReReport.ProofStrService;
import cn.cslg.report.service.business.InvalidReReport.InvalidReasonService;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
@SuppressWarnings({"all"})
public class FeatureService extends ServiceImpl<FeatureMapper, Features> {

    private final OutInterfaceService outInterfaceService;
    private final CacheUtils cacheUtils;
    private final ReportService reportService;
    private final LoginUtils loginUtils;
    private final FeatureMapper featureMapper;
    private final AssoRecordsFeatureService assoRecordsFeatureService;
    private final CompareRecordsService compareRecordsService;
    private final AssoTaskPersonelService assoTaskPersonelService;
    private final AssoTaskPatentSplitService assoTaskPatentSplitService;
    private final TaskService taskService;
    private final CompareMessageService compareMessageService;
    private final PatentRightUtils patentRightUtils;
    private final InvalidReasonService invalidReasonService;
    private final ProofStrService assoFeatureProofService;
    private final ArgumentsService argumentsService;
    private final AssoPositionFeaturesService assoPositionFeaturesService;

    /**
     * @param patentRights(专利权利要求)
     * @return List<PatentRight>
     * @function 对权要进行合并操作
     */

    public List<PatentRight> FormatPatentRights(List<PatentRight> patentRights, String patentNo) {
        StringBuilder stringBuilder = new StringBuilder();
        patentRights.forEach(item -> {
            stringBuilder.append(item.getContent());
        });

        StringBuilder stringBuilder2 = new StringBuilder();
        patentRights.forEach(item -> {
            stringBuilder2.append(item.getContentOut());
        });

        PatentRightParams params = new PatentRightParams();
        params.setPatentNo(patentNo);
        params.setPatentId(-1);
        params.setContent(stringBuilder.toString());
        params.setContentOut(stringBuilder2.toString());
        patentRights = patentRightUtils.formatPatentRight(params);
        return patentRights;
    }

    /**
     * @param patentNo  专利号
     * @param splitType 拆分类型
     * @param splitBy   拆分依据
     * @param reportId  报告id
     * @return 是否拆分成功
     * @throws IOException
     * @function 从PAS系统上获得权要并拆分
     */
    @Transactional(rollbackFor = Exception.class, timeout = 10)
    public String splitPatentRight(SplitVO splitVO) throws IOException {
        String patentNo = splitVO.getPatentNo();
        Integer reportId = splitVO.getReportId();
        Integer splitType = splitVO.getSplitType();
        Integer splitBy = splitVO.getSplitBy();
        Integer taskId = splitVO.getTaskId();
        Integer flag = 0;
        if (splitBy == null) {
            splitBy = 0;
        }
        if (splitType == null) {
            splitType = 0;
        }
        PersonnelVO personnelVO = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());
        //如果是FTO报告则 将拆分信息存入
        if (taskId != null) {
            //根据taskId获得报告ID
            Task task = taskService.getById(taskId);
            reportId = task.getReportId();
            //根据taskId 和专利号找到关联Id
            LambdaQueryWrapper<AssoTaskPersonel> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(AssoTaskPersonel::getTaskId, taskId)
                    .eq(AssoTaskPersonel::getPatentNo, patentNo);
            List<AssoTaskPersonel> assoTaskPersonels = assoTaskPersonelService.list(queryWrapper1);
            if (assoTaskPersonels != null && assoTaskPersonels.size() != 0) {
                //关联ID
                Integer assoId = assoTaskPersonels.get(0).getId();
                //根据关联ID 查询任务专利关联信息
                LambdaQueryWrapper<AssoTaskPatentSplit> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(AssoTaskPatentSplit::getTaskPatentId, assoId);
                List<AssoTaskPatentSplit> assoTaskPatentSplits = assoTaskPatentSplitService.list(queryWrapper);
                AssoTaskPatentSplit assoTaskPatentSplit = new AssoTaskPatentSplit();
                //如果没查到关联信息代表第一次拆分，新建一条
                if (assoTaskPatentSplits == null || assoTaskPatentSplits.size() == 0) {
                    assoTaskPatentSplit.setTaskPatentId(assoId);
                    assoTaskPatentSplit.setSplitBy(splitBy);
                    assoTaskPatentSplit.setSplitType(splitType);
                    assoTaskPatentSplit.insert();
                    flag = 1;
                } else {
                    assoTaskPatentSplit = assoTaskPatentSplits.get(0);
                    if (assoTaskPatentSplit.getSplitBy() != splitBy || assoTaskPatentSplit.getSplitType() != splitType) {
                        assoTaskPatentSplit.setSplitBy(splitBy);
                        assoTaskPatentSplit.setSplitType(splitType);
                        assoTaskPatentSplit.updateById();
                        flag = 1;
                    }
                }
            }
        } else {
            //根据报告ID查询报告
            LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(Report::getId, reportId);
            //未查到报告报错
            if (reportService.list(queryWrapper).size() == 0) {
                return Response.error("未查询到报告");
            }
            Report report = reportService.list(queryWrapper).get(0);
            //如果报告未拆分过权要，或者拆分类型不同则更新报告
            if (report.getSplitBy() == null || report.getSplitType() == null || report.getSplitBy() != splitBy || report.getSplitType() != splitType) {
                report.setSplitBy(splitBy);
                report.setSplitType(splitType);
                report.updateById();
                flag = 1;
            }
        }
        //权要（带拆分的特征）列表
        List<PatentRightVo> patentRightVos = new ArrayList<>();
        //从pas获得权要信息
        String resBody = outInterfaceService.getPatentRightFromPAS(patentNo);
        JSONObject jsonObject = JSONObject.parseObject(resBody);
        //解析jason获得标的专利的权要
        List<PatentRight> patentRightsOrgin = JSON.parseArray(jsonObject.getString("data"), PatentRight.class);
        //给权要进行格式更改
        List<PatentRight> patentRights = FormatPatentRights(patentRightsOrgin, patentNo);
        //List<Integer> partRightIds = new ArrayList<>();  //权要ids
        List<Integer> partRightSorts = new ArrayList<>();  //权要sorts
        List<String> flags = new ArrayList<>();
        // 当splitType=0仅拆解主权要
        if (splitType.equals(0)) {
            //partRightIds = patentRights.stream().filter(item -> item.getType().equals(1)).map(PatentRight::getId).collect(Collectors.toList());
            partRightSorts = patentRights.stream().filter(item -> item.getType().equals(1)).map(PatentRight::getSort).collect(Collectors.toList());
        }// 当splitType=1拆解全部权要
        else if (splitType.equals(1)) {
            //partRightIds = patentRights.stream().map(PatentRight::getId).collect(Collectors.toList());
            partRightSorts = patentRights.stream().map(PatentRight::getSort).collect(Collectors.toList());
        }
        //当splitBy=0时仅仅根据“,”拆解
        if (splitBy == 0) {
            flags.add(",");
            flags.add("，");
        }
        //当splitBy=1时仅仅根据“;“拆解
        else if (splitBy == 1) {
            flags.add(";");
            flags.add("；");
        }//当splitBy=2时根据“;“和”,”拆解
        else if (splitBy == 2) {
            flags.add(";");
            flags.add("；");
            flags.add(",");
            flags.add("，");
        }
        Integer a = splitBy;
        Integer b = splitType;
        Features featureTO = new Features();
        featureTO.setReportId(reportId);
        featureTO.setSignPatentNo(patentNo);
        featureTO.setPartnerId(personnelVO.getId());
        featureTO.setSplitType(splitType);
        featureTO.setSplitBy(splitBy);
        featureTO.setTaskId(taskId);
        //查询数据库里是否有拆分记录
        List<Features> featureFromDb = this.queryFeatures(featureTO);
        //删除所有不符合登录人拆分条件的拆分特征
        LambdaQueryWrapper<Features> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Features::getReportId, reportId)
                .eq(Features::getSignPatentNo, patentNo);
        wrapper.and(QueryWrapper -> QueryWrapper.ne(Features::getSplitBy, a).or().ne(Features::getSplitType, b));
        if (taskId != null) {
            List<Features> features = this.list(wrapper);
            List<Integer> Ids = features.stream().map(Features::getId).collect(Collectors.toList());
            if (Ids.size() != 0) {
                LambdaQueryWrapper<CompareMessage> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(CompareMessage::getFeatureId, Ids);
                compareMessageService.remove(queryWrapper);
            }
        }
        this.remove(wrapper);
        //将拆解的权要和特征装载到对象PatentRightVo
        for (int i = 0; i < patentRights.size(); i++) {
            //特征序号
            Integer order = 1;
            List<Features> featuresList = new ArrayList<>();
            int rightId = patentRights.get(i).getSort();
            String name = "权要" + (patentRights.get(i).getSort() + 1);
            //对需要拆解的权要进行拆解
            if (featureFromDb != null && featureFromDb.size() != 0) {
                featuresList = featureFromDb.stream().filter(item -> item.getRightId().equals(rightId) && item.getSplitBy().equals(a) && item.getPartnerId().equals(personnelVO.getId()) && item.getSplitType().equals(b)).collect(Collectors.toList());
            }
            //如果数据库里无拆解记录则手动插入一条
            if (featuresList == null || featuresList.size() == 0 || flag == 1) {
                featuresList = new ArrayList<>();
                List<String> contentOuts = Arrays.asList(patentRights.get(i).getContentOut());
                List<String> contents = Arrays.asList(patentRights.get(i).getContent());
                //如果是需要拆解的权要
                if (partRightSorts.contains(patentRights.get(i).getSort())) {
                    //获得权要的译文并且拆解
                    contentOuts = this.splitStringByFlags(patentRights.get(i).getContentOut(), flags);
                    //获得权要的原文并且拆解
                    contents = this.splitStringByFlags(patentRights.get(i).getContent(), flags);
                }
                //遍历拆解出来的内容并装载到features最后存入列表
                for (int t = 0; t < contents.size(); t++) {
                    Features features = new Features();
                    features.setRightId(patentRights.get(i).getSort());
                    features.setIsFinal(0);
                    features.setSignPatentNo(patentNo);
                    features.setReportId(reportId);
                    String countOut = contentOuts.size() - 1 >= t ? contentOuts.get(t) : "";
                    features.setContentOut(countOut);
                    features.setContent(contents.get(t));
                    features.setSplitBy(splitBy);
                    features.setPartnerId(personnelVO.getId());
                    features.setRightName(name);
                    features.setFeaturesOrder(order);
                    features.setRightType(patentRights.get(i).getType());
                    features.setSplitType(splitType);
                    if (taskId != null) {
                        features.setTaskId(taskId);
                    }
                    featuresList.add(features);
                    order += 1;
                }
                this.saveBatch(featuresList);
            }
            //装载到对象PatentRightVo
            PatentRightVo patentRightVo = new PatentRightVo();
            patentRightVo.setPatentId(patentRights.get(i).getPatentId());
            patentRightVo.setFeatures(featuresList);
            patentRightVo.setContent(patentRights.get(i).getContent());
            patentRightVo.setSort(patentRights.get(i).getSort());
            patentRightVo.setType(patentRights.get(i).getType());
            patentRightVo.setContentOut(patentRights.get(i).getContentOut());
            patentRightVo.setReportId(reportId);
            patentRightVo.setRightName(name);
            patentRightVo.setSignPatentNo(patentNo);
            patentRightVos.add(patentRightVo);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("patentRightVos", patentRightVos);
        map.put("splitBy", splitBy);
        map.put("splitType", splitType);
        return Response.success(map);
    }

    /**
     * @param patentNos 专利号
     * @param reportId  报告id
     * @return map
     * @throws IOException
     * @function 根据报告id 和专利号查询专利特征表
     */
    public String getFeatures(String patentNos, Integer reportId) throws IOException {

        LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Report::getId, reportId);
        if (reportService.list(queryWrapper).size() == 0) {
            return "";
        }
        Report report = reportService.list(queryWrapper).get(0);
        //权要（带拆分的特征）列表
        List<PatentRightVo> patentRightVos = new ArrayList<>();
        String patentNo = report.getSignPatentNo();
        //从pas获得权要信息
        if (patentNos != null) {
            patentNo = patentNos;
        }
        String resBody = outInterfaceService.getPatentRightFromPAS(patentNo);
        JSONObject jsonObject = JSONObject.parseObject(resBody);
        //解析jason获得标的专利的权要
        List<PatentRight> patentRightsOrgin = JSON.parseArray(jsonObject.getString("data"), PatentRight.class);
        //处理权要
        List<PatentRight> patentRights = FormatPatentRights(patentRightsOrgin, patentNo);
        Features featureTO = new Features();
        featureTO.setReportId(reportId);
        featureTO.setSignPatentNo(patentNo);
        featureTO.setPartnerIds(Arrays.asList(report.getPersonId(), report.getCreatePersonId()));

        //查询数据库里是否有查询记录
        List<Features> featureFromDb = this.queryFeatures(featureTO);
        //将拆解的权要和特征装载到对象PatentRightVo
        for (int i = 0; i < patentRights.size(); i++) {

            List<Features> featuresList = new ArrayList<>();
            //对需要拆解的权要进行拆解
            if (featureFromDb != null && featureFromDb.size() != 0) {
                int rightId = patentRights.get(i).getSort();
                featuresList = featureFromDb.stream().filter(item -> item.getRightId().equals(rightId) && (item.getPartnerId().equals(report.getPersonId()) || item.getPartnerId().equals(report.getCreatePersonId()))).collect(Collectors.toList());
            }
            //装载到对象PatentRightVo
            PatentRightVo patentRightVo = new PatentRightVo();
            String name = "权要" + (patentRights.get(i).getSort() + 1);
            patentRightVo.setPatentId(patentRights.get(i).getPatentId());
            patentRightVo.setFeatures(featuresList);
            patentRightVo.setContent(patentRights.get(i).getContent());
            patentRightVo.setSort(patentRights.get(i).getSort());
            patentRightVo.setType(patentRights.get(i).getType());
            patentRightVo.setContentOut(patentRights.get(i).getContentOut());
            patentRightVo.setReportId(reportId);
            patentRightVo.setRightName(name);
            patentRightVo.setSignPatentNo(patentNo);
            patentRightVos.add(patentRightVo);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("patentRightVos", patentRightVos);
        map.put("splitBy", report.getSplitBy());
        map.put("splitType", report.getSplitType());
        return Response.success(map);
    }

    //根据符号拆分字符串
    public List<String> splitStringByFlags(String sentence, List<String> flags) {
        List<String> sectences = new ArrayList<>();
//如果字符串为空则返回一个包含空字符串的list
        if (sentence == null) {
            sectences.add("");
            return sectences;
        }
        sectences.add(sentence);
        for (int i = 0; i < flags.size(); i++) {
            List<String> tem = new ArrayList<>();
            for (int t = 0; t < sectences.size(); t++) {
                List<String> attrs = Arrays.asList(sectences.get(t).split(flags.get(i)));
                for (int v = 0; v < attrs.size(); v++) {
                    if (v < attrs.size() - 1) {
                        attrs.set(v, attrs.get(v) + flags.get(i));
                    }
                    if (attrs.get(v).equals("其特征在于" + flags.get(i))) {
                        tem.set(tem.size() - 1, tem.get(tem.size() - 1) + attrs.get(v));
                    } else {
                        tem.add(attrs.get(v));
                    }
                }
            }
            sectences = tem;

        }
        return sectences;

    }

    /**
     * @author lrj
     * @deprecated 查询特征
     */
    public List<Features> queryFeatures(Features features) {
        List<Features> featureList = new ArrayList<>();
        LambdaQueryWrapper<Features> lambdaQueryWrapper = new LambdaQueryWrapper();
        if (features.getRightId() != null) {
            lambdaQueryWrapper.eq(Features::getRightId, features.getRightId());
        }
        if (features.getIsFinal() != null) {
            lambdaQueryWrapper.eq(Features::getIsFinal, features.getIsFinal());
        }
        if (features.getPartnerId() != null) {
            lambdaQueryWrapper.eq(Features::getPartnerId, features.getPartnerId());
        }
        if (features.getSignPatentNo() != null) {
            lambdaQueryWrapper.eq(Features::getSignPatentNo, features.getSignPatentNo());
        }
        if (features.getReportId() != null) {
            lambdaQueryWrapper.eq(Features::getReportId, features.getReportId());
        }
        if (features.getSplitType() != null) {
            lambdaQueryWrapper.eq(Features::getSplitType, features.getSplitType());
        }
        if (features.getPartnerIds() != null && features.getPartnerIds().size() > 0) {
            lambdaQueryWrapper.in(Features::getPartnerId, features.getPartnerIds());

        }
        if (features.getTaskId() != null) {
            lambdaQueryWrapper.eq(Features::getTaskId, features.getTaskId());
        }
        featureList = this.list(lambdaQueryWrapper);
        return featureList;
    }

    /**
     * @author 李仁杰
     * @deprecated 保存特征
     */
    @Transactional(rollbackFor = Exception.class)
    public String addFeatures(List<PatentRightVo> patentRightVos) {
        // 获取登录人信息
        PersonnelVO personnelVO = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());
        List<Features> features = new ArrayList<>();
        //根据登录人Id,报告Id,标的专利号查询特征
        LambdaQueryWrapper<Features> wrapper = new LambdaQueryWrapper<>();
        if (patentRightVos.get(0).getReportId() != null && patentRightVos.get(0).getSignPatentNo() != null) {
            wrapper.eq(Features::getReportId, patentRightVos.get(0).getReportId())
                    .eq(Features::getSignPatentNo, patentRightVos.get(0).getSignPatentNo());
            Features feature = this.list(wrapper).get(0);
            //根据登录人Id,报告Id,标的专利号删除原有特征
            this.remove(wrapper);
            for (int i = 0; i < patentRightVos.size(); i++) {
                int order = 1;
                PatentRightVo patentRightVo = patentRightVos.get(i);
                if (patentRightVo.getFeatures() != null && patentRightVo.getFeatures().size() != 0) {
                    List<Features> tem = patentRightVo.getFeatures();
                    for (int t = 0; t < tem.size(); t++) {
                        tem.get(t).setFeaturesOrder(order);
                        tem.get(t).setPartnerId(feature.getPartnerId());
                        tem.get(t).setSplitBy(feature.getSplitBy());
                        tem.get(t).setSplitType(feature.getSplitType());
                        tem.get(t).setId(null);
                        order += 1;
                        features.add(tem.get(t));
                    }
                }
            }
        }
        this.saveOrUpdateBatch(features);
        return Response.success();
    }


    public List<Map<String, Object>> querySimFeaturePatent(PatentVO patentVO) throws IOException {
        //获得当前用户信息
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        //根据报告Id,拆分人Id,标的专利号获得特征。
        LambdaQueryWrapper<Features> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Features::getReportId, patentVO.getReportId())
                .eq(Features::getPartnerId, personnelVO.getId());
        List<Features> features = this.list(queryWrapper);
        LambdaQueryWrapper<Report> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Report::getId, patentVO.getReportId());
        Report report = reportService.list(lambdaQueryWrapper).get(0);
        String signPatentNo = report.getSignPatentNo();
        //获得特征内容
        List<String> contents = features.stream().map(Features::getContent).collect(Collectors.toList());
        List<Features> featuresList = featureMapper.getSignPatentNo(contents, signPatentNo);
        if (featuresList.size() == 0) {
            return new ArrayList<Map<String, Object>>();
        }
        //根据特征Id 查询 对比记录特征关联信息
        List<Integer> featureIds = featuresList.stream().map(Features::getId).collect(Collectors.toList());
        List<AssoRecordsFeature> assoRecordsFeatures = new ArrayList<>();
        List<CompareRecords> compareRecords = new ArrayList<>();
        if (featureIds != null & featureIds.size() > 0) {
            LambdaQueryWrapper<AssoRecordsFeature> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.in(AssoRecordsFeature::getFeatureId, featureIds);
            assoRecordsFeatures = assoRecordsFeatureService.list(queryWrapper1);
            // 根据关联信息获得对比记录ID
            List<Integer> recordsId = assoRecordsFeatures.stream().map(AssoRecordsFeature::getRecordsId).collect(Collectors.toList());
            //根据对比记录ID获得对比记录信息
            LambdaQueryWrapper<CompareRecords> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.in(CompareRecords::getId, recordsId);
            compareRecords = compareRecordsService.list(queryWrapper2);
        }
        //装载信息
        List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
        //装载特征对应划出的话
        while (featuresList.size() > 0) {
            Map<String, Object> map = new HashMap<>();
            List<Map<String, Object>> temMapList = new ArrayList<>();
            Features features1 = featuresList.get(0);
            Map<String, Object> Map = new HashMap<>();
            List<Integer> recordIds = assoRecordsFeatures.stream().filter(item -> item.getFeatureId().equals(featuresList.get(0).getId())).map(AssoRecordsFeature::getRecordsId).collect(Collectors.toList());
            List<CompareRecords> PartRecords = compareRecords.stream().filter(item -> recordIds.contains(item.getId())).collect(Collectors.toList());
            if (PartRecords != null && PartRecords.size() > 0) {
                Map.put("feature", featuresList.get(0));
                Map.put("CompareRecords", PartRecords);
                temMapList.add(Map);
            }
            featuresList.remove(features1);
            map.put("signPatentNo", features1.getSignPatentNo());
            for (Features tem : featuresList) {
                if (tem.getSignPatentNo().equals(features1.getSignPatentNo())) {
                    Map<String, Object> temMap = new HashMap<>();
                    List<Integer> recordId = assoRecordsFeatures.stream().filter(item -> item.getFeatureId().equals(tem.getId())).map(AssoRecordsFeature::getRecordsId).collect(Collectors.toList());
                    List<CompareRecords> PartRecord = compareRecords.stream().filter(item -> recordIds.contains(item.getId())).collect(Collectors.toList());
                    if (PartRecords != null && PartRecords.size() > 0) {
                        temMap.put("feature", tem);
                        temMap.put("CompareRecords", PartRecords);
                        temMapList.add(temMap);
                    }
                    features.remove(tem);
                }
            }
            if (temMapList.size() != 0) {
                map.put("features", temMapList);
                mapList.add(map);
            }
        }
        return mapList;
    }

    public Features select(int id) {
        LambdaQueryWrapper<Features> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Features::getId, id);
        if (this.list(queryWrapper).size() == 0) {
            return null;
        }
        return this.list(queryWrapper).get(0);
    }


    @Transactional(rollbackFor = Exception.class)
    public Integer delByReportId(int reportId) {
        LambdaQueryWrapper<Features> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Features::getReportId, reportId);
        this.remove(queryWrapper);
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    public List<PatentRight> getRightNames(String patentNo) throws IOException {
        Map<Integer, Object> map = new HashMap<>();
        String resBody = outInterfaceService.getPatentRightFromPAS(patentNo);
        JSONObject jsonObject = JSONObject.parseObject(resBody);
        //解析jason获得标的专利的权要
        List<PatentRight> patentRightsOrgin = JSON.parseArray(jsonObject.getString("data"), PatentRight.class);
        StringBuilder stringBuilder = new StringBuilder();
        patentRightsOrgin.forEach(
                item -> {
                    stringBuilder.append(item.getContent());
                }
        );
        PatentRightParams params = new PatentRightParams();
        params.setContent(stringBuilder.toString());
        params.setPatentNo(patentNo);
        List<PatentRight> patentRights = PatentRightUtils.formatPatentRight(params);
        patentRights.forEach(item -> {
            item.setRightName("权要" + (item.getSort() + 1));
        });
        return patentRights;
    }

    /**
     * 添加单个特征
     *
     * @param featuresDTO
     * @return
     * @throws IOException
     */
    @Transactional(rollbackFor = Exception.class)
    public String addSingleFeature(FeaturesDTO featuresDTO) throws IOException {
        //判断报告id和权要序号是否为空
        if (featuresDTO.getReportId() == null || featuresDTO.getRightId() == null) {
            return Response.error("判断报告id或权要序号为空");
        }
        Report report = reportService.getById(featuresDTO.getReportId());
        String patentNo = report.getSignPatentNo();
        //装载检查特征类
        CheckReFeaturesDTO checkReFeaturesDTO = new CheckReFeaturesDTO();
        checkReFeaturesDTO.setReportId(featuresDTO.getReportId());
        checkReFeaturesDTO.setRightSort(featuresDTO.getRightId());
        CheckReFeaturesDTO.featuresIn featuresIn = new CheckReFeaturesDTO.featuresIn();
        featuresIn.setFeatureStr(featuresDTO.getContent());
        featuresIn.setPosition(featuresDTO.getPosition());
        checkReFeaturesDTO.setFeatures(Arrays.asList(featuresIn));
        if (checkReFeaturesDTO.getFeatures().get(0).getPosition() == null) {
            //检查权要是否有此特征
            checkReFeaturesDTO = this.getFeaturePosition(checkReFeaturesDTO, patentNo);
            if (checkReFeaturesDTO == null) {
                return Response.error("权要里无此特征");
            } else if (checkReFeaturesDTO.getFeatures().get(0).getPosition() == null) {
                return Response.error("特征已被添加");
            }
        }
        Boolean flag = invalidReasonService.checkReFeatures(checkReFeaturesDTO);

        if (!flag) {
            return Response.error("特征有交集");
        }
        //查询证据表，取出该报告已有证据最大排序序号
        List<Features> featuresList = this.list(new LambdaQueryWrapper<Features>().eq(Features::getReportId, featuresDTO.getReportId()).eq(Features::getRightId, featuresDTO.getRightId()).orderByDesc(Features::getFeaturesOrder));
        Integer biggestSort;
        //若该报告目前没有证据，则最大排序序号设为0；若有则最大排序序号就是当前按序号倒序的第一个证据的排序序号
        if (featuresList == null || featuresList.size() == 0) {
            biggestSort = 1;
        } else {
            biggestSort = featuresList.get(0).getFeaturesOrder() + 1;
        }
        Features features = new Features();
        features.setContent(featuresDTO.getContent());
        features.setRightId(featuresDTO.getRightId());
        features.setReportId(featuresDTO.getReportId());
        features.setFeaturesOrder(biggestSort);
        features.setSignPatentNo(patentNo);
        features.insert();
        AssoPositionFeatures assoPositionFeatures = new AssoPositionFeatures();
        assoPositionFeatures.setFeaturesID(features.getId());
        assoPositionFeatures.setPosition(checkReFeaturesDTO.getFeatures().get(0).getPosition());
        assoPositionFeatures.insert();
        return Response.success(features.getId());
    }

    //获得特征的位置
    public CheckReFeaturesDTO getFeaturePosition(CheckReFeaturesDTO checkReFeaturesDTO, String patentNo) throws IOException {
        List<PatentRight> patentRights = this.getRightNames(patentNo);
        //获得权要
        PatentRight patentRight = patentRights.stream().filter(item -> item.getSort().equals(checkReFeaturesDTO.getRightSort())).findFirst().orElse(null);
        String patentRightContent = patentRight.getContent();
        //获得特征
        String featureStr = checkReFeaturesDTO.getFeatures().get(0).getFeatureStr();
        //获得所有的特征起始位置
        List<Integer> indexs = new ArrayList<>();
        Integer index = patentRightContent.indexOf(featureStr);
        indexs.add(index);
        while (index != -1) {
            //这里 Index+1 是为了检索下一个的时候，位置需要向后挪1个字符，而不是挪 son.length 长度
            index += 1;
            index = patentRightContent.indexOf(featureStr, index);
            indexs.add(index);
        }
        //获得已经保存的特征
        List<QueryAllFeaturesVO> queryAllFeaturesVOS = featureMapper.queryAllFeatures(checkReFeaturesDTO.getReportId(), checkReFeaturesDTO.getRightSort());
        if (indexs.size() == 0 || (indexs.size() == 1 && indexs.get(0).equals(-1))) {
            return null;
        }
        //遍历寻找未选择的特征
        for (Integer item : indexs) {
            QueryAllFeaturesVO queryAllFeaturesVO = queryAllFeaturesVOS.stream().filter(tem -> tem.getFeatureStr().equals(featureStr) && tem.getPosition().equals(item)).findFirst().orElse(null);
            if (queryAllFeaturesVO == null && item != -1) {
                checkReFeaturesDTO.getFeatures().get(0).setPosition(item);
                break;
            }
        }
        return checkReFeaturesDTO;

    }


    private void CalculateNum(String father, String son, Integer reportId, Integer rightId) {
        int index = father.indexOf(son);
        while (index != -1) {
            //这里 Index+1 是为了检索下一个的时候，位置需要向后挪1个字符，而不是挪 son.length 长度
            index += 1;
            index = father.indexOf(son, index);
        }
        List<QueryAllFeaturesVO> queryAllFeaturesVOS = featureMapper.queryAllFeatures(reportId, rightId);
    }

    /**
     * 添加单个特征
     *
     * @param featuresDTO
     * @return
     * @throws IOException
     */
    @Transactional(rollbackFor = Exception.class)
    public String deleteSingleFeature(Integer featureId) throws IOException {
        if (featureId == null) {
            return Response.error("请选择特征");
        }
        //检查陈述意见是否有关联的特征
        LambdaQueryWrapper<Arguments> argumentsWrapper = new LambdaQueryWrapper<>();
        argumentsWrapper.eq(Arguments::getFeatureId, featureId);
        List<Arguments> arguments = argumentsService.list(argumentsWrapper);
        if (arguments.size() > 0) {
            return Response.error("此特征和陈述意见有关联");
        }
        LambdaQueryWrapper<ProofStr> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProofStr::getFeatureId, featureId);
        assoFeatureProofService.remove(wrapper);
        LambdaQueryWrapper<AssoPositionFeatures> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(AssoPositionFeatures::getFeaturesID, featureId);
        assoPositionFeaturesService.remove(wrapper1);
        this.removeById(featureId);
        return Response.success();
    }

    //获得特征列表
    public String getFeatureList(Integer reportId, Integer rightSort) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (reportId == null || rightSort == null) {
            return Response.error("请输入报告id和权要序号");
        }
        Report report = reportService.getById(reportId);
        LambdaQueryWrapper<Features> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Features::getRightId, rightSort)
                .eq(Features::getReportId, reportId)
                .eq(Features::getSignPatentNo, report.getSignPatentNo())
                .orderByAsc(Features::getFeaturesOrder);
        List<Features> features = this.list(queryWrapper);
        //过滤获得特征id
        List<Integer> ids = features.stream().map(Features::getId).collect(Collectors.toList());
        List<AssoPositionFeatures> assoPositionFeatures = new ArrayList<>();
        if (ids.size() > 0) {
            LambdaQueryWrapper<AssoPositionFeatures> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.in(AssoPositionFeatures::getFeaturesID, ids);
            assoPositionFeatures = assoPositionFeaturesService.list(queryWrapper1);

        }
        for (Features item : features) {
            AssoPositionFeatures assoPositionFeature = assoPositionFeatures.stream().filter(tem -> tem.getFeaturesID().equals(item.getId())).findFirst().orElse(new AssoPositionFeatures());
            Map<String, Object> map = new HashMap<>();
            map.put("featureId", item.getId());
            map.put("content", item.getContent());
            map.put("featureName", "特征" + item.getFeaturesOrder());
            map.put("position", assoPositionFeature.getPosition());
            mapList.add(map);
        }

        return Response.success(mapList);
    }
}
