package org.dromara.zjk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.dict.service.impl.DictServiceImpl;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.zjk.domain.*;
import org.dromara.zjk.domain.bo.ZjkProductSummarizeBo;
import org.dromara.zjk.domain.excels.ZjkProductSummarizeExcelVO;
import org.dromara.zjk.domain.vo.*;
import org.dromara.zjk.enums.ReviewSnEnum;
import org.dromara.zjk.enums.SummarizeStatusEnum;
import org.dromara.zjk.mapper.*;
import org.dromara.zjk.service.IZjkApprovalProcessLogsService;
import org.dromara.zjk.service.IZjkExpertItemService;
import org.dromara.zjk.service.IZjkProductSummarizeService;
import org.springframework.stereotype.Service;

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

/**
 * 项目总结Service业务层处理
 *
 * @author ygh
 * @date 2024-11-02
 */
@RequiredArgsConstructor
@Service
public class ZjkProductSummarizeServiceImpl implements IZjkProductSummarizeService {

    private final ZjkProductSummarizeMapper baseMapper;

    private final ZjkExpertMapper expertMapper;

    private final ZjkExpertItemMapper expertItemMapper;

    private final ZjkProductMapper zjkProductMapper;

    private final ZjkReviewPhaseMapper zjkReviewPhaseMapper;

    private final IZjkExpertItemService zjkExpertItemService;

    private final ZjkProductSummarizeLogMapper zjkProductSummarizeLogMapper;

    private final ZjkExpertMajorMapper zjkExpertMajorMapper;

    private final IZjkApprovalProcessLogsService zjkApprovalProcessLogsService;
    private final DictServiceImpl dictServiceImpl;


    /**
     * 查询项目总结
     *
     * @param id 主键
     * @return 项目总结
     */
    @Override
    public ZjkProductSummarizeVo queryById(Long id) {
        ZjkProductSummarizeVo zjkProductSummarizeVo = baseMapper.selectVoById(id);
        if (zjkProductSummarizeVo == null) {
            return null;
        }
        Long itemId = zjkProductSummarizeVo.getReviewId();
        ItemVO byId = expertItemMapper.getById(itemId);
        if (byId != null) {
            zjkProductSummarizeVo.setProductName(byId.getProductName());
            zjkProductSummarizeVo.setReviewSn(byId.getReviewSn());
        }
        List<ZjkExpertItemVo> expertByReviewList = zjkExpertItemService.getExpertByReviewId(itemId);
        if (CollectionUtil.isEmpty(expertByReviewList)) {
            return zjkProductSummarizeVo;
        }
        List<Long> expertIdList = expertByReviewList.stream().map(ZjkExpertItemVo::getExpertId).collect(Collectors.toList());
        //方法被多次使用无法修改
        List<ZjkExpert> zjkExperts = expertMapper.selectByIds(expertIdList);

        List<ZjkExpertVo> zjkExpertVos = BeanUtil.copyToList(zjkExperts, ZjkExpertVo.class);
        List<ZjkExpertMajor> zjkExpertMajors = zjkExpertMajorMapper.selectMajorList(expertIdList);
        if(CollectionUtil.isNotEmpty(zjkExpertMajors)){
            Map<Long, List<ZjkExpertMajor>> expertMajorMap = zjkExpertMajors.stream().collect(Collectors.groupingBy(ZjkExpertMajor::getExpertId));
            for (ZjkExpertVo zjkExpertVo : zjkExpertVos) {
                Long expertId = zjkExpertVo.getExpertId();
                zjkExpertVo.setMajorList(expertMajorMap.get(expertId));
            }

        }
        zjkProductSummarizeVo.setZjkExpertList(zjkExpertVos);


        return zjkProductSummarizeVo;
    }

