package cn.cslg.report.service.business;

import cn.cslg.report.common.model.dto.CompareOrderDTO;
import cn.cslg.report.common.model.dto.CustomFieldLabelDTO;

import cn.cslg.report.common.model.vo.CompareFilesVO;
import cn.cslg.report.common.model.vo.PatentIndexSettingVO;

import cn.cslg.report.common.model.vo.PatentVO;
import cn.cslg.report.common.utils.JsonUtils;
import cn.cslg.report.common.utils.Response;
import cn.cslg.report.entity.*;
import cn.cslg.report.entity.asso.AssoRecordsFeature;
import cn.cslg.report.entity.asso.AssoTaskPersonel;
import cn.cslg.report.mapper.CompareFilesMapper;
import cn.cslg.report.service.OutInterfaceService;
import cn.hutool.core.lang.func.Func;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
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.function.Function;
import java.util.stream.Collectors;

@SuppressWarnings({"all"})
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class CompareFilesService extends ServiceImpl<CompareFilesMapper, CompareFiles> {
    private final CompareFilesMapper compareFilesMapper;
    private final OutInterfaceService outInterfaceService;
    private final ReportService reportService;
    private final ReportFieldService reportFieldService;
    private final ReportFieldTreeService reportFieldTreeService;
    private final ReportFieldOptionService reportFieldOptionService;
    private final AssoComapareFielService assoComapareFielService;
    private final ReportFieldPatentLinkService reportFieldPatentLinkService;
    private final TaskService taskService;
    private final AssoTaskPersonelService assoTaskPersonelService;
    private final CompareRecordsService compareRecordsService;

    /**
     * @param compareFilesVO
     * @return 是否添加成功
     * @throws IOException
     * @function 添加对比文件
     */
    @Transactional(rollbackFor = Exception.class)
    public String addCompareFile(CompareFilesVO compareFilesVO) throws IOException {
        //查询标的专利信息
        Report report = reportService.getById(compareFilesVO.getReportId());
        //根据标的专利号获得专利信息
        String res1 = outInterfaceService.getPatentFromPAS(report.getSignPatentNo());
        JSONObject res1Object = JSONObject.parseObject(res1);
        JSONObject patentNoJSON = JSONObject.parseObject(res1Object.get("data").toString());
        //获得引用专利号
        String quote = patentNoJSON.get("quote").toString().replace(" ", "");
        List<String> quotes = Arrays.asList(quote.split("\\|"));
        //获得同族专利号
        List<String> familyPatentNos = new ArrayList<>();
        if (patentNoJSON.containsKey("family")) {
            String familyJson = patentNoJSON.get("family").toString();
            familyPatentNos = JsonUtils.jsonToList(JsonUtils.objectToJson(familyJson), String.class);
        }
        LambdaQueryWrapper<CompareFiles> queryWrapper = new LambdaQueryWrapper<>();
        //根据报告id 获取文件对比表的详情
        queryWrapper.eq(CompareFiles::getReportId, compareFilesVO.getReportId());
        List<CompareFiles> compareFile1 = this.list(queryWrapper);
        //获取对比文件对比表的专利号
        List<String> patentNoList = compareFile1.stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        List<CompareFiles> compareFiles = new ArrayList<>();
        PatentVO patentVO = new PatentVO();
        patentVO.setStartNumber(compareFilesVO.getStartNumber() - 1);
        patentVO.setEndNumber(compareFilesVO.getEndNumber());
        patentVO.setReportId(compareFilesVO.getReportId());
        patentVO.setPatentNos(patentNoList);
        // 见outInterfaceService getComPatentNos接口
        String res = outInterfaceService.getComPatentNos(patentVO);
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<String> patentNos = JSONArray.parseArray(jsonObject.get("data").toString(), String.class);
        //删除原有的
        patentNos.removeAll(compareFilesVO.getIsDelete());
        //添加新的
        patentNos.addAll(compareFilesVO.getIsAdd());
        //获取对比文件对比表的专利号
        patentNos.removeAll(patentNoList);
        List<String> flags =new ArrayList<>();
        for (int i = 0; i < patentNos.size(); i++) {
            CompareFiles compareFiles1 = new CompareFiles();
            if(!flags.contains(patentNos.get(i))){
                //根据专利号和报告id造对象
                compareFiles1.setPatentNo(patentNos.get(i));
                compareFiles1.setReportId(compareFilesVO.getReportId());
                //区分对比文件的类型
                if (familyPatentNos != null && quotes.size() != 0 && quotes.contains(patentNos.get(i))) {
                    compareFiles1.setRemark("引");
                }
                if (familyPatentNos != null && familyPatentNos.size() != 0 && familyPatentNos.contains(patentNos.get(i))) {
                    compareFiles1.setRemark("同");
                }
                compareFiles.add(compareFiles1);
                flags.add(patentNos.get(i));
            }

        }
        // 批量添加
        this.saveBatch(compareFiles);
        return Response.success();
    }

    /**
     * @param compareFilesVO
     * @return
     * @throws IOException
     * @Autor lrj
     */
    @Transactional(rollbackFor = Exception.class)
    public String addFTOCompareFile(CompareFilesVO compareFilesVO) throws IOException {

        List<CompareFiles> compareFiles = new ArrayList<>();
        PatentVO patentVO = new PatentVO();
        patentVO.setStartNumber(compareFilesVO.getStartNumber() - 1);
        patentVO.setEndNumber(compareFilesVO.getEndNumber());
        patentVO.setReportId(compareFilesVO.getReportId());

        // 见outInterfaceService getComPatentNos接口
        String res = outInterfaceService.getComPatentNos(patentVO);
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<String> patentNos = JSONArray.parseArray(jsonObject.get("data").toString(), String.class);
        //删除原有的
        patentNos.removeAll(compareFilesVO.getIsDelete());
        //添加新的
        patentNos.addAll(compareFilesVO.getIsAdd());
        for (int i = 0; i < patentNos.size(); i++) {
            CompareFiles compareFiles1 = new CompareFiles();
            //根据专利号和报告id造对象
            compareFiles1.setPatentNo(patentNos.get(i));
            compareFiles1.setReportId(compareFilesVO.getReportId());
            compareFiles.add(compareFiles1);
        }
        // 批量添加
        this.saveBatch(compareFiles);
        return Response.success();
    }

    /**
     * @param patentVO
     * @return 标的专利号和数量 map
     * @throws IOException
     * @function 根据PatentVO里的条件（分页）模糊查询标的专利号和数量
     */
    public String getCompareFile(PatentVO patentVO) throws IOException {
        LambdaQueryWrapper<CompareFiles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompareFiles::getReportId, patentVO.getReportId());
        //根据报告id 获取文件对比表的详情
        List<CompareFiles> compareFiles = this.list(queryWrapper);
        //获取文件对比表的详情的专利号
        List<String> patentNos = compareFiles.stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        String res;
        //1 代表已添加
        if (patentVO.getState() == 1) {
            patentVO.setPatentNos(patentNos);
            //详情见outInterfaceService.getPatentFromPAS
            res = outInterfaceService.getPatentFromPAS(patentVO, 1);
        } else {
            //根据标的专利号和报告id找到报告
            LambdaQueryWrapper<Report> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.select(Report::getSignPatentNo);
            wrapper1.eq(Report::getId, patentVO.getReportId());
            //获取标的专利号
            if (reportService.list(wrapper1).size() == 0) {
                return "";
            }
            patentVO.setNotInPatentNos(patentNos);
            //详情见outInterfaceService.getPatentFromPAS
            res = outInterfaceService.getPatentFromPAS(patentVO, 0);
        }
        JSONObject jsonObject = JSONObject.parseObject(res);
        JSONObject resData = JSONObject.parseObject(jsonObject.getString("data"));
        List<JSONObject> list = JSONArray.parseArray(resData.getString("records"), JSONObject.class);
        List<String> temNos = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            //查到专利的专利号在标的内拿到
            if (patentNos.contains(list.get(i).get("patentNo").toString())) {
                temNos.add(list.get(i).get("patentNo").toString());
            }
        }
        //根据报告id获取对比文件的数量
        int i = compareFilesMapper.selectedTotal(patentVO.getReportId());
        Map<String, Object> map = new HashMap<>();
        map.put("datas", resData);
        map.put("select", temNos);
        map.put("selectedTotal", i);
        return Response.success(map);
    }

    /**
     * @param patentVO
     * @return
     * @throws IOException
     * @function 根据PatentVO里的条件模糊查询获得已经确定的对比专利详情
     */
    //
    public String getSureCompareFile(PatentVO patentVO) throws IOException {
        List<String> patentNos = new ArrayList<>();
        LambdaQueryWrapper<CompareFiles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompareFiles::getReportId, patentVO.getReportId());

