package com.jwipc.spe.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.jwipc.aggregation.ModelAggregationService;
import com.jwipc.constant.FlagConst;
import com.jwipc.exception.DaoException;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.spe.constant.AppraisePlanSupplierStatus;
import com.jwipc.spe.constant.AppraiseRectifiedNoticeStatus;
import com.jwipc.spe.constant.EvaluationCycleType;
import com.jwipc.spe.convert.SupAppraisePlanSupplierConvert;
import com.jwipc.spe.convert.SupAppraiseRectifiedExamineLogConvert;
import com.jwipc.spe.convert.SupAppraiseRectifiedMeasuresConvert;
import com.jwipc.spe.convert.SupAppraiseRectifiedNoticeConvert;
import com.jwipc.spe.dto.*;
import com.jwipc.spe.entity.*;
import com.jwipc.spe.logic.RectifiedNoticeLogic;
import com.jwipc.spe.model.po.AppraiseRectifiedNoticePO;
import com.jwipc.spe.model.po.RectifiedSupplierPO;
import com.jwipc.spe.model.query.AppraiseRectifiedNoticeQuery;
import com.jwipc.spe.service.*;
import com.jwipc.sys.client.EmailSendClient;
import com.jwipc.sys.client.SequenceClient;
import com.jwipc.sys.client.SupplierEmailClient;
import com.jwipc.sys.client.dto.EmailTmpSendDTO;
import com.jwipc.sys.client.dto.SupplierEmailCDTO;
import com.jwipc.util.DateUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.jwipc.spe.constant.SequenceConst.RECTIFICATION_NOTICE_CODE;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class RectifiedNoticeLogicImpl implements RectifiedNoticeLogic {
    private final ISupAppraisePlanService appraisePlanService;
    private final ISupAppraisePlanSupplierService supAppraisePlanSupplierService;
    private final SupAppraisePlanSupplierConvert supAppraisePlanSupplierConvert;
    private final ModelAggregationService modelAggregationService;
    private final ISupAppraiseRectifiedNoticeService supAppraiseRectifiedNoticeService;
    private final ISupAppraiseRectifiedExamineLogService supAppraiseRectifiedExamineLogService;
    private final SupAppraiseRectifiedExamineLogConvert supAppraiseRectifiedExamineLogConvert;
    private final ISupAppraiseRectifiedMeasuresService supAppraiseRectifiedMeasuresService;
    private final SequenceClient sequenceClient;
    private final SupAppraiseRectifiedNoticeConvert supAppraiseRectifiedNoticeConvert;
    private final SupAppraiseRectifiedMeasuresConvert supAppraiseRectifiedMeasuresConvert;
    private final ISupAppraiseResultDetailService supAppraiseResultDetailService;
    private final SupplierEmailClient supplierEmailClient;
    private final EmailSendClient emailSendClient;


    @Override
    public SupAppraisePlanSupplierBaseDTO getAppraisePlan(Long supplierPlanId) {
        final SupAppraisePlanSupplier planSupplier = supAppraisePlanSupplierService.getById(supplierPlanId);
        SupAppraisePlanSupplierBaseDTO supAppraisePlanSupplierBaseDTO = supAppraisePlanSupplierConvert.entity2Dto(
                planSupplier);
        modelAggregationService.processRelationAggregation(supAppraisePlanSupplierBaseDTO);
        return supAppraisePlanSupplierBaseDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitRectification(AppraiseRectifiedNoticeSaveDTO saveDTO)
    {
        final SupAppraisePlanSupplier result = supAppraisePlanSupplierService.getById(saveDTO.getSupplierPlanId());
        final SupAppraisePlanSupplierBaseDTO supAppraisePlanSupplierBaseDTO = supAppraisePlanSupplierConvert.entity2Dto(
                result);
        modelAggregationService.processRelationAggregation(supAppraisePlanSupplierBaseDTO);
        if (Objects.isNull(result)) {
            throw new DaoException("操作失败，未找到考核结果记录");
        }
        if (!Objects.equals(AppraisePlanSupplierStatus.NEWLY_BUILD.getIndex(), result.getStatus())) {
            throw new DaoException("操作失败，考核结果记录已经被处理");
        }
        result.setStatus(AppraisePlanSupplierStatus.SUBMITTED_CORRECT.getIndex());
        supAppraisePlanSupplierService.updateById(result);
        final String noticeCode =
                sequenceClient.createSequenceNo(RECTIFICATION_NOTICE_CODE.getCode());
        SupAppraiseRectifiedNotice notice = new SupAppraiseRectifiedNotice();
        notice.setNoticeCode(noticeCode);
        notice.setStatus(AppraiseRectifiedNoticeStatus.WAIT_RECTIFICATION.getIndex());
        notice.setId(null);
        notice.setSupplierPlanId(result.getId());
        notice.setCreateTime(LocalDateTime.now());
        notice.setCreateUserId(LoginUtil.getUserId());
        notice.setCreateUserCode(LoginUtil.getName());
        notice.setCreateUserName(LoginUtil.getAccount());
        notice.setConfirmUserCode(saveDTO.getConfirmUserCode());
        notice.setSupplierCode(supAppraisePlanSupplierBaseDTO.getSupplierCode());
        notice.setSupplierName(supAppraisePlanSupplierBaseDTO.getSupplierName());
        notice.setOpinionRemark(saveDTO.getOpinionRemark());
        supAppraiseRectifiedNoticeService.save(notice);
        // 格式化整改措施信息
        if (CollUtil.isNotEmpty(saveDTO.getMeasures())) {
            List<SupAppraiseRectifiedMeasures> insList = supAppraiseRectifiedMeasuresConvert.dtos2Entities(
                    saveDTO.getMeasures());
            for (SupAppraiseRectifiedMeasures supAppraiseRectifiedMeasures : insList) {
                supAppraiseRectifiedMeasures.setNoticeOrderId(notice.getId());
            }
            if (CollUtil.isNotEmpty(insList)) {
                supAppraiseRectifiedMeasuresService.saveBatch(insList);
            }
        }
    }

    @Override
    public PageView getList(AppraiseRectifiedNoticeQuery query) {
        Page<AppraiseRectifiedNoticePO> page = PageUtil.toPage(query);
        if (LoginUtil.isSupplier()) {
            query.setSupplierId(LoginUtil.getSupplierId());
        }
        final List<AppraiseRectifiedNoticeDTO> dtos = getNoticeDTOS(query, page);
        return PageUtil.getPV(dtos, page.getTotal());
    }

    private List<AppraiseRectifiedNoticeDTO> getNoticeDTOS(AppraiseRectifiedNoticeQuery query,
                                                           Page<AppraiseRectifiedNoticePO> page)
    {
        List<AppraiseRectifiedNoticePO> pos = supAppraiseRectifiedNoticeService.findForList(page, query);
        List<AppraiseRectifiedNoticeDTO> dtos = supAppraiseRectifiedNoticeConvert.pos2Dtos(pos);
        return dtos;
    }

    @Override
    public Pair<SupAppraiseRectifiedNoticeBaseDTO, AppraiseReportDTO> getDetail(Long id) {
        final SupAppraiseRectifiedNotice rectifiedNotice = supAppraiseRectifiedNoticeService.getById(id);
        if (Objects.nonNull(rectifiedNotice)) {
            //需要获取绩效考核的数据
            final Long supplierPlanId = rectifiedNotice.getSupplierPlanId();
            final List<SupAppraiseResultDetail> list = supAppraiseResultDetailService.list(
                    new LambdaQueryWrapper<>(SupAppraiseResultDetail.class)
                            .eq(SupAppraiseResultDetail::getSupplierPlanId, supplierPlanId));
            final Long planId = list.get(0).getPlanId();
            final SupAppraisePlan supAppraisePlan = appraisePlanService.getById(planId);
            final AppraiseReportDTO appraiseReportDTO = new AppraiseReportDTO();
            appraiseReportDTO.setMonth(supAppraisePlan.getMonth());
            appraiseReportDTO.setYear(supAppraisePlan.getYear());
            final Map<String, SupAppraiseResultDetail> resultDetailMap = list.stream()
                    .collect(Collectors.toMap(SupAppraiseResultDetail::getQuotaCode, a -> a));
            final String zwPz25 = resultDetailMap.get("ZW_PZ_25").getFinalScore();//总分
            appraiseReportDTO.setScore(zwPz25);
            final String zwPz26 = resultDetailMap.get("ZW_PZ_26").getFinalScore();//等级
            appraiseReportDTO.setLevel(zwPz26);

            final String zwPz01 = resultDetailMap.get("ZW_PZ_01").getFinalScore();//进料批次
            final String zwPz13 = resultDetailMap.get("ZW_PZ_13").getFinalScore();//判退批次
            final BigDecimal bigDecimal1 = new BigDecimal(zwPz01);
            final BigDecimal bigDecimal2 = new BigDecimal(zwPz13);
            if (bigDecimal1.compareTo(BigDecimal.ZERO) > 0) {
                final String plainString = bigDecimal1.subtract(bigDecimal2).divide(bigDecimal1, 4, RoundingMode.DOWN)
                        .stripTrailingZeros().multiply(BigDecimal.valueOf(100)).toPlainString();
                appraiseReportDTO.setContent1(plainString);
            }
            final String zwPz03 = resultDetailMap.get("ZW_PZ_03").getFinalScore();//产线异常笔数(3%＜不良率≤50%)
            final String zwPz04 = resultDetailMap.get("ZW_PZ_04").getFinalScore();//产线异常笔数(50%＜不良率≤100%)
            final String zwPz05 = resultDetailMap.get("ZW_PZ_05").getFinalScore();//产线停线扣分笔数
            final String plainString = new BigDecimal(zwPz03).add(new BigDecimal(zwPz04)).add(new BigDecimal(zwPz05))
                    .stripTrailingZeros().toPlainString();
            appraiseReportDTO.setContent2(plainString);

            final String zwPz02 = new BigDecimal(resultDetailMap.get("ZW_PZ_02").getFinalScore()).stripTrailingZeros()
                    .toPlainString();//产线异常笔数(不良率≤3%)
            appraiseReportDTO.setContent3(zwPz02);

            final String zwPz06 = resultDetailMap.get("ZW_PZ_06").getFinalScore();//OQC/客验扣分笔数
            final String zwPz10 = resultDetailMap.get("ZW_PZ_10").getFinalScore();//客诉笔数(一般客诉)
            final String zwPz11 = resultDetailMap.get("ZW_PZ_11").getFinalScore();//客诉笔数(严重客诉)
            final String zwPz12 = resultDetailMap.get("ZW_PZ_12").getFinalScore();//客诉笔数(特大客诉)
            final String plainString1 = new BigDecimal(zwPz06).add(new BigDecimal(zwPz10)).add(new BigDecimal(zwPz11))
                    .add(new BigDecimal(zwPz12))
                    .stripTrailingZeros().toPlainString();
            appraiseReportDTO.setContent4(plainString1);

            final String zwPz08 = new BigDecimal(resultDetailMap.get("ZW_PZ_08").getFinalScore()).stripTrailingZeros()
                    .toPlainString();//错/混料扣分笔数
            appraiseReportDTO.setContent5(zwPz08);

            final String zwPz09 = new BigDecimal(resultDetailMap.get("ZW_PZ_09").getFinalScore()).stripTrailingZeros()
                    .toPlainString();//重复发生问题扣分笔数 (功能或可靠性不良)
            appraiseReportDTO.setContent6(zwPz09);

//            final String zwPz29 = new BigDecimal(resultDetailMap.get("ZW_PZ_29").getFinalScore()).stripTrailingZeros()
//                    .toPlainString();//有害物质超标扣分
//            appraiseReportDTO.setContent7(zwPz29);

            //需要修改环保不良次数统计
            //ZW_PZ_33 有害物质超标次数
            if(resultDetailMap.get("ZW_PZ_33") != null){
                final String ZW_PZ_33 = new BigDecimal(resultDetailMap.get("ZW_PZ_33").getFinalScore()).stripTrailingZeros()
                        .toPlainString();//有害物质超标扣分
                appraiseReportDTO.setContent7(ZW_PZ_33);
            }else{
                final String zwPz29 = new BigDecimal(resultDetailMap.get("ZW_PZ_29").getFinalScore()).stripTrailingZeros()
                    .toPlainString();//有害物质超标扣分
            appraiseReportDTO.setContent7(zwPz29);
            }

            //需要增加pcn不良次数统计
            //ZW_PZ_34 供应商PCN违规次数
            if(resultDetailMap.get("ZW_PZ_34") !=null){
                final String zwPz34 = new BigDecimal(resultDetailMap.get("ZW_PZ_34").getFinalScore()).stripTrailingZeros()
                        .toPlainString();//有害物质超标扣分
                appraiseReportDTO.setContent8(zwPz34);
            }else{
                appraiseReportDTO.setContent8("0");
            }

            return Pair.of(supAppraiseRectifiedNoticeConvert.entity2Dto(rectifiedNotice), appraiseReportDTO);
        }
        SupAppraiseRectifiedNoticeBaseDTO supAppraiseRectifiedNoticeBaseDTO = new SupAppraiseRectifiedNoticeBaseDTO();
        supAppraiseRectifiedNoticeBaseDTO.setSupplierPlanId(-1L);
        supAppraiseRectifiedNoticeBaseDTO.setId(-1L);
        return Pair.of(supAppraiseRectifiedNoticeBaseDTO, null);
    }

    @Override
    public PageView getMeasuresList(Long id) {
        final List<SupAppraiseRectifiedMeasures> measures = supAppraiseRectifiedMeasuresService.list(
                new LambdaQueryWrapper<SupAppraiseRectifiedMeasures>()
                        .eq(SupAppraiseRectifiedMeasures::getNoticeOrderId, id));
        List<AppraiseRectifiedMeasuresBaseDTO> dtos = supAppraiseRectifiedMeasuresConvert.entities2Dtos(measures);
        return PageUtil.getPV(dtos, dtos.size());
    }

    @Override
    public PageView getExamineLogList(Long noticeId) {
        final List<SupAppraiseRectifiedExamineLog> examineLogs = supAppraiseRectifiedExamineLogService.list(
                new LambdaQueryWrapper<SupAppraiseRectifiedExamineLog>()
                        .eq(SupAppraiseRectifiedExamineLog::getNoticeOrderId, noticeId));
        List<AppraiseRectifiedExamineLogBaseDTO> logBaseDTOS = supAppraiseRectifiedExamineLogConvert.entities2Dtos(
                examineLogs);
        return PageUtil.getPV(logBaseDTOS, logBaseDTOS.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRectification(AppraiseRectifiedNoticeUpdateDTO updateDTO) {
        final SupAppraiseRectifiedNotice notice = supAppraiseRectifiedNoticeService.getById(updateDTO.getNoticeId());
        notice.setAttachments(updateDTO.getAttachments());
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateUserId(LoginUtil.getUserId());
        notice.setUpdateUserCode(LoginUtil.getAccount());
        notice.setUpdateUserName(LoginUtil.getName());
        //如果待整改或者确认不通过，状态设为已整改
        if (Objects.equals(notice.getStatus(), AppraiseRectifiedNoticeStatus.WAIT_RECTIFICATION.getIndex()) ||
                Objects.equals(notice.getStatus(), AppraiseRectifiedNoticeStatus.CONFIRM_NOT.getIndex())) {
            notice.setStatus(AppraiseRectifiedNoticeStatus.SUBMIT.getIndex());
        }
        supAppraiseRectifiedNoticeService.updateById(notice);
        List<SupAppraiseRectifiedMeasures> insList = Lists.newArrayList();
        List<SupAppraiseRectifiedMeasures> delList = Lists.newArrayList();
        Map<Long, String> map = Maps.newHashMap();
        for (AppraiseRectifiedMeasuresBaseDTO dto : updateDTO.getMeasures()) {
            SupAppraiseRectifiedMeasures measures = supAppraiseRectifiedMeasuresConvert.dto2Entitie(dto);
            measures.setMeasuresContent(dto.getMeasuresContent());
            measures.setPersonLiable(dto.getPersonLiable());
            measures.setStatus(dto.getStatus());
            measures.setAttachments(dto.getAttachments());
            if (dto.getId() != 0 && dto.getNoticeOrderId() == -1) {
                measures.setId(dto.getId());
                delList.add(measures);
            } else {
                if (dto.getId() != 0) {
                    measures.setId(dto.getId());
                } else {
                    measures.setId(IdWorker.getId());
                }
                measures.setNoticeOrderId(notice.getId());
                insList.add(measures);
                map.put(measures.getId(), dto.getAttachments());
            }
        }
        if (CollUtil.isNotEmpty(delList)) {
            for (SupAppraiseRectifiedMeasures appraiseRectifiedMeasures : delList) {
                supAppraiseRectifiedMeasuresService.removeById(appraiseRectifiedMeasures.getId());
            }
        }
        if (CollUtil.isNotEmpty(insList)) {
            supAppraiseRectifiedMeasuresService.saveOrUpdateBatch(insList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRectification1(AppraiseRectifiedNoticeUpdateDTO updateDTO) {
        final SupAppraiseRectifiedNotice notice = supAppraiseRectifiedNoticeService.getById(updateDTO.getNoticeId());
        notice.setAttachments(updateDTO.getAttachments());
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateUserId(LoginUtil.getUserId());
        notice.setUpdateUserCode(LoginUtil.getAccount());
        notice.setUpdateUserName(LoginUtil.getName());
        //如果待整改或者确认不通过，状态设为已整改
        if (Objects.equals(notice.getStatus(), AppraiseRectifiedNoticeStatus.WAIT_RECTIFICATION.getIndex()) ||
                Objects.equals(notice.getStatus(), AppraiseRectifiedNoticeStatus.CONFIRM_NOT.getIndex())) {
            notice.setStatus(AppraiseRectifiedNoticeStatus.WAIT_TRACK.getIndex());
        }
        supAppraiseRectifiedNoticeService.updateById(notice);
        List<SupAppraiseRectifiedMeasures> insList = Lists.newArrayList();
        List<SupAppraiseRectifiedMeasures> delList = Lists.newArrayList();
        Map<Long, String> map = Maps.newHashMap();
        for (AppraiseRectifiedMeasuresBaseDTO dto : updateDTO.getMeasures()) {
            SupAppraiseRectifiedMeasures measures = supAppraiseRectifiedMeasuresConvert.dto2Entitie(dto);
            measures.setMeasuresContent(dto.getMeasuresContent());
            measures.setPersonLiable(dto.getPersonLiable());
            measures.setStatus(dto.getStatus());
            measures.setAttachments(dto.getAttachments());
            if (dto.getId() != 0 && dto.getNoticeOrderId() == -1) {
                measures.setId(dto.getId());
                delList.add(measures);
            } else {
                if (dto.getId() != 0) {
                    measures.setId(dto.getId());
                } else {
                    measures.setId(IdWorker.getId());
                }
                measures.setNoticeOrderId(notice.getId());
                insList.add(measures);
                map.put(measures.getId(), dto.getAttachments());
            }
        }
        if (CollUtil.isNotEmpty(delList)) {
            for (SupAppraiseRectifiedMeasures appraiseRectifiedMeasures : delList) {
                supAppraiseRectifiedMeasuresService.removeById(appraiseRectifiedMeasures.getId());
            }
        }
        if (CollUtil.isNotEmpty(insList)) {
            supAppraiseRectifiedMeasuresService.saveOrUpdateBatch(insList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitRectified(Long noticeId) {
        SupAppraiseRectifiedNotice notice = supAppraiseRectifiedNoticeService.getById(noticeId);
        if (Objects.isNull(notice)) {
            throw new DaoException("未找到相应的通知单记录");
        }
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateUserId(LoginUtil.getUserId());
        notice.setUpdateUserCode(LoginUtil.getAccount());
        notice.setUpdateUserName(LoginUtil.getName());
        final long count = supAppraiseRectifiedMeasuresService.count(
                new LambdaQueryWrapper<SupAppraiseRectifiedMeasures>()
                        .eq(SupAppraiseRectifiedMeasures::getNoticeOrderId, noticeId));
        if (count <= 0) {
            throw new DaoException("未添加任何整改措施，不允许提交审批");
        }
        //状态为待确认
        notice.setStatus(AppraiseRectifiedNoticeStatus.WAIT_CONFIRM.getIndex());
        supAppraiseRectifiedNoticeService.updateById(notice);
        SupAppraiseRectifiedExamineLog examineLog = new SupAppraiseRectifiedExamineLog();
        examineLog.setId(null);
        examineLog.setExamineStatus(1);
        examineLog.setExamineTime(LocalDateTime.now());
        examineLog.setExamineUserCode(LoginUtil.getAccount());
        examineLog.setExamineUserName(LoginUtil.getName());
        examineLog.setNoticeOrderId(notice.getId());
        examineLog.setNoticeOrderCode(notice.getNoticeCode());
        examineLog.setExamineView("提交整改审批");
        supAppraiseRectifiedExamineLogService.save(examineLog);
        supAppraisePlanSupplierService.update(new LambdaUpdateWrapper<SupAppraisePlanSupplier>()
                .eq(SupAppraisePlanSupplier::getId, notice.getSupplierPlanId())
                .set(SupAppraisePlanSupplier::getStatus, AppraisePlanSupplierStatus.SUBMITTED_CORRECT.getIndex()));
    }

    @Override
    public PageView getConfirmList(AppraiseRectifiedNoticeQuery query) {
        Page<AppraiseRectifiedNoticePO> page = PageUtil.toPage(query);
        //待确认只查询待确认的数据
        if (Objects.isNull(query.getStatusStr())) {
            final String statusStr = AppraiseRectifiedNoticeStatus.WAIT_CONFIRM.getIndex() + "," +
                    AppraiseRectifiedNoticeStatus.NEW.getIndex();
            query.setStatusStr(statusStr);
        }
        if (Objects.nonNull(query.getStatusStr()) &&
                !query.getStatusStr().equals(String.valueOf(AppraiseRectifiedNoticeStatus.COMPLETED.getIndex()))) {
        }
        final List<AppraiseRectifiedNoticeDTO> noticeDTOS = getNoticeDTOS(query, page);
        return PageUtil.getPV(noticeDTOS, page.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitConfirm(Long noticeId, String examineView, Integer passFlag) {
        final SupAppraiseRectifiedNotice notice = supAppraiseRectifiedNoticeService.getById(noticeId);
        if (Objects.isNull(notice)) {
            throw new DaoException("未找到相应的通知单记录");
        }
        SupAppraiseRectifiedExamineLog examineLog = new SupAppraiseRectifiedExamineLog();

        if (passFlag == FlagConst.Y.getCode()) {
            notice.setStatus(AppraiseRectifiedNoticeStatus.WAIT_TRACK.getIndex());
        } else {
            notice.setStatus(AppraiseRectifiedNoticeStatus.CONFIRM_NOT.getIndex());
        }
        notice.setUpdateTime(LocalDateTime.now());
        notice.setUpdateUserId(LoginUtil.getUserId());
        notice.setUpdateUserCode(LoginUtil.getAccount());
        notice.setUpdateUserName(LoginUtil.getName());
        examineLog.setExamineStatus(passFlag);
        examineLog.setExamineView(examineView);
        supAppraiseRectifiedNoticeService.updateById(notice);
        examineLog.setId(null);
        examineLog.setExamineTime(LocalDateTime.now());
        examineLog.setExamineUserCode(LoginUtil.getAccount());
        examineLog.setExamineUserName(LoginUtil.getName());
        examineLog.setNoticeOrderId(notice.getId());
        examineLog.setNoticeOrderCode(notice.getNoticeCode());
        supAppraiseRectifiedExamineLogService.save(examineLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitExamine(AppraiseRectifiedNoticeExamineSaveDTO saveDTO) {
        final SupAppraiseRectifiedNotice rectifiedNotice = supAppraiseRectifiedNoticeService.getById(
                saveDTO.getNoticeId());
        if (Objects.isNull(rectifiedNotice)) {
            throw new DaoException("未找到相应的通知单记录");
        }
        SupAppraiseRectifiedExamineLog examineLog = new SupAppraiseRectifiedExamineLog();
        final LambdaUpdateWrapper<SupAppraiseRectifiedNotice> updateWrapper =
                new LambdaUpdateWrapper<SupAppraiseRectifiedNotice>()
                        .eq(SupAppraiseRectifiedNotice::getId, saveDTO.getNoticeId());
        if (Objects.equals(saveDTO.getTrackFlag(), FlagConst.Y.getCode())) {
            List<SupAppraiseRectifiedMeasures> meList = supAppraiseRectifiedMeasuresConvert.dtos2Entities(
                    saveDTO.getMeasures());

            if (CollUtil.isNotEmpty(meList)) {
                supAppraiseRectifiedMeasuresService.updateBatchById(meList);
            }
            final List<SupAppraiseRectifiedMeasures> measures = supAppraiseRectifiedMeasuresService.list(
                    new LambdaQueryWrapper<SupAppraiseRectifiedMeasures>()
                            .eq(SupAppraiseRectifiedMeasures::getNoticeOrderId, saveDTO.getNoticeId()));
            // 默认整改通知单状态为 待审批
            int meStatus = AppraiseRectifiedNoticeStatus.WAIT_EXAMINE.getIndex();
            for (SupAppraiseRectifiedMeasures med : measures) {
                // 如果有行项目状态为open，则通知单状态为待跟踪
                if (Objects.equals(med.getStatus(), FlagConst.N.getCode())) {
                    meStatus = AppraiseRectifiedNoticeStatus.WAIT_TRACK.getIndex();
                    break;
                } else {
                    meStatus = AppraiseRectifiedNoticeStatus.COMPLETED.getIndex();
                    break;
                }
            }
            updateWrapper.set(SupAppraiseRectifiedNotice::getStatus, meStatus);

            examineLog.setExamineStatus(meStatus == AppraiseRectifiedNoticeStatus.WAIT_EXAMINE.getIndex() ? 10 : 20);
            examineLog.setExamineView(meStatus ==
                    AppraiseRectifiedNoticeStatus.WAIT_EXAMINE.getIndex() ? "整改跟踪通过" : "整改跟踪不通过");
        } else {
            if (saveDTO.getExamineStatus() == 1) {
                updateWrapper.set(SupAppraiseRectifiedNotice::getStatus,
                        AppraiseRectifiedNoticeStatus.COMPLETED.getIndex());
            } else {
                updateWrapper.set(SupAppraiseRectifiedNotice::getStatus,
                        AppraiseRectifiedNoticeStatus.WAIT_RECTIFICATION.getIndex());
            }
            examineLog.setExamineStatus(saveDTO.getExamineStatus());
            examineLog.setExamineView(saveDTO.getExamineView());
        }
        supAppraiseRectifiedNoticeService.update(updateWrapper);
        examineLog.setExamineTime(LocalDateTime.now());
        examineLog.setExamineUserCode(LoginUtil.getAccount());
        examineLog.setExamineUserName(LoginUtil.getName());
        examineLog.setNoticeOrderId(rectifiedNotice.getId());
        examineLog.setNoticeOrderCode(rectifiedNotice.getNoticeCode());
        supAppraiseRectifiedExamineLogService.save(examineLog);

    }

    @Override
    public Set<String> getAppraiseItem(Long supplierPlanId) {
        final List<SupAppraiseResultDetail> list = supAppraiseResultDetailService.list(
                new LambdaQueryWrapper<SupAppraiseResultDetail>()
                        .eq(SupAppraiseResultDetail::getSupplierPlanId, supplierPlanId)
                        .in(SupAppraiseResultDetail::getQuotaCode, Sets.newHashSet("ZW_PZ_30", "ZW_PZ_31")));
        final Set<String> collect = list.stream().filter(a -> StrUtil.isNotEmpty(a.getFinalScore()))
                .map(SupAppraiseResultDetail::getFinalScore)
                .collect(Collectors.toSet());
        return collect;
    }

    @Override
    public void saveBatchNotice(String ids, Long planId) {
        final List<RectifiedSupplierPO> rectifiedSupplier = supAppraisePlanSupplierService.findRectifiedSupplier(
                planId);
        final List<String> split = StrUtil.split(ids, ",");
        final List<RectifiedSupplierPO> list = rectifiedSupplier.stream()
                .filter(a -> split.contains(String.valueOf(a.getId())) &&
                        Objects.equals(a.getStatus(), AppraisePlanSupplierStatus.NEWLY_BUILD.getIndex())).toList();
        if (CollUtil.isNotEmpty(list)) {
            final LocalDateTime now = LocalDateTime.now();
            final Set<String> supplierCodeCache = list.stream().map(RectifiedSupplierPO::getSupplierCode)
                    .collect(Collectors.toSet());
            final List<SupplierEmailCDTO> supplierEmails = supplierEmailClient.getSupplierEmails(supplierCodeCache);
            final Map<String, List<SupplierEmailCDTO>> supplierPurchaseUserCache = supplierEmails.stream()
                    .collect(Collectors.groupingBy(SupplierEmailCDTO::getSupplierCode));
            final SupAppraisePlan ap = appraisePlanService.getById(planId);
            String date = StrUtil.EMPTY;
            if (ap.getEvaluationCycle().compareTo(EvaluationCycleType.YEAR.getValue()) == 0) {
                date = ap.getYear() + "年";
            } else if (ap.getEvaluationCycle().compareTo(EvaluationCycleType.MONTH.getValue()) == 0) {
                date = ap.getYear() + "年" + ap.getMonth() + "月";

            } else if (ap.getEvaluationCycle().compareTo(EvaluationCycleType.QUARTER.getValue()) == 0) {
                date = ap.getYear() + "年" + ap.getQuarter() + "季度";
            }

            //需要批量处理整改数据
            List<SupAppraiseRectifiedMeasures> insertLists = Lists.newArrayList();
            for (RectifiedSupplierPO rectifiedSupplierPO : list) {
                final String noticeCode =
                        sequenceClient.createSequenceNo(RECTIFICATION_NOTICE_CODE.getCode());
                SupAppraiseRectifiedNotice notice = new SupAppraiseRectifiedNotice();
                notice.setNoticeCode(noticeCode);
                notice.setStatus(AppraiseRectifiedNoticeStatus.NEW.getIndex());
                notice.setId(null);
                notice.setSupplierPlanId(rectifiedSupplierPO.getId());

                notice.setCreateTime(now);
                notice.setCreateUserId(LoginUtil.getUserId());
                notice.setCreateUserCode(LoginUtil.getAccount());
                notice.setCreateUserName(LoginUtil.getName());
                notice.setConfirmUserCode(LoginUtil.getAccount());
                notice.setSupplierCode(rectifiedSupplierPO.getSupplierCode());
                notice.setSupplierName(rectifiedSupplierPO.getSupplierName());
                supAppraiseRectifiedNoticeService.save(notice);
                if (StrUtil.isNotEmpty(rectifiedSupplierPO.getRemark1())) {
                    SupAppraiseRectifiedMeasures measure = new SupAppraiseRectifiedMeasures();
                    measure.setNoticeOrderId(notice.getId());
                    measure.setIndexRemark(rectifiedSupplierPO.getRemark1());
                    insertLists.add(measure);
                }
                if (StrUtil.isNotEmpty(rectifiedSupplierPO.getRemark2())) {
                    SupAppraiseRectifiedMeasures measure = new SupAppraiseRectifiedMeasures();
                    measure.setNoticeOrderId(notice.getId());
                    measure.setIndexRemark(rectifiedSupplierPO.getRemark2());
                    insertLists.add(measure);
                }
                //需要发送邮件
                final List<SupplierEmailCDTO> supplierEmailCDTOS = supplierPurchaseUserCache.get(
                        rectifiedSupplierPO.getSupplierCode());
                if (CollUtil.isNotEmpty(supplierEmailCDTOS)) {
                    final Set<String> emails = supplierEmailCDTOS.stream()
                            .filter(a -> StrUtil.isNotEmpty(a.getEmail())).map(
                                    SupplierEmailCDTO::getEmail).collect(
                                    Collectors.toSet());
                    if (CollUtil.isNotEmpty(emails)) {
                        Map<String, Object> params = Maps.newHashMap();
                        params.put("code", noticeCode);
                        params.put("month", date);
                        params.put("creater", LoginUtil.getName());
                        params.put("time", DateUtils.formatYYYYMMDD(now));
                        EmailTmpSendDTO a = new EmailTmpSendDTO();
                        a.setReceiver(emails);
                        a.setSender(LoginUtil.getUserId());
                        a.setTemplateCode("JW_POST_130");
                        a.setParams(params);
                        emailSendClient.async(a);
                    }
                }
            }
            if (CollUtil.isNotEmpty(insertLists)) {
                supAppraiseRectifiedMeasuresService.saveBatch(insertLists);
            }
            final LambdaUpdateWrapper<SupAppraisePlanSupplier> updateWrapper =
                    new LambdaUpdateWrapper<SupAppraisePlanSupplier>()
                            .set(SupAppraisePlanSupplier::getStatus,
                                    AppraisePlanSupplierStatus.SUBMITTED_CORRECT.getIndex())
                            .in(SupAppraisePlanSupplier::getId, split);
            supAppraisePlanSupplierService.update(updateWrapper);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNotice(AppraiseRectifiedNoticeSaveDTO saveDTO) {
        final Long id = saveDTO.getId();
        final SupAppraiseRectifiedNotice rectifiedNotice = supAppraiseRectifiedNoticeService.getById(id);
        if (Objects.isNull(rectifiedNotice)) {
            throw new DaoException("整改单不存在!");
        }
        supAppraiseRectifiedNoticeService.update(new LambdaUpdateWrapper<>(SupAppraiseRectifiedNotice.class)
                .set(SupAppraiseRectifiedNotice::getOpinionRemark, saveDTO.getOpinionRemark())
                .set(SupAppraiseRectifiedNotice::getReportJson, saveDTO.getReportJson())
                .set(SupAppraiseRectifiedNotice::getStatus, AppraiseRectifiedNoticeStatus.WAIT_RECTIFICATION.getIndex())
                .eq(SupAppraiseRectifiedNotice::getId, id));
        final List<AppraiseRectifiedMeasuresBaseDTO> measures = saveDTO.getMeasures();
        supAppraiseRectifiedMeasuresService.remove(new LambdaQueryWrapper<SupAppraiseRectifiedMeasures>()
                .eq(SupAppraiseRectifiedMeasures::getNoticeOrderId, id
                ));
        for (AppraiseRectifiedMeasuresBaseDTO measure : measures) {
            measure.setNoticeOrderId(id);
        }
        final List<SupAppraiseRectifiedMeasures> supAppraiseRectifiedMeasures =
                supAppraiseRectifiedMeasuresConvert.dtos2Entities(
                        measures);
        supAppraiseRectifiedMeasuresService.saveBatch(supAppraiseRectifiedMeasures);

    }

    @Override
    public PageView getAllList(AppraiseRectifiedNoticeQuery query) {
        Page<AppraiseRectifiedNoticePO> page = PageUtil.toPage(query);
        List<AppraiseRectifiedNoticePO> pos = supAppraiseRectifiedNoticeService.findAllForList(page, query);
        List<AppraiseRectifiedNoticeDTO> dtos = supAppraiseRectifiedNoticeConvert.pos2Dtos(pos);
        return PageUtil.getPV(dtos, page.getTotal());
    }
}