package cn.cslg.report.service.business.InvalidReReport;

import cn.cslg.report.common.model.dto.invalidReReport.ArgumentsScenarioDTO;
import cn.cslg.report.common.model.vo.invalidReReport.ArgumentsListVO;
import cn.cslg.report.common.model.vo.invalidReReport.ArgumentsScenarioVO;
import cn.cslg.report.common.model.vo.invalidReReport.ArgumentsVO;
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.invalidReReport.Arguments;
import cn.cslg.report.entity.invalidReReport.ArgumentsScenarios;
import cn.cslg.report.entity.invalidReReport.AssoArguments;
import cn.cslg.report.entity.invalidReReport.AssoFeatureProof;
import cn.cslg.report.mapper.InvalidReReport.ArgumentsScenarioMapper;
import cn.cslg.report.mapper.TemplateMapper;
import cn.cslg.report.service.business.CompareFilesService;
import cn.cslg.report.service.business.FeatureService;
import cn.cslg.report.service.business.ReportService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

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


@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ArgumentsScenarioService extends ServiceImpl<ArgumentsScenarioMapper, ArgumentsScenarios> {
    private final LoginUtils loginUtils;
    private final AssoArgumentsService assoArgumentsService;
    private final ArgumentsService argumentsService;
    private final FeatureService featureService;
    private final AssoFeatureProofService assoFeatureProofService;
    private final ReportService reportService;
    private final CompareFilesService compareFilesService;

    /**
     * 添加陈述意见方案
     *
     * @param argumentsScenarioDTO
     * @return
     */
    public String addArgumentsScenario(ArgumentsScenarioDTO argumentsScenarioDTO) {
        Integer loginId = loginUtils.getId();
        //修改方案/理由
        List<Integer> argumentIds = argumentsScenarioDTO.getArgumentIds();
        //报告id
        Integer reportId = argumentsScenarioDTO.getReportId();
        //权要排序
        Integer rightSort = argumentsScenarioDTO.getRightSort();
        if (argumentIds == null || argumentIds.size() == 0 || reportId == null || rightSort == null) {
            return Response.error("请按要求输入参数");
        }
        //查询陈述意见
        LambdaQueryWrapper<Arguments> argumentsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        argumentsLambdaQueryWrapper.in(Arguments::getId, argumentIds);
        List<Arguments> arguments = argumentsService.list(argumentsLambdaQueryWrapper);
        //装载陈述意见方案
        ArgumentsScenarios argumentsScenarios = new ArgumentsScenarios();
        BeanUtils.copyProperties(argumentsScenarioDTO, argumentsScenarios);
        argumentsScenarios.setCreateId(loginId);
        argumentsScenarios.setProofId(arguments.get(0).getProofId());
        argumentsScenarios.insert();
        //添加陈述意见方案和陈述意见关联关系
        List<AssoArguments> assoArguments = new ArrayList<>();
        argumentIds.forEach(item -> {
            AssoArguments assoArgument = new AssoArguments();
            assoArgument.setArgumentId(item);
            assoArgument.setCreateId(loginId);
            assoArgument.setScenarioId(argumentsScenarios.getId());
            assoArguments.add(assoArgument);
        });
        assoArgumentsService.saveBatch(assoArguments);
        return Response.success("添加陈述意见方案成功");
    }

    /**
     * 删除陈述意见方案
     *
     * @param scenarioIds
     * @return
     */
    public String deleteArgumentsScenario(List<Integer> scenarioIds) {
        //若ids为空或者size=0则返回请至少选择一个方案进行删除
        if (scenarioIds == null || scenarioIds.size() == 0) {
            return Response.error("请至少选择一个方案");
        }
        //根据陈述意见方案id批量删除陈述意见方案和陈述意见关联关系
        LambdaQueryWrapper<AssoArguments> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(AssoArguments::getScenarioId, scenarioIds);
        assoArgumentsService.remove(wrapper);
        //根据陈述意见方案id批量删除陈述意见方案
        this.removeByIds(scenarioIds);
        return Response.success("删除成功");
    }

    //查询陈述意见方案
    public List<ArgumentsScenarioVO> queryArgumentsScenario(Integer reportId) throws IOException {
        //新建需要返回的陈述意见方案集合
        List<ArgumentsScenarioVO> argumentsScenarioVOS = new ArrayList<>();
        //判断传入报告id是否为空
        if (reportId != null && reportId > 0) {
            //根据报告id查询标的专利号
            Report report = reportService.getById(reportId);
            String patentNo = report.getSignPatentNo();
            //根据报告id查询表中多个陈述意见方案实体类的集合
            LambdaQueryWrapper<ArgumentsScenarios> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ArgumentsScenarios::getReportId, reportId);
            List<ArgumentsScenarios> argumentsScenariosList = this.list(wrapper);
            argumentsScenarioVOS = this.loadArguments(argumentsScenariosList, patentNo);

        }
        return argumentsScenarioVOS;
    }

    public List<ArgumentsScenarioVO> loadArguments(List<ArgumentsScenarios> argumentsScenariosList, String patentNo) throws IOException {
        //获得权要
        List<PatentRight> patentRights = featureService.getRightNames(patentNo);
        List<Integer> scenariosIds = argumentsScenariosList.stream().map(ArgumentsScenarios::getId).collect(Collectors.toList());
        List<Integer> proofIds = argumentsScenariosList.stream().map(ArgumentsScenarios::getProofId).collect(Collectors.toList());
        //根据证据id查询证据文献
        List<CompareFiles> compareFiles = new ArrayList<>();
        if (proofIds.size() != 0) {
            LambdaQueryWrapper<CompareFiles> compareFilesLambdaQueryWrapper =new LambdaQueryWrapper<>();
            compareFilesLambdaQueryWrapper.in(CompareFiles::getId,proofIds);
            compareFiles = compareFilesService.list(compareFilesLambdaQueryWrapper);
        }
        //根据方案id获得陈述意见列表
        List<AssoArguments> assoArguments = new ArrayList<>();
        if (scenariosIds.size() > 0) {
            LambdaQueryWrapper<AssoArguments> argumentsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            argumentsLambdaQueryWrapper.in(AssoArguments::getScenarioId, scenariosIds);
            assoArguments = assoArgumentsService.list(argumentsLambdaQueryWrapper);
        }
        //获得陈述意见id
        List<Integer> argumentIds = assoArguments.stream().map(AssoArguments::getArgumentId).collect(Collectors.toList());

        //根据陈述意见id查询陈述意见
        List<Arguments> arguments = new ArrayList<>();
        if (argumentIds.size() > 0) {
            LambdaQueryWrapper<Arguments> argumentsQueryWrapper = new LambdaQueryWrapper<>();
            argumentsQueryWrapper.in(Arguments::getId, argumentIds);
            arguments = argumentsService.list(argumentsQueryWrapper);
        }
        //根据陈述意见获得特征id
        List<Integer> featureIds = arguments.stream().map(Arguments::getFeatureId).collect(Collectors.toList());
        List<Features> features = new ArrayList<>();
        //根据特征id获得相关证据
        List<AssoFeatureProof> assoFeatureProofs = new ArrayList<>();
        if (featureIds.size() > 0) {
            LambdaQueryWrapper<Features> featuresLambdaQueryWrapper = new LambdaQueryWrapper<>();
            featuresLambdaQueryWrapper.in(Features::getId, featureIds);
            features = featureService.list(featuresLambdaQueryWrapper);
            LambdaQueryWrapper<AssoFeatureProof> assoFeatureWrapper = new LambdaQueryWrapper<>();
            assoFeatureWrapper.in(AssoFeatureProof::getFeatureId, featureIds);
            assoFeatureProofs = assoFeatureProofService.list(assoFeatureWrapper);
        }
        List<ArgumentsScenarioVO> argumentsScenarioVOS = new ArrayList<>();
        //遍历陈述意见方案
        for (ArgumentsScenarios item : argumentsScenariosList) {
            Integer scenarioId = item.getId();
            Integer rightSort = item.getRightSort();
            PatentRight patentRight = patentRights.stream().filter(tem -> tem.getSort().equals(rightSort)).findFirst().orElse(new PatentRight());
            ArgumentsScenarioVO argumentsScenarioVO = new ArgumentsScenarioVO();
            argumentsScenarioVO.setRightContent(patentRight.getContent());
            //装载文件信息
          CompareFiles compareFile=  compareFiles.stream().filter(tem->tem.getId().equals(item.getProofId())).findFirst().orElse(new CompareFiles());
            argumentsScenarioVO.setProofId(compareFile.getId());
            argumentsScenarioVO.setProofName("D"+compareFile.getSysOrder());
            //复制，装载陈述意见方案基本信息
            BeanUtils.copyProperties(item, argumentsScenarioVO);
            // 根据方案id 获得陈述意见id列表
            List<Integer> partArgumentIds = assoArguments.stream().filter(tem -> tem.getScenarioId().equals(scenarioId)).map(AssoArguments::getArgumentId).collect(Collectors.toList());
            //根据陈述意见列表获得特征id
            List<Integer> partFeatureIds = arguments.stream().filter(tem -> partArgumentIds.contains(tem.getId())).map(Arguments::getFeatureId).collect(Collectors.toList());
            List<Features> partFeatures = features.stream().filter(tem -> partFeatureIds.contains(tem.getId())).collect(Collectors.toList());
            List<ArgumentsListVO> argumentsListVOs = new ArrayList<>();
            for (Features tem : partFeatures) {
                AssoFeatureProof partProof = assoFeatureProofs.stream().filter(te -> te.getFeatureId().equals(tem.getId()) && te.getCompareFileId().equals(item.getProofId())).findFirst().orElse(null);
                ArgumentsListVO argumentsListVO = new ArgumentsListVO();
                argumentsListVO.setProofId(item.getProofId());
                argumentsListVO.setRightSort(item.getRightSort());
                argumentsListVO.setRightName("权要" + (item.getRightSort() + 1));
                argumentsListVO.setFeatureId(tem.getId());
                argumentsListVO.setFeatureName("特征" + tem.getFeaturesOrder());
                argumentsListVO.setFeatureContent(tem.getContent());
                if (partProof != null) {
                    argumentsListVO.setProofStrId(partProof.getId());
                    argumentsListVO.setProofStr(partProof.getProofStr());
                }
                //装载陈述意见
                //获得陈述意见
                List<Arguments> partArguments = arguments.stream().filter(te -> te.getFeatureId().equals(tem.getId()) && te.getProofId().equals(item.getProofId())).collect(Collectors.toList());
                List<ArgumentsListVO.ArgumentIn> argumentIns = new ArrayList<>();

                partArguments.forEach(te -> {
                    ArgumentsListVO.ArgumentIn argumentIn = new ArgumentsListVO.ArgumentIn();
                    argumentIn.setId(te.getId());
                    argumentIn.setArgumentStr(te.getArgumentStr());
                    argumentIns.add(argumentIn);
                });
                argumentsListVO.setArguments(argumentIns);
                argumentsListVOs.add(argumentsListVO);
            }
            argumentsScenarioVO.setArgumentsVOList(argumentsListVOs);
            argumentsScenarioVOS.add(argumentsScenarioVO);
        }
        return argumentsScenarioVOS;
    }

    /**
     * 更新陈述意见方案
     *
     * @param argumentsScenarioDTO
     * @return
     */
    public String updateArgumentsScenario(ArgumentsScenarioDTO argumentsScenarioDTO) {
        if (argumentsScenarioDTO.getId() == null) {
            return Response.error("请选择陈述意见方案");
        }
        //需要更新入关联表的陈述意见ids
        List<Integer> argumentIds = argumentsScenarioDTO.getArgumentIds();
        LambdaQueryWrapper<Arguments> argumentsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询陈述意见
        argumentsLambdaQueryWrapper.in(Arguments::getId, argumentIds);
        List<Arguments> arguments = argumentsService.list(argumentsLambdaQueryWrapper);
        ArgumentsScenarios argumentsScenarios = this.getById(argumentsScenarioDTO.getId());
        BeanUtils.copyProperties(argumentsScenarioDTO, argumentsScenarios);
        argumentsScenarios.setProofId(arguments.get(0).getProofId());
        argumentsScenarios.updateById();
        //关联表中所有的陈述意见ids
        LambdaQueryWrapper<AssoArguments> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AssoArguments::getScenarioId, argumentsScenarioDTO.getId());
        List<AssoArguments> assoArguments = assoArgumentsService.list(wrapper);
        List<Integer> oldArgumentIds = assoArguments.stream().map(AssoArguments::getArgumentId).collect(Collectors.toList());
        //需要删除的陈述意见ids在关联表中
        List<Integer> needDeleteIds = new ArrayList<>();
        for (Integer id : oldArgumentIds) {
            if (!argumentIds.contains(id)) {
                needDeleteIds.add(id);
            }
        }
        if (needDeleteIds != null && needDeleteIds.size() > 0) {
            //删除
            LambdaQueryWrapper<AssoArguments> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.in(AssoArguments::getArgumentId, needDeleteIds);
            assoArgumentsService.remove(wrapper1);
        }
        //需要新增的陈述意见ids
        List<Integer> needInsertIds = new ArrayList<>();
        for (Integer insertId : argumentIds) {
            if (!oldArgumentIds.contains(insertId)) {
                needInsertIds.add(insertId);
            }
        }
        if (needInsertIds != null && needDeleteIds.size() > 0) {
            //新增
            assoArgumentsService.add(argumentsScenarioDTO.getId(), needInsertIds);
        }
        return Response.success("更新成功");
    }
}