if(patentVO.getOrderItem()!=null&&patentVO.getOrderType()!=null&&patentVO.getOrderItem().equals("SysOrder")&&patentVO.getOrderType().equals("desc"))
{
    queryWrapper .last("ORDER BY IF(isnull(SYS_ORDER),0,1), SYS_ORDER DESC");
}
else if(patentVO.getOrderItem()!=null&&patentVO.getOrderItem().equals("SysOrder")){
    queryWrapper .last("ORDER BY IF(isnull(SYS_ORDER),1,0), SYS_ORDER ASC");
}
        List<CompareFiles> compareFiles = this.list(queryWrapper);
        List<String> AllpatentNos = compareFiles.stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        //无查询条件
        if (patentVO.getFiledOptions() == null || patentVO.getFiledOptions().size() == 0) {
            patentNos = new ArrayList<>(AllpatentNos);
        }
        //有查询条件时，自定义字段的专利号和任务的专利号取交集
        else {
            patentNos = reportFieldService.getPatentNo1(patentVO.getFiledOptions(), patentVO.getReportId(), patentVO.getTaskId(), patentVO.getTaskStatus());
        }
        //如果有任务过滤条件
        List<String> patentNosTask = new ArrayList<>();
        if (patentVO.getTaskSources() != null && patentVO.getTaskSources().size() != 0) {
            patentNosTask = assoTaskPersonelService.getBaseMapper().getPatents(patentVO.getTaskSources());
        }
        List<String> allPatentsCopy = new ArrayList<>();
        if (patentVO.getNotAssignTypes() != null && patentVO.getNotAssignTypes().size() != 0) {
            for(Integer types :patentVO.getNotAssignTypes()) {
                LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
                wrapper.select(Task::getId)
                        .eq(Task::getType, types)
                        .eq(Task::getReportId, patentVO.getReportId());

                Function<Object, Integer> f = (o -> Integer.parseInt(o.toString()));
                List<Integer> taskIds = taskService.listObjs(wrapper, f);
                List<String> PatentsCopy = new ArrayList<>(AllpatentNos);
                if (taskIds.size() != 0) {
                    LambdaQueryWrapper<AssoTaskPersonel> assoWrapper = new LambdaQueryWrapper<>();
                    assoWrapper.in(AssoTaskPersonel::getTaskId,taskIds);
                    List<AssoTaskPersonel> assoTaskPersonels = assoTaskPersonelService.list(assoWrapper);
                    List<String> tem = assoTaskPersonels.stream().map(AssoTaskPersonel::getPatentNo).collect(Collectors.toList());
                    PatentsCopy.removeAll(tem);
                }
                allPatentsCopy.addAll(PatentsCopy);
            }
        }
        if ((patentVO.getTaskSources() != null && patentVO.getTaskSources().size() != 0) || (patentVO.getNotAssignTypes() != null && patentVO.getNotAssignTypes().size() != 0)) {
            patentNosTask.addAll(allPatentsCopy);
            patentNos = new ArrayList<>(CollectionUtils.intersection(patentNosTask, patentNos));
        }
        if (patentVO.getOrderItem()!=null&&patentVO.getOrderItem().equals("SysOrder")) {
            List<String> noCopy = new ArrayList<>();
            for (CompareFiles item : compareFiles) {
                if (patentNos.contains(item.getPatentNo()))
                {  noCopy.add(item.getPatentNo());}
            }
            patentNos = noCopy;
        }
        patentVO.setPatentNos(patentNos);
        //详情见outInterfaceService.getPatentFromPAS 接口
        String res = outInterfaceService.getPatentFromPAS(patentVO, 1);
        JSONObject jsonObject = JSONObject.parseObject(res);
        JSONObject jsonObject1 = JSONObject.parseObject(jsonObject.get("data").toString());
        List<JSONObject> jsonObjects = JSONArray.parseArray(jsonObject1.get("records").toString(), JSONObject.class);
        List<JSONObject> jsonObjects2 = new ArrayList<>();
        for (JSONObject jsonObject2 : jsonObjects) {
            for(CompareFiles com:compareFiles){
                if(jsonObject2.get("publicNo").toString().equals(com.getPatentNo()))
                {
                    jsonObject2.put("SysOrder",com.getSysOrder());
                }
            }
            jsonObjects2.add(jsonObject2);
        }
        jsonObject1.put("records", jsonObjects2);
        jsonObject.put("data", jsonObject1);
        return jsonObject.toString();
    }

    public String getCompareNos(Integer reportId) throws IOException {
        LambdaQueryWrapper<CompareFiles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompareFiles::getReportId, reportId);
        List<CompareFiles> compareFiles = this.list(queryWrapper);
        List<String> patentNos = compareFiles.stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        return Response.success(patentNos);
    }

    /**
     * @param compareFilesVO
     * @return 是否删除成功
     * @throws IOException
     * @function 删除单个对比专利
     */

    public String deletePatentNo(CompareFilesVO compareFilesVO) throws IOException {
        List<String> patentNos = new ArrayList<>();
        //是否根据范围删除
        if (compareFilesVO.getStartNumber() != null && compareFilesVO.getEndNumber() != null && compareFilesVO.getEndNumber() > compareFilesVO.getStartNumber()) {
            LambdaQueryWrapper<CompareFiles> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(CompareFiles::getPatentNo)
                    .eq(CompareFiles::getReportId, compareFilesVO.getReportId())
                    //分页查询 传的起始条数和结束条数
                    .last("limit " + (compareFilesVO.getStartNumber() - 1) + "," + compareFilesVO.getEndNumber());
            patentNos = this.list(wrapper).stream().map(CompareFiles::getPatentNo).collect(Collectors.toList());
        }
        //减少的专利号
        if (compareFilesVO.getIsDelete() != null) {
            patentNos.removeAll(compareFilesVO.getIsDelete());
        }
        //增加的专利号
        if (compareFilesVO.getIsAdd() != null) {
            patentNos.addAll(compareFilesVO.getIsAdd());
        }
        //根据专利号删除
        if (patentNos.size() != 0) {
            LambdaQueryWrapper<CompareFiles> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(CompareFiles::getPatentNo, patentNos);
            this.remove(lambdaQueryWrapper);
        }
        return Response.success();
    }
    /**
     * @param id
     * @return
     * @throws IOException
     * @function 根据id删除对比文件
     */
    public String deleByReportId(int id) throws IOException {
        CompareFiles compareFiles = new CompareFiles();
        compareFiles.deleteById(id);
        return Response.success();
    }

    /**
     * @param reportId  报告的id
     * @param patentNos 专利号
     * @return 专利号的集合
     * @throws IOException
     * @function 根据报告id 和专利号查询对比文件
     */
    public List<CustomFieldLabelDTO> setAll(Integer reportId, String patentNos) throws IOException {
        List<CustomFieldLabelDTO> dataList = new ArrayList<>();
        //根据报告id找到对比文件
        List<ReportField> reportFields = reportFieldService.selectAll(reportId);
        for (ReportField reportField : reportFields) {
            PatentIndexSettingVO params = new PatentIndexSettingVO();
            CustomFieldLabelDTO data = new CustomFieldLabelDTO();
            params.setPatentNo(patentNos);
            params.setType(reportField.getType());
            params.setFieldId(reportField.getId());
            params.setReportId(reportField.getReportId());
            data.setName(reportField.getName());
            data.setId(reportField.getId());
            data.setType(reportField.getType());
            //详细见reportFieldPatentLinkService getPatentIndexSetting方法
            data.setSelected(reportFieldPatentLinkService.getPatentIndexSetting(params));
            dataList.add(data);
        }

        return dataList;


    }

    /**
     * @param params
     * @throws IOException
     * @function 修改 reportFieldPatentLink
     */
    @Transactional(rollbackFor = Exception.class)
    public void getPatentIndexSetting(PatentIndexSettingVO params) throws IOException {
        if (params.getTaskID() != null) {
            Task task = taskService.getById(params.getTaskID());
            params.setReportId(task.getReportId());
            reportFieldPatentLinkService.updatePatentIndexSetting(params);
            LambdaQueryWrapper<AssoTaskPersonel> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AssoTaskPersonel::getTaskId, params.getTaskID())
                    .eq(AssoTaskPersonel::getPatentNo, params.getPatentNo());
            AssoTaskPersonel assoTaskPersonel = assoTaskPersonelService.list(queryWrapper).get(0);
            assoTaskPersonel.setState(1);
            assoTaskPersonel.updateById();
        } else {
            reportFieldPatentLinkService.updatePatentIndexSetting(params);
        }
    }

    /**
     * @param reportId 报告的id
     * @return
     * @function 根据报告id查询对比文件
     */


    public Map<String, Object> reTaskStateCount(Integer reportId) {
        //根据报告id查询对比方案与对比记录关联表的详细
        LambdaQueryWrapper<AssoTaskPersonel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AssoTaskPersonel::getReportId, reportId);

        List<AssoTaskPersonel> assoTaskPersonels = assoTaskPersonelService.list(queryWrapper);
        LambdaQueryWrapper<CompareFiles> queryWrapper1 = new LambdaQueryWrapper<>();
        //根据报告id查询对比文件的详情
        queryWrapper1.eq(CompareFiles::getReportId, reportId);
        List<CompareFiles> compareFiles = this.list(queryWrapper1);
        Map<String, Object> reMap = new HashMap<>();
        reMap.put("all", compareFiles.size());
        reMap.put("noRead", 0);
        reMap.put("read", 0);
        if (assoTaskPersonels.size() == 0) {
            return reMap;
        }

        List<AssoTaskPersonel> assoRead = assoTaskPersonels.stream().filter(item -> item.getState().equals(1)).collect(Collectors.toList());
        reMap.put("all", compareFiles.size());
        reMap.put("noRead", compareFiles.size() - assoRead.size());
        reMap.put("read", assoRead.size());
        return reMap;
    }

    /**
     * function : 在删除报告的时候删除对比文件
     */
    @Transactional(rollbackFor = Exception.class)
    public String delete(Integer id) {
        LambdaQueryWrapper<CompareFiles> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompareFiles::getReportId, id);
        remove(queryWrapper);
        return Response.success();
    }

    public Integer addOrder(CompareOrderDTO compareOrderDTO) {
        //根据报告ID 和专利号 查询对比文件
        LambdaQueryWrapper<CompareFiles> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompareFiles::getReportId, compareOrderDTO.getReport());
        List<CompareFiles> compareFiles = this.list(wrapper);
        //如果未查到则返回-1
        if (compareFiles.size() == 0) {
            return -1;
        }
        // 判断该顺序是否被使用过
        compareFiles.forEach(item -> {
            compareOrderDTO.getOrders().forEach(
                    item2 -> {
                        if (item2.getPatentNO().equals(item.getPatentNo())) {
                            item.setSysOrder(item2.getOrder());
                        }
                    }
            );
        });
        this.saveOrUpdateBatch(compareFiles);
        return 1;
    }

    public List<Integer> getOrder(Integer reportId) {
        List<Integer> orders = new ArrayList<>();
        int i = 1;
        LambdaQueryWrapper<CompareRecords> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompareRecords::getReportId, reportId);
        List<CompareRecords> list = new ArrayList<>();
        List<CompareRecords> compareRecords = compareRecordsService.list(wrapper);
        List<String> headerPatentNos = new ArrayList<>();
        for (CompareRecords records : compareRecords) {
            if (!headerPatentNos.contains(records.getPatentNo())) {
                orders.add(i);
                i++;
            }
        }
        return orders;
    }
}
