package com.patzn.lims.staff.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.patzn.lims.common.StringHandleUtils;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.res.service.ILmsBaseDictService;
import com.patzn.lims.res.service.ILmsPropertyService;
import com.patzn.lims.staff.entity.LmsStaffTrainPlan;
import com.patzn.lims.staff.entity.LmsStaffTrainPlanAttachment;
import com.patzn.lims.staff.entity.LmsStaffTrainPlanRecord;
import com.patzn.lims.staff.enums.StaffTrainPlanEnum;
import com.patzn.lims.staff.mapper.LmsStaffTrainPlanMapper;
import com.patzn.lims.staff.service.ILmsStaffTrainPlanAttachmentService;
import com.patzn.lims.staff.service.ILmsStaffTrainPlanRecordService;
import com.patzn.lims.staff.service.ILmsStaffTrainPlanService;
import com.patzn.lims.staff.vo.LmsStaffTrainPlanVO;
import com.patzn.lims.workflow.FlowInfo;
import com.patzn.lims.workflow.FlowProcess;
import com.patzn.lims.workflow.FlowType;
import com.patzn.lims.workflow.FlowVariables;
import com.patzn.lims.workflow.service.IFlowProcessService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 人员管理-人员培训计划 服务实现类
 * </p>
 *
 * @author patzn
 * @since 2017-11-03
 */
@Service
public class LmsStaffTrainPlanServiceImpl extends BaseServiceImpl<LmsStaffTrainPlanMapper, LmsStaffTrainPlan> implements ILmsStaffTrainPlanService {

    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private ILmsStaffTrainPlanRecordService lmsStaffTrainPlanRecordService;
//    @Autowired
//    private MqProperties mqProperties;
    @Autowired
    private IFlowProcessService flowProcessClient;
    @Autowired
    private ILmsPropertyService lmsPropertyService;
    @Autowired
    private ILmsBaseDictService lmsBaseDictService;
    @Autowired
    private ILmsStaffTrainPlanAttachmentService lmsStaffTrainPlanAttachmentService;

    @Override
    public Page<LmsStaffTrainPlanVO> page(Page<LmsStaffTrainPlanVO> page, LmsStaffTrainPlan lmsStaffTrainPlan) {
        return page.setRecords(baseMapper.selectPageVO(page, lmsStaffTrainPlan));
    }

    @Override
    public List<LmsStaffTrainPlan> list(LmsStaffTrainPlan lmsStaffTrainPlan) {
        return this.list(Wrappers.<LmsStaffTrainPlan>query(lmsStaffTrainPlan));
    }

    @Override
    public LmsStaffTrainPlanVO getPlanInfo(Long id) {
        LmsStaffTrainPlanVO vo;
        LmsStaffTrainPlan plan = baseMapper.selectById(id);
        vo = plan.convert(LmsStaffTrainPlanVO.class);
        vo.setPxlx(null != plan.getType() ? lmsBaseDictService.getById(plan.getType()).getName() : null);
        vo.setAssessment(null != plan.getAssessmentMethod() ? lmsBaseDictService.getById(plan.getAssessmentMethod()).getName() : null);
        vo.setTrainContent(StringUtils.isNotBlank(vo.getTrainContent()) ? vo.getTrainContent().replaceAll("<[.[^<]]*>", "") : null);
        return vo;
    }

    @Override
    public Boolean edit(LmsStaffTrainPlan lmsStaffTrainPlan) {
        PtAssert.fail(null == lmsStaffTrainPlan.getId(), "编辑id不能为空");
        LmsStaffTrainPlan staffTrainPlan = getById(lmsStaffTrainPlan.getId());
        String remark = lmsPropertyService.getObjectCompareDifferent(lmsStaffTrainPlan, staffTrainPlan, "人员培训计划信息对比", "信息修改：");
        if (StringUtils.isNotBlank(remark)) {
            LmsStaffTrainPlanRecord record = new LmsStaffTrainPlanRecord();
            record.setOrigin(StaffTrainPlanEnum.valueOf(staffTrainPlan.getStatus()).getDisplay());
            record.setTarget(StaffTrainPlanEnum.valueOf(staffTrainPlan.getStatus()).getDisplay());
            record.setType(2);
            record.setRemark(remark);
            record.setTrainPlanId(staffTrainPlan.getId());
            record.setOperator(LoginHelper.getAccount().getUserName());
            lmsStaffTrainPlanRecordService.save(record);
        }
        return super.updateById(lmsStaffTrainPlan);
    }

