package com.casic.missiles.service.Impl.workbench;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.casic.missiles.core.model.auth.AuthUser;
import com.casic.missiles.core.page.PageFactory;
import com.casic.missiles.core.shiro.ShiroKit;
import com.casic.missiles.dto.ReturnDTO;
import com.casic.missiles.dto.ReturnUtil;
import com.casic.missiles.dto.flowable.ToBeApprovedDTO;
import com.casic.missiles.dto.meter.*;
import com.casic.missiles.dto.workbench.ApprovalMessageRequest;
import com.casic.missiles.dto.workbench.ApprovalMessageUpdateRequest;
import com.casic.missiles.dto.workbench.MessageInfoCountRequest;
import com.casic.missiles.dto.workbench.MessageInfoCountResponse;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.enums.system.ApplyFromIdEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.mapper.meter.MeterFileMapper;
import com.casic.missiles.mapper.meter.MeterTraceSupplierMapper;
import com.casic.missiles.mapper.meter.MeterTrainPlanMapper;
import com.casic.missiles.mapper.workbench.WorkbenchApprovalMessageMapper;
import com.casic.missiles.mapper.workbench.WorkbenchRemindMessageMapper;
import com.casic.missiles.model.meter.MeterFile;
import com.casic.missiles.model.meter.MeterTraceSupplier;
import com.casic.missiles.model.meter.MeterTrainPlan;
import com.casic.missiles.model.workbench.WorkbenchApprovalMessage;
import com.casic.missiles.model.workbench.WorkbenchRemindMessage;
import com.casic.missiles.service.IBaseApprovalService;
import com.casic.missiles.service.workbench.IWorkbenchApprovalMessageService;
import com.casic.missiles.utils.ConvertUtils;
import com.casic.missiles.utils.DictCodeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 审批通过通知消息 服务实现类
 * </p>
 *
 * @author wangpeng
 * @since 2023-02-24
 */
@Service
public class WorkbenchApprovalMessageServiceImpl extends ServiceImpl<WorkbenchApprovalMessageMapper, WorkbenchApprovalMessage> implements IWorkbenchApprovalMessageService {
    @Autowired
    private IBaseApprovalService baseApprovalService;
    @Autowired
    private WorkbenchApprovalMessageMapper approvalMessageMapper;
    @Autowired
    private WorkbenchRemindMessageMapper remindMessageMapper;
    @Resource
    private MeterFileMapper meterFileMapper;
    @Autowired
    private MeterTrainPlanMapper trainPlanMapper;
    @Autowired
    private MeterTraceSupplierMapper traceSupplierMapper;