    /**
     * 分页查询项目总结列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 项目总结分页列表
     */
    @Override
    public TableDataInfo<ZjkProductSummarizeVo> queryPageList(ZjkProductSummarizeBo bo, PageQuery pageQuery) {
        Page<ZjkProductSummarizeVo> result = baseMapper.getProductInfo(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的项目总结列表
     *
     * @param bo 查询条件
     * @return 项目总结列表
     */
    @Override
    public List<ZjkProductSummarizeVo> queryList(ZjkProductSummarizeBo bo) {
        List<ZjkProductSummarizeVo> zjkProductSummarizeVos = baseMapper.exportList(bo);
        if (CollectionUtil.isEmpty(zjkProductSummarizeVos)) {
            return zjkProductSummarizeVos;
        }
        for (ZjkProductSummarizeVo zjkProductSummarizeVo : zjkProductSummarizeVos) {
            String status = zjkProductSummarizeVo.getStatus();
            SummarizeStatusEnum byCode = SummarizeStatusEnum.getByCode(status);
            if (byCode != null) {
                zjkProductSummarizeVo.setStatusName(byCode.getDesc());
            }
            String productSummarizeType = zjkProductSummarizeVo.getProductSummarizeType();
            SummarizeStatusEnum byCode1 = SummarizeStatusEnum.getByCode(productSummarizeType);
            if (byCode1 != null) {
                zjkProductSummarizeVo.setProductSummarizeName(byCode1.getDesc());
            }
        }
        return zjkProductSummarizeVos;
    }

    private LambdaQueryWrapper<ZjkProductSummarize> buildQueryWrapper(ZjkProductSummarizeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ZjkProductSummarize> lqw = Wrappers.lambdaQuery();
        lqw.eq(!Objects.isNull(bo.getReviewId()), ZjkProductSummarize::getReviewId, bo.getReviewId());
        lqw.like(StringUtils.isNotBlank(bo.getProductSummarizeName()), ZjkProductSummarize::getProductSummarizeName, bo.getProductSummarizeName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductSummarizeType()), ZjkProductSummarize::getProductSummarizeType, bo.getProductSummarizeType());
        lqw.eq(StringUtils.isNotBlank(bo.getProductGeneral()), ZjkProductSummarize::getProductGeneral, bo.getProductGeneral());
        lqw.eq(StringUtils.isNotBlank(bo.getReviewScope()), ZjkProductSummarize::getReviewScope, bo.getReviewScope());
        lqw.eq(StringUtils.isNotBlank(bo.getReviewConclusion()), ZjkProductSummarize::getReviewConclusion, bo.getReviewConclusion());
        lqw.eq(StringUtils.isNotBlank(bo.getFeedback()), ZjkProductSummarize::getFeedback, bo.getFeedback());
        lqw.eq(StringUtils.isNotBlank(bo.getSubsequent()), ZjkProductSummarize::getSubsequent, bo.getSubsequent());
        lqw.eq(StringUtils.isNotBlank(bo.getAttachment()), ZjkProductSummarize::getAttachment, bo.getAttachment());
        lqw.eq(StringUtils.isNotBlank(bo.getExpertIds()), ZjkProductSummarize::getExpertIds, bo.getExpertIds());
        lqw.eq(bo.getStatus() != null, ZjkProductSummarize::getStatus, bo.getStatus());
        lqw.in(!CollectionUtil.isEmpty(bo.getProductIds()), ZjkProductSummarize::getProductId, bo.getProductIds());
        lqw.eq(bo.getProductId() != null, ZjkProductSummarize::getProductId, bo.getProductId());
        return lqw;
    }

    /**
     * 新增项目总结
     *
     * @param bo 项目总结
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ZjkProductSummarizeBo bo) {
        ZjkProductSummarize add = MapstructUtils.convert(bo, ZjkProductSummarize.class);
        validEntityBeforeSave(add);
        Long reviewId = bo.getReviewId();
        List<ZjkExpert> expertByReviewId = getExpertByReviewId(reviewId);
        if (!CollectionUtil.isEmpty(expertByReviewId)) {
            String collect = expertByReviewId.stream()
                .map(ZjkExpert::getExpertId) // 假设 ZjkExpert 有 getId() 方法
                .map(String::valueOf)  // 确保 id 被转换为字符串
                .collect(Collectors.joining(","));
            add.setExpertIds(collect);
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        zjkReviewPhaseMapper.updateByIds(Arrays.asList(bo.getReviewId()));
        String status = bo.getStatus();
        if (SummarizeStatusEnum.to_be_evaluated.getCode().equals(status)) {
            ZjkProductSummarizeLog zjkProductSummarizeLog = BeanUtil.copyProperties(add, ZjkProductSummarizeLog.class);
            zjkProductSummarizeLog.setId(null);
            zjkProductSummarizeLog.setSummarizeId(add.getId());
            zjkProductSummarizeLogMapper.insert(zjkProductSummarizeLog);
        }
        // 审批流程记录
        //zjkApprovalProcessLogsService.saveCommonApprovalRecord(ApprovalProcessTypeEnum.APPROVAL_INITIATED.getCode(),
        //    ApprovalProcessBusinessTypeEnum.PROJECT_APPROVALS.getCode(),
        //    null);
        return flag;
    }

    /**
     * 修改项目总结
     *
     * @param bo 项目总结
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ZjkProductSummarizeBo bo) {
        ZjkProductSummarize update = MapstructUtils.convert(bo, ZjkProductSummarize.class);
        validEntityBeforeSave(update);
        if (bo == null) {
            throw new ServiceException("无效参数");
        }
        Long id = bo.getId();
        if (id == null) {
            throw new ServiceException("无效id");
        }

        ZjkProductSummarizeVo zjkProductSummarizeVo = baseMapper.selectVoById(id);
        if (zjkProductSummarizeVo == null) {
            return false;
        }
        String status = zjkProductSummarizeVo.getStatus();
        if (SummarizeStatusEnum.to_be_evaluated.getCode().equals(status)) {
            throw new ServiceException("无法修改");
        }
        baseMapper.updateById(update);
        String status1 = bo.getStatus();
        if (SummarizeStatusEnum.to_be_evaluated.getCode().equals(status1)) {
            ZjkProductSummarizeLog zjkProductSummarizeLog = BeanUtil.copyProperties(bo, ZjkProductSummarizeLog.class);
            zjkProductSummarizeLog.setId(null);
            zjkProductSummarizeLog.setSummarizeId(bo.getId());
            zjkProductSummarizeLogMapper.insert(zjkProductSummarizeLog);
        }
        return true;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ZjkProductSummarize entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除项目总结信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public int auditSny(AuditVo auditVo) {
        Long id = auditVo.getId();
        if (id == null) {
            throw new ServiceException("id为空");
        }
        ZjkProductSummarize zjkProductSummarize = baseMapper.selectById(id);
        if (zjkProductSummarize == null) {
            throw new ServiceException("无效id");
        }
        Long userId = LoginHelper.getUserId();
        zjkProductSummarize.setAuditBy(userId);
        String auditRemark = auditVo.getAuditRemark();
        zjkProductSummarize.setAuditRemark(auditRemark);
        String auditStatus = auditVo.getAuditStatus();
        zjkProductSummarize.setAuditStatus(auditStatus);
        zjkProductSummarize.setStatus(auditStatus);
        zjkProductSummarize.setAuditTime(new Date());
        return baseMapper.updateById(zjkProductSummarize);
    }

    @Override
    public List<ZjkExpert> getExpertByReviewId(Long reviewId) {
        List<ZjkExpertItemVo> expertByReviewList = zjkExpertItemService.getExpertByReviewId(reviewId);
        if (CollectionUtil.isEmpty(expertByReviewList)) {
            return new ArrayList<>();
        }
        List<Long> list = expertByReviewList.stream().map(ZjkExpertItemVo::getExpertId).collect(Collectors.toList());
        List<ZjkExpert> zjkExperts = expertMapper.selectByIds(list);
        zjkExperts.forEach(zjkExpert -> {
            // 获取专业学历
            ZjkExpertMajor  zjkExpertMajor = zjkExpertMajorMapper.selectOne(new LambdaQueryWrapper<ZjkExpertMajor>()
                .eq(ZjkExpertMajor::getExpertId, zjkExpert.getExpertId())
                .orderByDesc(ZjkExpertMajor::getDegree)
                .last("limit 1"));
            if (zjkExpertMajor != null) {
                zjkExpert.setMajor(zjkExpertMajor.getMajor()+"/"+dictServiceImpl.getDictLabel("degree_type", String.valueOf(zjkExpertMajor.getDegree())));
            }
        });
        return zjkExperts;
    }

    @Override
    public List<ZjkProductSummarizeVo> getExpertByProductId(Long productId) {
        ZjkProductSummarizeBo bo = new ZjkProductSummarizeBo();
        bo.setProductId(productId);
        bo.setStatus(SummarizeStatusEnum.to_be_evaluated.getCode());
        LambdaQueryWrapper<ZjkProductSummarize> wrapper = buildQueryWrapper(bo);
        return baseMapper.selectVoList(wrapper);
    }

    @Override
    public boolean importSummarize(List<ZjkProductSummarizeExcelVO> vos) {
        Set<String> collect = vos.stream().map(ZjkProductSummarizeExcelVO::getProductName).collect(Collectors.toSet());

        LambdaQueryWrapper<ZjkProduct> lqw = Wrappers.lambdaQuery();
        lqw.in(ZjkProduct::getProductName,collect);
        lqw.eq(ZjkProduct::getUserId,LoginHelper.getUserId());
        List<ZjkProductVo> zjkProductVos = zjkProductMapper.selectVoList(lqw);
        if(CollectionUtil.isEmpty(zjkProductVos)){
            throw new ServiceException("无效项目");
        }
        Map<String, ZjkProductVo> productMap = zjkProductVos.stream().collect(Collectors.toMap(ZjkProductVo::getProductName, v -> v));

        //查询项目抽取
        List<Long> productSet = zjkProductVos.stream().map(ZjkProductVo::getId).collect(Collectors.toList());


        //获取项目全部评审阶段
        LambdaQueryWrapper<ZjkReviewPhase> ReviewLqw = Wrappers.lambdaQuery();
        ReviewLqw.in(ZjkReviewPhase::getItemId,productSet);
        ReviewLqw.eq(ZjkReviewPhase::getEffective,1);
        ReviewLqw.eq(ZjkReviewPhase::getParentId,0);
        ReviewLqw.eq(ZjkReviewPhase::getIsSummarize,0);
        List<ZjkReviewPhaseVo> zjkReviewPhaseVos = zjkReviewPhaseMapper.selectVoList(ReviewLqw);


        //项目总结
        LambdaQueryWrapper<ZjkProductSummarize> pSlqw = Wrappers.lambdaQuery();
        pSlqw.in(ZjkProductSummarize::getProductId, productSet);
        List<ZjkProductSummarizeVo> zjkProductSummarizeVos = baseMapper.selectVoList(pSlqw);
        Map<Long, ZjkProductSummarizeVo> zjkProductSummarizeVoMap = zjkProductSummarizeVos.stream().collect(Collectors.toMap(ZjkProductSummarizeVo::getReviewId, v -> v));

        List<ZjkProductSummarize> zjkProductSummarizes= new ArrayList<>();
        for (ZjkProductSummarizeExcelVO vo : vos) {
            if(!productMap.containsKey(vo.getProductName())){
                continue;
            }
            ZjkProductVo zjkProductVo = productMap.get(vo.getProductName());
            Long productId = zjkProductVo.getId();
            String reviewSn = vo.getReviewSn();

            ZjkProductSummarize  zjkProductSummarize = BeanUtil.copyProperties(vo, ZjkProductSummarize.class);
            zjkProductSummarize.setProductId(productId);
            List<ZjkReviewPhaseVo> collect1 = zjkReviewPhaseVos.stream().filter(s -> s.getReviewSn().equals(reviewSn) && s.getItemId().equals(productId)).collect(Collectors.toList());
            if(CollectionUtil.isEmpty(collect1)){
                throw new ServiceException("无效项目阶段，请修改");
            }
            for (ZjkReviewPhaseVo zjkReviewPhaseVo : collect1) {
                if(zjkProductSummarizeVoMap.containsKey(zjkReviewPhaseVo.getId())){
                    throw new ServiceException(vo.getProductName()+
                        ReviewSnEnum.getByCode(zjkReviewPhaseVo.getReviewSn()).getDesc()
                        +"阶段  已总结");
                }

                zjkProductSummarize.setReviewId(zjkReviewPhaseVo.getId());
            }
            List<ZjkExpert> expertByReviewId = getExpertByReviewId(zjkProductSummarize.getReviewId());
            if (!CollectionUtil.isEmpty(expertByReviewId)) {
                String collect11 = expertByReviewId.stream()
                    .map(ZjkExpert::getExpertId) // 假设 ZjkExpert 有 getId() 方法
                    .map(String::valueOf)  // 确保 id 被转换为字符串
                    .collect(Collectors.joining(","));
                zjkProductSummarize.setExpertIds(collect11);
            }
            zjkProductSummarize.setStatus(SummarizeStatusEnum.to_be_evaluated.getCode());
            zjkProductSummarize.setAttachment("[]");

            zjkProductSummarizes.add(zjkProductSummarize);
        }
         baseMapper.insertBatch(zjkProductSummarizes);

        List<ZjkProductSummarizeLog> zjkProductSummarizeLogs = BeanUtil.copyToList(zjkProductSummarizes, ZjkProductSummarizeLog.class);
        for (ZjkProductSummarizeLog zjkProductSummarizeLog : zjkProductSummarizeLogs) {
            zjkProductSummarizeLog.setSummarizeId(zjkProductSummarizeLog.getId());
            zjkProductSummarizeLog.setId(null);
        }
        zjkProductSummarizeLogMapper.insertBatch(zjkProductSummarizeLogs);
        Set<Long> reviewIds = zjkReviewPhaseVos.stream().map(ZjkReviewPhaseVo::getId).collect(Collectors.toSet());
        //修改项目总结 导入代码
        if(CollectionUtil.isNotEmpty(reviewIds)){
            zjkReviewPhaseMapper.updateByIds(reviewIds);
        }
        return true;
    }

    @Override
    public Long getCount() {
        LambdaQueryWrapper<ZjkProductSummarize> lqw = Wrappers.lambdaQuery();
        lqw.in(ZjkProductSummarize::getStatus, Arrays.asList(SummarizeStatusEnum.to_be_evaluated.getCode()));
        return baseMapper.selectCount(lqw);
    }
}