    @Override
    public Boolean add(LmsStaffTrainPlan lmsStaffTrainPlan) {
        lmsStaffTrainPlan.setUserId(LoginHelper.getAccount().getUserId());
        lmsStaffTrainPlan.setUserName(LoginHelper.getAccount().getUserName());
        lmsStaffTrainPlan.setStatus((Integer) StaffTrainPlanEnum.DRAFT.getValue());
        lmsStaffTrainPlan.setProgress((Integer) StaffTrainPlanEnum.DRAFT.getValue());
        lmsStaffTrainPlan.setTemp(1);
        return saveOrUpdate(lmsStaffTrainPlan);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<FlowProcess> commit(LmsStaffTrainPlan lmsStaffTrainPlan, Account account) {
        lmsStaffTrainPlan.setUserId(LoginHelper.getAccount().getUserId());
        lmsStaffTrainPlan.setUserName(LoginHelper.getAccount().getUserName());
        lmsStaffTrainPlan.setTemp(1);
        saveOrUpdate(lmsStaffTrainPlan);
        Long[] arr = new Long[]{lmsStaffTrainPlan.getId()};
        return submitCheckFlow(arr, account);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sendMsg() {
        List<LmsStaffTrainPlan> planList = baseMapper.selectListByDate();
        for (LmsStaffTrainPlan lmsStaffTrainPlan : planList) {
            if (null != lmsStaffTrainPlan.getStaffIds()) {
                sendMsg(lmsStaffTrainPlan);
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<FlowProcess> submitCheckFlow(Long[] ids, Account account) {
        if (ArrayUtils.isEmpty(ids)) {
            return null;
        }
        List<LmsStaffTrainPlan> staffTrainPlanCheckList = super.list(Wrappers.<LmsStaffTrainPlan>query().in("id", ids));
        List<FlowInfo> flowInfoList = new ArrayList<>();

        List<LmsStaffTrainPlanRecord> recordList = Lists.newArrayList();

        List<LmsStaffTrainPlan> updateStaffTrainPlanList = staffTrainPlanCheckList.
                stream().filter(trainPlan -> null != trainPlan).map(trainPlan -> {
            flowInfoList.add(
                    FlowInfo.convertFlowInfo(FlowType.STAFF_TRAIN_PLAN_CHECK,
                            account, trainPlan.getId(), StringHandleUtils.getObjectValue(trainPlan.getTrainPlan()).toString() + StringHandleUtils.getObjectValue(trainPlan.getName()).toString())
            );
            // 设置状态为待审批
            LmsStaffTrainPlan plan = new LmsStaffTrainPlan();
            plan.setId(trainPlan.getId());
            plan.setApplyId(account.getUserId());
            plan.setApplyName(account.getUserName());
            plan.setApplyDate(new Date());
            plan.setStatus((Integer) StaffTrainPlanEnum.EXAMINE.EXAMINE.getValue());
            plan.setProgress((Integer)StaffTrainPlanEnum.EXAMINE.getValue());

            LmsStaffTrainPlanRecord record = new LmsStaffTrainPlanRecord();
            record.setTrainPlanId(plan.getId());
            record.setOperator(account.getUserName());
            record.setLiable(account.getUserName());
            record.setRemark("人员培训计划提交审批");
            record.setType(0);
            record.setTarget(StaffTrainPlanEnum.EXAMINE.getDisplay());
            record.setOrigin(StaffTrainPlanEnum.DRAFT.getDisplay());
            recordList.add(record);
            return plan;
        }).collect(Collectors.toList());
        this.updateBatchById(updateStaffTrainPlanList);
        if (CollectionUtils.isNotEmpty(recordList)) {
            lmsStaffTrainPlanRecordService.saveBatch(recordList);
        }
        return flowProcessClient.saveTask(flowInfoList,account);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean approveFlow(String taskId, String status, String reason) {
        FlowVariables flowVariables = new FlowVariables(taskId);
        FlowInfo flowInfo;
        Map<String, Object> map = new HashMap<>(2);
        Account account = LoginHelper.getAccount();
        PtAssert.fail(StringUtils.isBlank(status), "status不能为空");
        PtAssert.fail(!(status.equalsIgnoreCase("pass") || status.equalsIgnoreCase("back")), "通过状态为'pass'，驳回状态为'back'");

        LmsStaffTrainPlan plan = new LmsStaffTrainPlan();
        plan.setApproverId(LoginHelper.getAccount().getUserId());
        plan.setApprover(LoginHelper.getAccount().getUserName());
        plan.setApprovDate(new Date());
        plan.setApproverOpinion(reason);

        LmsStaffTrainPlanRecord record = new LmsStaffTrainPlanRecord();
        record.setTrainPlanId(plan.getId());
        record.setOperator(account.getUserName());
        record.setLiable(account.getUserName());
        record.setOrigin(StaffTrainPlanEnum.EXAMINE.getDisplay());
        if ("pass".equals(status)) {
            //人员培训计划审批通过
            map.put("staffTrainCheckPass", true);
            plan.setStatus((Integer)StaffTrainPlanEnum.EXAMINE_PASS.getValue());
            plan.setProgress((Integer)StaffTrainPlanEnum.EXAMINE_PASS.getValue());
            record.setTarget(StaffTrainPlanEnum.EXAMINE_PASS.getDisplay());
            record.setRemark("人员培训计划审批通过" + reason);
            record.setType(0);

        } else if ("back".equals(status)) {
            //人员培训计划审批驳回
            map.put("staffTrainCheckPass", false);
            plan.setStatus((Integer)StaffTrainPlanEnum.DRAFT.getValue());
            plan.setProgress((Integer)StaffTrainPlanEnum.EXAMINE_BACK.getValue());
            record.setTarget(StaffTrainPlanEnum.EXAMINE_BACK.getDisplay());
            record.setRemark("人员培训计划审批驳回" + reason);
            record.setType(1);
        }
        map.put(FlowInfo.APPLY_ID, account.getUserId());
        flowVariables.setVariables(map);
        flowInfo = flowProcessClient.complete(flowVariables);
        PtAssert.fail(null == flowInfo, "流程审批错误");
        plan.setId(flowInfo.getId());
        record.setTrainPlanId(flowInfo.getId());
        lmsStaffTrainPlanRecordService.save(record);
        return updateById(plan);
    }

    @Override
    public LmsStaffTrainPlanVO temp() {
        LmsStaffTrainPlanVO trainPlanVO = new LmsStaffTrainPlanVO();
        List<LmsStaffTrainPlanAttachment> list = new ArrayList<>();
        LmsStaffTrainPlan trainPlan = this.getOne(Wrappers.<LmsStaffTrainPlan>query().eq("temp", 0));
        if (trainPlan == null) {
            LmsStaffTrainPlan plan = new LmsStaffTrainPlan();
            plan.setTemp(0);
            this.save(plan);
            trainPlanVO.setId(plan.getId());
            trainPlanVO.setAttachmentList(list);
            return trainPlanVO;
        } else {
            list = lmsStaffTrainPlanAttachmentService.list(Wrappers.<LmsStaffTrainPlanAttachment>query().eq("train_plan_id", trainPlan.getId()));
            trainPlanVO.setId(trainPlan.getId());
            trainPlanVO.setAttachmentList(list);
            return trainPlanVO;
        }
    }

    /**
     * 消息通知
     *
     * @param lmsStaffTrainPlan
     */
    private void sendMsg(LmsStaffTrainPlan lmsStaffTrainPlan) {
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        try {
//            StringBuilder content = new StringBuilder();
//            StringBuilder title = new StringBuilder();
//            title.append("培训通知:");
//            content.append("培训日期:").append(sdf.format(lmsStaffTrainPlan.getTrainDate()));
//            content.append("计划名称：").append(lmsStaffTrainPlan.getName());
//            content.append("负责人：").append(lmsStaffTrainPlan.getChargerName());
//            content.append("受训人员：").append(lmsStaffTrainPlan.getStaffNames());
//            MqMsg mqMsg = new MqMsg();
//            mqMsg.setUid(lmsStaffTrainPlan.getUserId());
//            mqMsg.setCompanyId(lmsStaffTrainPlan.getCompanyId());
//            mqMsg.setSender(lmsStaffTrainPlan.getUserName());
//            mqMsg.setTitle(title.toString());
//            mqMsg.setContent(content.toString());
//            mqMsg.setType(1);
//            mqMsg.setSender("系统发送");
//            mqMsg.setReceiverIds(lmsStaffTrainPlan.staffIdList());
//            amqpTemplate.convertAndSend(mqProperties.getTopic().getPushMsg(), mqMsg);
//        } catch (AmqpException e) {
//            logger.error("培训计划发送消息失败", lmsStaffTrainPlan.getName(), e);
//        }
    }
}
