package cn.cslg.report.service.business;

import cn.cslg.report.common.model.dto.LabelDTO;
import cn.cslg.report.common.model.vo.PatentIndexSettingVO;
import cn.cslg.report.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.report.common.utils.StringUtils;
import cn.cslg.report.entity.*;
import cn.cslg.report.mapper.ReportFieldPatentLinkMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 标引内容关联专利 服务类
 * </p>
 *
 * @author 王岩
 * @since 2022-02-22
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
@SuppressWarnings({"all"})
public class ReportFieldPatentLinkService extends ServiceImpl<ReportFieldPatentLinkMapper, ReportFieldPatentLink> {

    private final ReportFieldTextService reportFieldTextService;
    private final ReportFieldOptionService projectFieldOptionService;
    private final ReportFieldTreeService projectFieldTreeService;
    private final ReportFieldService reportFieldService;
    private final LoginUtils loginUtils;
    private final ReportFieldOptionService reportFieldOptionService;
    private final ReportFieldPatentLinkService reportFieldPatentLinkService;


    /**
     * @param patentNo  专利号
     * @param projectId 报告id
     * @return
     * @function 根据专利号和报告id插叙标引内容关联专利
     */
    public List<ReportFieldPatentLink> getProjectPatentLinkByPatentAndProId(String patentNo, Integer projectId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReportFieldPatentLink::getPatentNo, patentNo);
        queryWrapper.eq(ReportFieldPatentLink::getReportId, projectId);
        return this.list(queryWrapper);
    }

    /**
     * @param patentNo  专利号
     * @param projectId 报告id
     * @param fieldId   自定义字段id
     * @return
     * @function 根据专利号，报告id，自定义字段id 插叙标引内容关联专利
     */

    public List<ReportFieldPatentLink> getProjectPatentLinkByPatentAndProjectIdAndFieldId(String patentNo, Integer projectId, Integer fieldId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReportFieldPatentLink::getPatentNo, patentNo);
        queryWrapper.eq(ReportFieldPatentLink::getReportId, projectId);
        queryWrapper.eq(ReportFieldPatentLink::getFieldId, fieldId);
        List<ReportFieldPatentLink> list = this.list(queryWrapper);

        return list;
    }

    /**
     * @param patentId  专利号
     * @param projectId 报告id
     * @param fieldId   自定义字段id
     * @param optionId  分类标引的id
     * @return
     * @function 根据专利号，报告id，自定义字段id 分类标引的id 插叙标引内容关联专利
     */

    public ReportFieldPatentLink getProjectPatentLinkByPatentAndProjectIdAndFieldIdAndOptionId(String patentId, Integer projectId, Integer fieldId, Integer optionId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReportFieldPatentLink::getPatentNo, patentId);
        queryWrapper.eq(ReportFieldPatentLink::getReportId, projectId);
        queryWrapper.eq(ReportFieldPatentLink::getFieldId, fieldId);
        queryWrapper.eq(ReportFieldPatentLink::getOptionId, optionId);
        return this.getOne(queryWrapper);
    }

    /**
     * @param patentNo  专利号
     * @param type      类型
     * @param fieldId   文件id
     * @param optionId  分类标引id
     * @param userId    用户id（当前登录人id）
     * @param projectId 报告id
     * @function 修改插叙标引内容关联专利
     */
    public void updateProjectPatentLink(String patentNo, Integer type, Integer fieldId, Integer optionId, Integer userId, Integer projectId) {
        ReportFieldPatentLink reportFieldPatentLink = new ReportFieldPatentLink();
        reportFieldPatentLink.setType(type);
        reportFieldPatentLink.setPatentNo(patentNo);
        reportFieldPatentLink.setOptionId(optionId);
        reportFieldPatentLink.setFieldId(fieldId);
        reportFieldPatentLink.setCreateBy(userId);
        reportFieldPatentLink.setReportId(projectId);
        reportFieldPatentLink.insert();
    }

    /**
     * @param patentNos 专利号
     * @param projectId 任务id
     * @return
     * @function 查询插叙标引内容关联专利
     */

    public List<ReportFieldPatentLink> getProjectPatentLinkByPatentIdsAndProjectId(List<String> patentNos, Integer projectId) {
        if (patentNos == null || patentNos.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ReportFieldPatentLink::getPatentNo, patentNos);
        queryWrapper.eq(ReportFieldPatentLink::getReportId, projectId);
        return this.list(queryWrapper);
    }

    /**
     * @param fieldId 自定义字段id
     * @function 删除ReportFieldPatentLink
     */
    public void deleteByFieldId(Integer fieldId) {
        this.remove(Wrappers.<ReportFieldPatentLink>lambdaQuery().eq(ReportFieldPatentLink::getFieldId, fieldId));
    }

    /**
     * @param optionId 分类标引的id
     * @function 删除ReportFieldPatentLink
     */
    public void deleteByOptionId(Integer optionId) {
        this.remove(Wrappers.<ReportFieldPatentLink>lambdaQuery().eq(ReportFieldPatentLink::getOptionId, optionId));
    }

    /**
     * @param optionIds
     * @function 批量删除
     */
    public void deleteByOptionIds(List<Integer> optionIds) {
        if (optionIds != null && optionIds.size() != 0) {
            this.remove(Wrappers.<ReportFieldPatentLink>lambdaQuery().in(ReportFieldPatentLink::getOptionId, optionIds));
        }
    }

    /**
     * @param patentNos 专利号
     * @param projectId 报告id
     * @param fieldId   自定义字段id
     * @function 删除
     */
    public void deleteByPatentIdsAndProjectIdAndFieldId(List<Integer> patentNos, Integer projectId, Integer fieldId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ReportFieldPatentLink::getPatentNo, patentNos);
        queryWrapper.eq(ReportFieldPatentLink::getReportId, projectId);
        queryWrapper.eq(ReportFieldPatentLink::getFieldId, fieldId);
        this.remove(queryWrapper);
    }

    /**
     * @param patentNos 专利号
     * @param projectId 报告id
     * @param fieldId   自定义字段id
     * @function 删除
     */
    public void delete(Integer patentId, String patentNo, Integer fieldId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReportFieldPatentLink::getPatentNo, patentNo)
                .eq(ReportFieldPatentLink::getReportId, patentId)
                .eq(ReportFieldPatentLink::getFieldId, fieldId);
        this.remove(queryWrapper);


    }

    /**
     * @param params
     * @return
     * @throws IOException
     * @function 获取自定义字段
     */
    public List<LabelDTO> getPatentIndexSetting(PatentIndexSettingVO params) throws IOException {
        //根据专利号报告id自定义字段的id找到ReportFieldPatentLink
        List<ReportFieldPatentLink> projectFieldPatentLinkList = this.getProjectPatentLinkByPatentAndProjectIdAndFieldId(params.getPatentNo(), params.getReportId(), params.getFieldId());
        //找到不同类型自定义字段的id
        List<Integer> optionIds = projectFieldPatentLinkList.stream().map(ReportFieldPatentLink::getOptionId).collect(Collectors.toList());
        List<LabelDTO> mapList = new ArrayList<>();
        switch (params.getType()) {
            case 0:
            case 1:
                //文本 时间
            case 2:
                List<ReportFieldText> projectFieldTextList = reportFieldTextService.getProjectFieldTextByIds(optionIds);
                for (ReportFieldText projectFieldText : projectFieldTextList) {
                    LabelDTO map = new LabelDTO();
                    map.setValue(projectFieldText.getId());
                    map.setLabel(projectFieldText.getText());
                    mapList.add(map);
                }
                break;
            //选项
            case 3:
            case 4:
            case 5:
                List<ReportFieldOption> projectFieldOptionList = reportFieldOptionService.getFieldOptionListByIds(optionIds);

                for (ReportFieldOption projectFieldOption : projectFieldOptionList) {
                    LabelDTO map = new LabelDTO();
                    map.setValue(projectFieldOption.getId());
                    map.setLabel(projectFieldOption.getName());
                    mapList.add(map);
                }
                break;
            //树类型
            case 6:
                List<ReportFieldTree> projectFieldTreeList = projectFieldTreeService.getProjectFieldTreeOptionByIds(optionIds);
                for (ReportFieldTree projectFieldTree : projectFieldTreeList) {
                    LabelDTO map = new LabelDTO();
                    map.setValue(projectFieldTree.getId());
                    map.setLabel(projectFieldTree.getName());
                    mapList.add(map);
                }
                break;
        }
        return mapList;
    }

    /**
     * @param params
     * @function
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePatentIndexSetting(PatentIndexSettingVO params) {
        LambdaQueryWrapper<ReportFieldPatentLink> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ReportFieldPatentLink::getPatentNo, params.getPatentNo())
                .eq(ReportFieldPatentLink::getReportId, params.getReportId())
                .eq(ReportFieldPatentLink::getFieldId, params.getFieldId());
        reportFieldPatentLinkService.remove(lambdaQueryWrapper);
        List<Integer> optionIds = params.getSelected().stream().map(LabelDTO::getValue).distinct().collect(Collectors.toList());
        List<String> texts = params.getSelected().stream().map(LabelDTO::getLabel).distinct().collect(Collectors.toList());
        List<ReportFieldPatentLink> projectFieldPatentLinkList = new ArrayList<>();
        switch (params.getType()) {
            case 0:
            case 1:
            case 2:
                LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ReportFieldPatentLink::getPatentNo, params.getPatentNo())
                        .eq(ReportFieldPatentLink::getReportId, params.getReportId())
                        .eq(ReportFieldPatentLink::getFieldId, params.getFieldId());
                List<ReportFieldPatentLink> list = this.list(queryWrapper);
                ReportFieldPatentLink reportFieldPatentLink;
               if(params.getSelected().get(0).getLabel()!=null) {
                   if (list.size() != 0) {
                       reportFieldPatentLink = list.get(0);
                       Integer optionId = reportFieldPatentLink.getOptionId();
                       List<ReportFieldText> reportFieldTexts = reportFieldTextService.get(optionId);
                       ReportFieldText reportFieldText = reportFieldTexts.get(0);
                       reportFieldText.setText(params.getSelected().get(0).getLabel());
                       reportFieldText.updateById();
                       reportFieldPatentLink.setFieldId(reportFieldText.getFieldId());
                       reportFieldPatentLink.setOptionId(reportFieldText.getId());
                       reportFieldPatentLink.setCreateBy(loginUtils.getId());
                       reportFieldPatentLink.setPatentNo(params.getPatentNo());
                       reportFieldPatentLink.setReportId(params.getReportId());
                       reportFieldPatentLink.updateById();
                   } else {
                       LambdaQueryWrapper<ReportFieldText> queryWrapper1 = new LambdaQueryWrapper<>();
                       queryWrapper1.eq(ReportFieldText::getText, params.getSelected().get(0).getLabel())
                               .eq(ReportFieldText::getFieldId, params.getFieldId());
                       List<ReportFieldText> reportFieldTexts = reportFieldTextService.list(queryWrapper1);
                       reportFieldPatentLink = new ReportFieldPatentLink();
                       ReportFieldText reportFieldText = new ReportFieldText();
                       if (reportFieldTexts != null && reportFieldTexts.size() != 0) {
                           reportFieldText = reportFieldTexts.get(0);
                       } else {
                           reportFieldText.setText(params.getSelected().get(0).getLabel());
                           reportFieldText.setFieldId(params.getFieldId());
                           reportFieldText.insert();
                       }
                       reportFieldPatentLink.setFieldId(reportFieldText.getFieldId());
                       reportFieldPatentLink.setOptionId(reportFieldText.getId());
                       reportFieldPatentLink.setCreateBy(loginUtils.getId());
                       reportFieldPatentLink.setPatentNo(params.getPatentNo());
                       reportFieldPatentLink.setReportId(params.getReportId());
                       reportFieldPatentLink.insert();
                   }
               }
                //将没有使用到的选项值删除
                LambdaQueryWrapper<ReportFieldPatentLink> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
                lambdaQueryWrapper1.eq(ReportFieldPatentLink::getReportId, params.getReportId())
                        .eq(ReportFieldPatentLink::getFieldId, params.getFieldId());
                List<ReportFieldPatentLink> links = reportFieldPatentLinkService.list(lambdaQueryWrapper1);
                if (links.size() != 0) {
                    List<Integer> opIds = links.stream().map(ReportFieldPatentLink::getOptionId).collect(Collectors.toList());
                    LambdaQueryWrapper<ReportFieldText> removeWrapper = new LambdaQueryWrapper<>();
                    removeWrapper.notIn(ReportFieldText::getId, opIds).eq(ReportFieldText::getFieldId, params.getFieldId());
                    reportFieldTextService.remove(removeWrapper);


                }
                break;
            case 3:
            case 4:
            case 5:
            case 6:
                LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(ReportFieldPatentLink::getPatentNo, params.getPatentNo())
                        .eq(ReportFieldPatentLink::getFieldId, params.getFieldId())
                        .eq(ReportFieldPatentLink::getReportId, params.getReportId());
                this.remove(queryWrapper1);
                for (Integer optionId : optionIds) {
                    ReportFieldPatentLink projectFieldPatentLink = new ReportFieldPatentLink();
                    projectFieldPatentLink.setPatentNo(params.getPatentNo());
                    projectFieldPatentLink.setReportId(params.getReportId());
                    projectFieldPatentLink.setType(params.getType());
                    projectFieldPatentLink.setFieldId(params.getFieldId());
                    projectFieldPatentLink.setCreateBy(loginUtils.getId());
                    projectFieldPatentLink.setOptionId(optionId);
                    projectFieldPatentLinkList.add(projectFieldPatentLink);
                }
                break;
        }
        if (projectFieldPatentLinkList.size() != 0) {
            this.saveOrUpdateBatch(projectFieldPatentLinkList);
        }

    }

    public List<ReportFieldPatentLink> get(int id) throws IOException {
        LambdaQueryWrapper<ReportFieldPatentLink> linkLambdaQueryWrapper = new LambdaQueryWrapper<>();
        linkLambdaQueryWrapper.eq(ReportFieldPatentLink::getReportId, id);
        return this.list(linkLambdaQueryWrapper);
    }

    public void updatePatentIndexSetting2(PatentIndexSettingVO params) {
        switch (params.getType()) {
            case 0:
            case 1:
            case 2:
            case 3:
                List<LabelDTO> selected = params.getSelected();
                for (LabelDTO a : selected) {
                    ReportFieldText reportFieldText = new ReportFieldText();
                    reportFieldText.setText(a.getLabel());
                    reportFieldText.setId(a.getValue());
                    reportFieldText.updateById();
                }
                break;
            case 4:
            case 5:
                List<LabelDTO> selected2 = params.getSelected();
                for (LabelDTO a : selected2) {
                    ReportFieldOption reportFieldOption = new ReportFieldOption();
                    reportFieldOption.setName(a.getLabel());
                    reportFieldOption.setId(a.getValue());
                    reportFieldOption.updateById();
                }
                break;
            case 6:
                List<LabelDTO> selected3 = params.getSelected();
                for (LabelDTO a : selected3) {
                    ReportFieldTree reportFieldTree = new ReportFieldTree();
                    reportFieldTree.setId(a.getValue());
                    reportFieldTree.setName(a.getLabel());

                }
                break;

        }
    }

    /**
     * @param FieldId
     * @param valueId
     * @return
     */
    public List<String> getPatentNos(Integer FieldId, Integer valueId) {
        LambdaQueryWrapper<ReportFieldPatentLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(ReportFieldPatentLink::getPatentNo);
        queryWrapper.eq(ReportFieldPatentLink::getFieldId, FieldId);
        queryWrapper.eq(ReportFieldPatentLink::getOptionId, valueId);
        List<ReportFieldPatentLink> reportFieldPatentLinks = this.list(queryWrapper);
        List<String> patentNos = reportFieldPatentLinks.stream().map(ReportFieldPatentLink::getPatentNo).collect(Collectors.toList());
        return patentNos;

    }

    /**
     *
     * @param reportId 报告ID
     * @param pantentNO 专利号
     * @return
     */


}
