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

import cn.cslg.report.common.model.dto.invalidReReport.ProofDetailDTO;
import cn.cslg.report.common.model.dto.invalidReReport.ProofGroupDTO;
import cn.cslg.report.common.model.vo.PersonnelVO;
import cn.cslg.report.common.model.vo.invalidReReport.ProofGroupVO;
import cn.cslg.report.common.utils.CacheUtils;
import cn.cslg.report.common.utils.Response;
import cn.cslg.report.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.report.entity.Personnel;
import cn.cslg.report.entity.invalidReReport.AssoProofGroup;
import cn.cslg.report.entity.invalidReReport.ProofDetail;
import cn.cslg.report.entity.invalidReReport.ProofGroup;
import cn.cslg.report.exception.XiaoShiException;
import cn.cslg.report.mapper.InvalidReReport.ProofDetailMapper;
import cn.cslg.report.mapper.InvalidReReport.ProofGroupMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
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.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ProofGroupService extends ServiceImpl<ProofGroupMapper,ProofGroup> {
    private final CacheUtils cacheUtils;
    private final LoginUtils loginUtils;
    private final AssoProofGroupService assoProofGroupService;

    /**
     * 批量添加证据组合
     * @param proofGroupDTOS
     */
    public void addProofGroup(List<ProofGroupDTO> proofGroupDTOS) {
        for(ProofGroupDTO proofGroupDTO:proofGroupDTOS){
            //判断proofIds是否为空，若为空则返回
            if (proofGroupDTO.getProofIds() != null && proofGroupDTO.getProofIds().size() != 0) {
                //添加证据组合
                ProofGroup proofGroup = new ProofGroup();
                BeanUtils.copyProperties(proofGroupDTO, proofGroup);
                //获取当前登录人信息
                PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
                proofGroup.setCreateId(personnelVO.getId());
    //            proofGroup.setCreateId(1);
                proofGroup.insert();
                //添加证据组合和证据关联
                //批量插入
                List<AssoProofGroup> assoProofGroups = new ArrayList<>();
                for (int i = 0; i < proofGroupDTO.getProofIds().size(); i++) {
                    AssoProofGroup assoProofGroup = new AssoProofGroup();
                    assoProofGroup.setGroupId(proofGroup.getId());
                    assoProofGroup.setProofId(proofGroupDTO.getProofIds().get(i));
                    assoProofGroup.setCreateId(personnelVO.getId());
    //                assoProofGroup.setCreateId(1);
                    assoProofGroups.add(assoProofGroup);
                }
                assoProofGroupService.saveBatch(assoProofGroups);
            } else {
                throw new XiaoShiException("传入数据不能为空");
            }
        }
    }


    /**
     *批量删除证据组合
     * @param ids 证据组合ids
     * @return
     */
    public void deleteProofGroup(List<Integer> ids) {
        if(ids != null && ids.size() != 0) {
            //根据证据组合id批量删除证据组合-证据关联
            LambdaQueryWrapper<AssoProofGroup> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(AssoProofGroup::getGroupId, ids);
            assoProofGroupService.remove(queryWrapper);
            //根据ids批量删除证据组合
            this.removeByIds(ids);
        } else {
            throw new XiaoShiException("删除错误");
        }
    }

    /**
     * 更新证据组合
     * @param proofGroupDTO
     * @return
     */
    public void updateProofGroup(ProofGroupDTO proofGroupDTO) {
        //判断proofIds是否为空，若为空则返回
        if (proofGroupDTO.getProofIds() != null && proofGroupDTO.getProofIds().size() != 0){
            //查出证据组合数据
            ProofGroup proofGroup = this.getById(proofGroupDTO.getId());
            BeanUtils.copyProperties(proofGroupDTO, proofGroup);
            //获取当前登录人信息
            PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
            proofGroup.setCreateId(personnelVO.getId());
//            proofGroup.setCreateId(1);
            //更新证据组合信息
            proofGroup.updateById();
            //证据组合id
            Integer groupId = proofGroup.getId();
            //根据证据组合id查找 证据组合和证据关联ids
            LambdaQueryWrapper<AssoProofGroup> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(AssoProofGroup::getProofId);
            queryWrapper.eq(AssoProofGroup::getGroupId, groupId);
            List<AssoProofGroup> assoProofGroups = assoProofGroupService.list(queryWrapper);
            List<Integer> oldProofIds = assoProofGroups.stream().map(AssoProofGroup::getProofId).collect(Collectors.toList());
            List<Integer> newProofIds = proofGroupDTO.getProofIds();
            //寻找proofIds比关联ids少的id并从证据组合和证据关联表中删除
            List<Integer> needDelIds = new ArrayList<>(oldProofIds);
            needDelIds.removeAll(newProofIds);
            LambdaQueryWrapper<AssoProofGroup> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.in(AssoProofGroup::getProofId, needDelIds);
            List<AssoProofGroup> needDelete = assoProofGroupService.list(queryWrapper1);
            List<Integer> ids = needDelete.stream().map(AssoProofGroup::getId).collect(Collectors.toList());
            assoProofGroupService.removeByIds(ids);
            //寻找proofIds比关联ids多的id并插入到证据组合和证据关联表中
            newProofIds.removeAll(oldProofIds);
            //批量插入
            List<AssoProofGroup> needInsert = new ArrayList<>();
            for(int i = 0; i < newProofIds.size(); i++) {
                AssoProofGroup assoProofGroup = new AssoProofGroup();
                assoProofGroup.setGroupId(groupId);
                assoProofGroup.setProofId(newProofIds.get(i));
                assoProofGroup.setCreateId(personnelVO.getId());
//                assoProofGroup.setCreateId(1);
                needInsert.add(assoProofGroup);
            }
            assoProofGroupService.saveBatch(needInsert);
        } else {
            throw new XiaoShiException("传入证据id不能为空");
        }
    }

    /**
     * 查询证据组合详情
     * @param id 证据组合id
     * @return
     */
    public ProofGroupVO queryProofGroupDetail(Integer id) {
        //根据证据组合id查询证据组合并装载到ProofGroupVO类里
        ProofGroupVO proofGroupVO = new ProofGroupVO();
        ProofGroup proofGroup = this.getById(id);
        if(proofGroup == null){
            throw new XiaoShiException("没有这一条数据");
        }
        proofGroupVO.setInvalidReasonId(proofGroup.getInvalidReasonId());
        proofGroupVO.setArgument_str(proofGroup.getArgument_str());
        proofGroupVO.setDescription(proofGroup.getDescription());
        LambdaQueryWrapper<AssoProofGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(AssoProofGroup::getProofId);
        queryWrapper.eq(AssoProofGroup::getGroupId, id);
        List<AssoProofGroup> AssoProofGroups = assoProofGroupService.list(queryWrapper);
        List<Integer> proofIds = AssoProofGroups.stream().map(AssoProofGroup::getProofId).collect(Collectors.toList());
        proofGroupVO.setProofIds(proofIds);
        return proofGroupVO;
    }

    /**
     * 查询证据组合
     * @param invalidId 无效理由Id
     * @return proofGroups
     */
    public List<ProofGroup> queryProofGroup(Integer invalidId) {
        //根据无效理由Id查询证据组合列表，并返回
        LambdaQueryWrapper<ProofGroup> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProofGroup::getInvalidReasonId, invalidId);
        List<ProofGroup> proofGroups = this.list(queryWrapper);
        return proofGroups;
    }
}