    /**
     * 所有业务待审批列表封装为消息
     * 计量管理：计量文件、培训计划、溯源供方
     * 测量设备：标准装置：更换、暂停、撤销、恢复、复查；
     *          状态管理：闲置、封存、启封、报废、处置，维护：检修、保养，领用，借用这些都在状态管理里，对应枚举：EquipmentApplyTypeEnum
     * 业务管理：分包方资格、项目申请、项目验收，现场检测
     */
    @Override
    public List<WorkbenchApprovalMessage> listPage(ApprovalMessageRequest request) throws Exception {
        AuthUser user = ShiroKit.getUser();
        Assert.isFalse(Objects.isNull(user), () -> {
            throw new BusinessException(BusinessExceptionEnum.LOGIN_USER_ACQUIRE_FAILED);
        });
        List<WorkbenchApprovalMessage> resultList = new ArrayList<>();
        //审批消息
        if(Objects.nonNull(request.getStatus()) && 0 == request.getStatus()){
            Arrays.stream(ApplyFromIdEnum.values()).forEach(applyFromIdEnum -> {
                if(StringUtils.isNotEmpty(request.getMessageSourceModule()) &&
                        !applyFromIdEnum.getSource().equals(request.getMessageSourceModule())){
                    return;
                }
                List<ToBeApprovedDTO> toBeApprovedList = baseApprovalService.getToBeApprovedList(applyFromIdEnum.getCode());
                if(CollectionUtils.isEmpty(toBeApprovedList)){
                    return;
                }
                toBeApprovedList.forEach(a -> {
                    WorkbenchApprovalMessage message = new WorkbenchApprovalMessage();
                    message.setCreateTime(a.getCreateTime());
                    message.setFormId(applyFromIdEnum.getCode());
                    message.setMessageSourceModule(applyFromIdEnum.getSource());
                    message.setMessageTitle("待审批通知");
                    message.setMessageContent(applyFromIdEnum.getValue());
                    message.setStatus(0);//待审批消息都是未读/未处理，处理后就不会在这个列表显示
                    message.setBusinessId(a.getBusinessKey());
                    message.setProcessId(a.getProcessId());
                    message.setTaskId(a.getTaskId());
                    message.setDecisionItem(a.getDecisionItem());
                    resultList.add(message);
                });
            });
        }
        //通知消息
        QueryWrapper<WorkbenchApprovalMessage> wrapper = new QueryWrapper<>();
        wrapper.eq("notice_id", user.getId());
        wrapper.eq(StringUtils.isNotBlank(request.getMessageSourceModule()), "message_source_module", request.getMessageSourceModule());
        wrapper.eq(Objects.nonNull(request.getStatus()), "status", request.getStatus());
        wrapper.apply(StringUtils.isNotBlank(request.getStartTime()),
                "{0} <= DATE_FORMAT(create_time,'%Y-%m-%d')", request.getStartTime().split(" ")[0]);
        wrapper.apply(StringUtils.isNotBlank(request.getEndTime()),
                "{0} >= DATE_FORMAT(create_time,'%Y-%m-%d')", request.getEndTime().split(" ")[0]);
        List<WorkbenchApprovalMessage> list = approvalMessageMapper.selectList(wrapper);
        if(!CollectionUtils.isEmpty(list)){
            resultList.addAll(list);
        }
        //按时间排序组装
        List<WorkbenchApprovalMessage> finalList = resultList.stream().sorted(Comparator.comparing(WorkbenchApprovalMessage::getCreateTime).reversed()).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(finalList)) {
            for (WorkbenchApprovalMessage approvalMessage : finalList) {
                DictCodeUtils.convertDictCodeToName(approvalMessage);
                //丰富跳转参数，仅计量文件、培训计划、溯源供方
                enrichSkipParams(approvalMessage);
            }
        }
        return finalList.stream().filter(message -> message.getDel() == 0).collect(Collectors.toList());
    }

    private void enrichSkipParams(WorkbenchApprovalMessage approvalMessage) {
        List<String> businessIds = new ArrayList<>();
        businessIds.add(approvalMessage.getBusinessId());
        if(ApplyFromIdEnum.FILE_APPROVAL.getCode().equals(approvalMessage.getFormId())) {
            List<MeterFile> meterFiles = meterFileMapper.selectBatchForApproval(PageFactory.defaultPage(), new FileApprovalListRequest(), businessIds);
            if(!CollectionUtils.isEmpty(meterFiles)){
                FileApprovalListResponse fileApprovalListResponse = ConvertUtils.sourceToTarget(meterFiles.get(0), FileApprovalListResponse.class);
                approvalMessage.setSkipParamsObject(fileApprovalListResponse);
            }else {
                //查询为空说明待审批在flowable中残留，在业务表中已删除
                approvalMessage.setDel(1);
            }
        }else if(ApplyFromIdEnum.TRAIN_APPROVAL.getCode().equals(approvalMessage.getFormId())) {
            List<MeterTrainPlan> meterTrainPlans = trainPlanMapper.selectBatchForApproval(PageFactory.defaultPage(), new TrainPlanApprovalListRequest(), businessIds);
            if(!CollectionUtils.isEmpty(meterTrainPlans)){
                TrainPlanApprovalListResponse trainPlanApprovalListResponse = ConvertUtils.sourceToTarget(meterTrainPlans.get(0), TrainPlanApprovalListResponse.class);
                approvalMessage.setSkipParamsObject(trainPlanApprovalListResponse);
            }else {
                approvalMessage.setDel(1);
            }
        }else if(ApplyFromIdEnum.STANDARD_EQUIPMENT.getCode().equals(approvalMessage.getFormId())) {
            List<MeterTraceSupplier> meterTraceSuppliers = traceSupplierMapper.selectBatchForApproval(PageFactory.defaultPage(), new TraceSupplierApprovalListRequest(), businessIds);
            if(!CollectionUtils.isEmpty(meterTraceSuppliers)){
                TraceSupplierApprovalListResponse traceSupplierApprovalListResponse = ConvertUtils.sourceToTarget(meterTraceSuppliers.get(0), TraceSupplierApprovalListResponse.class);
                approvalMessage.setSkipParamsObject(traceSupplierApprovalListResponse);
            }else {
                approvalMessage.setDel(1);
            }
        }
    }

    @Override
    public ReturnDTO updateStatus(ApprovalMessageUpdateRequest updateRequest) {
        WorkbenchApprovalMessage message = new WorkbenchApprovalMessage();
        if(Objects.isNull(updateRequest.getId())){
            String formId = updateRequest.getFormId();
            message.setNoticeId(ShiroKit.getUser().getId());
            message.setFormId(formId);
            message.setMessageSourceModule(ApplyFromIdEnum.getSourceByCode(formId));
            message.setMessageTitle("待审批通知");
            message.setMessageContent(ApplyFromIdEnum.getValueByCode(formId));
            message.setStatus(1);
            message.setBusinessId(updateRequest.getBusinessId());
            message.setProcessId(updateRequest.getProcessId());
            message.setTaskId(updateRequest.getTaskId());
            message.setDecisionItem(updateRequest.getDecisionItem());
            if(approvalMessageMapper.insert(message) > 0) return ReturnUtil.success();
        }else {
            message.setId(updateRequest.getId());
            message.setStatus(updateRequest.getStatus());
            if(approvalMessageMapper.updateById(message) > 0) return ReturnUtil.success();
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    @Override
    public MessageInfoCountResponse infoCount(MessageInfoCountRequest request) {
        //未处理待审批数量
        List<WorkbenchApprovalMessage> resultList = new ArrayList<>();
        Arrays.stream(ApplyFromIdEnum.values()).parallel().forEach(applyFromIdEnum -> {
            List<ToBeApprovedDTO> toBeApprovedList = baseApprovalService.getToBeApprovedList(applyFromIdEnum.getCode());
            if(CollectionUtils.isEmpty(toBeApprovedList)){
                return;
            }
            toBeApprovedList.forEach(a -> {
                WorkbenchApprovalMessage message = new WorkbenchApprovalMessage();
                message.setCreateTime(a.getCreateTime());
                resultList.add(message);
            });
        });
        //未处理的工作提醒数量
        Page<WorkbenchRemindMessage> page = PageFactory.defaultPage();
        QueryWrapper<WorkbenchRemindMessage> wrapper = new QueryWrapper<>();
        wrapper.eq( "remind_id", request.getRemindId());
        wrapper.eq("remind_dept_id", request.getRemindDeptId());
        wrapper.eq("status", 0);
        Page<WorkbenchRemindMessage> remindMessagePage = remindMessageMapper.selectPage(page, wrapper);

        MessageInfoCountResponse response = new MessageInfoCountResponse();
        response.setApprovalMessageCount(resultList.size());
        response.setRemindMessageCount(Math.toIntExact(remindMessagePage.getTotal()));
        return response;
    }
}
