package com.patzn.lims.equip.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.common.collect.Lists;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.equip.entity.*;
import com.patzn.lims.equip.enums.EquipDataStatusEnum;
import com.patzn.lims.equip.enums.EquipLogDataTypeEnum;
import com.patzn.lims.equip.enums.EquipLogStatusEnum;
import com.patzn.lims.equip.mapper.LmsEquipMaintainMapper;
import com.patzn.lims.equip.service.*;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.equip.vo.LmsEquipMaintainDetailVO;
import com.patzn.lims.equip.vo.LmsEquipMaintainVO;
import com.patzn.lims.sys.dto.MqMsgDTO;
import com.patzn.lims.workflow.FlowInfo;
import com.patzn.lims.workflow.FlowType;
import com.patzn.lims.workflow.FlowVariables;
import com.patzn.lims.workflow.service.IFlowProcessService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 仪器保养计划信息表 服务实现类
 * </p>
 *
 * @author wwd
 * @since 2020-03-28
 */
@Service
public class LmsEquipMaintainServiceImpl extends BaseServiceImpl<LmsEquipMaintainMapper, LmsEquipMaintain> implements ILmsEquipMaintainService {

    @Autowired
    private ILmsEquipMaintainDetailService lmsEquipMaintainDetailService;

    @Autowired
    private ILmsEquipMaintainManageService lmsEquipMaintainManageService;


    @Autowired
    private ILmsEquipElectronicDocumentsService lmsEquipElectronicDocumentsService;

    @Autowired
    private ILmsEquipLogService lmsEquipLogService;


    @Autowired
    private ILmsEquipFileService lmsEquipFileService;
    @Autowired
    private ILmsEquipInfoService lmsEquipInfoService;
    @Autowired
    private ILmsEquipMaintainHistoryService lmsEquipMaintainHistoryService;
    @Autowired
    private IFlowProcessService flowProcessService;



    @Override
    public Page<LmsEquipMaintain> page(Page<LmsEquipMaintain> page, LmsEquipMaintain lmsEquipMaintain) {
        QueryWrapper<LmsEquipMaintain> wrapper = Wrappers.<LmsEquipMaintain>query(lmsEquipMaintain);
        return this.page(page, wrapper);
    }


    @Override
    public Page<LmsEquipMaintainVO> pageMaintain(Page<LmsEquipMaintainVO> page, LmsEquipMaintainVO vo) {
        vo.setTempStatus(EquipDataStatusEnum.REAL.getValue());
        vo.setCompanyId(LoginHelper.getAccount().getCompanyId());
        return page.setRecords(baseMapper.selectMaintainList(page, vo));
    }


    @Override
    public LmsEquipMaintainVO getTempVO() {
        LmsEquipMaintainVO lmsEquipMaintainVO = new LmsEquipMaintainVO();
        lmsEquipMaintainVO.setLmsEquipMaintainDetailVOList(Lists.newArrayList());
        LmsEquipMaintainVO maintainVO = new LmsEquipMaintainVO();
        maintainVO.setUserId(LoginHelper.getAccount().getUserId());
        maintainVO.setTempStatus(EquipDataStatusEnum.TEMP.getValue());
        LmsEquipMaintain lmsEquipMaintain = super.getOne(Wrappers.<LmsEquipMaintain>query().eq("temp_status", 0).eq("user_id", LoginHelper.getAccount().getUserId()).last("LIMIT 1"));
        if (null != lmsEquipMaintain) {
            lmsEquipMaintainVO = lmsEquipMaintain.convert(LmsEquipMaintainVO.class);
            //获取详情
            LmsEquipMaintainDetailVO vo = new LmsEquipMaintainDetailVO();
            vo.setMaintainId(lmsEquipMaintain.getId());
            List<LmsEquipMaintainDetailVO> lmsEquipMaintainDetailVOList = lmsEquipMaintainDetailService.listVO(vo);
            lmsEquipMaintainVO.setLmsEquipMaintainDetailVOList(lmsEquipMaintainDetailVOList);
            //获取附件
            LmsEquipFile lmsEquipFile = new LmsEquipFile();
            lmsEquipFile.setRelId(lmsEquipMaintain.getId());
            List<LmsEquipFile> lmsEquipFileList = lmsEquipFileService.list(lmsEquipFile);
            lmsEquipMaintainVO.setLmsEquipFiles(lmsEquipFileList);
        } else {
            LmsEquipMaintain maintain = new LmsEquipMaintain();
            maintain.setTempStatus(EquipDataStatusEnum.TEMP.getValue());
            maintain.setUserId(LoginHelper.getAccount().getUserId());
            maintain.setId(IdWorker.getId());
            save(maintain);
            lmsEquipMaintainVO = maintain.convert(LmsEquipMaintainVO.class);
            //获取附件
            LmsEquipFile lmsEquipFile = new LmsEquipFile();
            lmsEquipFile.setRelId(lmsEquipMaintainVO.getId());
            List<LmsEquipFile> lmsEquipFileList = lmsEquipFileService.list(lmsEquipFile);
            lmsEquipMaintainVO.setLmsEquipFiles(lmsEquipFileList);
        }

        return lmsEquipMaintainVO;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateAdd(Long[] ids, LmsEquipMaintainDetail detail) {
        PtAssert.fail(null == detail.getMaintainId(), "id不能为空");
        PtAssert.fail(StringUtils.isBlank(detail.getMaintainerNames()), "负责人不能为空");
        PtAssert.fail(null == detail.getMaintainStartTimePlan(), "计划保养开始时间不能为空");
        PtAssert.fail(null == detail.getMaintainEndTimePlan(), "计划保养结束时间不能为空");
        PtAssert.fail(ArrayUtils.isEmpty(ids), "请选择仪器");
        LmsEquipMaintain lm = super.getById(detail.getMaintainId());
        PtAssert.fail(null == lm, "当前保养单已被删除");
        for (int i = 0; i < ids.length; i++) {
            detail.setEquipId(ids[i]);
            detail.setId(IdWorker.getId());
            lmsEquipMaintainDetailService.save(detail);
        }

        List<LmsEquipInfo> lmsEquipInfo = lmsEquipInfoService.list(Wrappers.<LmsEquipInfo>query().in("id",ids));
        String equipName = lmsEquipInfo.stream().map(e ->(null==e.getLabNum()?"":e.getLabNum())+ e.getName()).collect(Collectors.joining("、"));
        LmsEquipMaintainHistory lmsEquipMaintainHistory = new LmsEquipMaintainHistory();
        lmsEquipMaintainHistory.setMaintainId(detail.getMaintainId());
        lmsEquipMaintainHistory.setName(lm.getName());
        lmsEquipMaintainHistory.setNum(lm.getNum());
        lmsEquipMaintainHistory.setRemark(detail.getRemark());
        lmsEquipMaintainHistory.setType(0);
        lmsEquipMaintainHistory.setDetails("编辑时新增:" + equipName);
        lmsEquipMaintainHistory.setOperation("新增");
        lmsEquipMaintainHistory.setUname(LoginHelper.getAccount().getUserName());
        return lmsEquipMaintainHistoryService.save(lmsEquipMaintainHistory);
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public   boolean saveBatchEquipId(Long[] ids,LmsEquipMaintainDetailVO lmsEquipMaintainDetail){
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择一条记录");
        PtAssert.fail(StringUtils.isBlank(lmsEquipMaintainDetail.getMaintainContent())||StringUtils.isBlank(lmsEquipMaintainDetail.getMaintainerNames()
                ) ||null==lmsEquipMaintainDetail.getMaintainStartTimePlan()||null==lmsEquipMaintainDetail.getMaintainEndTimePlan()||null==lmsEquipMaintainDetail.getMaintainId(),"请填写必填项"
        );
        List<LmsEquipInfo> lmsEquipInfo = lmsEquipInfoService.list(Wrappers.<LmsEquipInfo>query().in("id",ids));
//        String name= lmsEquipInfo.stream().map(e->e.getName()).collect(Collectors.joining(","));
        LmsEquipMaintainDetail detail =lmsEquipMaintainDetail.convert(LmsEquipMaintainDetail.class);
        for(int i=0;i<ids.length;i++){
            detail.setEquipId(ids[i]);
            detail.setId(IdWorker.getId());
            lmsEquipMaintainDetailService.save(detail.setEquipId(ids[i]));
        }
        return  true;
    }

    public boolean lmsEquipMainNum(String num) {
        PtAssert.fail(StringUtils.isBlank(num), "请输入编号");
        return 0 == super.count(Wrappers.<LmsEquipMaintain>query().eq("num", num));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean add(LmsEquipMaintain lmsEquipMaintain) {
        PtAssert.fail(null == lmsEquipMaintain.getId(), "id不能为空");
        PtAssert.fail(null == lmsEquipMaintain.getNum(), "请输入编号");
        PtAssert.fail(null == lmsEquipMaintain.getName(), "计划名称不能为空");
        PtAssert.fail(!lmsEquipMainNum(lmsEquipMaintain.getNum()), "编号错误,请重新填写");

        lmsEquipMaintain.setRegisterId(LoginHelper.getAccount().getUserId());
        lmsEquipMaintain.setRegisterName(LoginHelper.getAccount().getUserName());
        lmsEquipMaintain.setRegisterTime(new Date());
        //提交
        List<LmsEquipMaintainDetail> lmsEquipMaintainDetail =lmsEquipMaintainDetailService.list(Wrappers.<LmsEquipMaintainDetail>query().eq("maintain_id",lmsEquipMaintain.getId()));
        StringBuilder builder = new StringBuilder();
        lmsEquipMaintainDetail.forEach(dto ->{
            PtAssert.fail(null == dto.getMaintainStartTimePlan(), "计划保养开始时间不能为空");
            PtAssert.fail(null == dto.getMaintainEndTimePlan(), "计划保养结束时间不能为空");
            PtAssert.fail(null == dto.getEquipId(), "提交的保养单中含有不存在找不到该仪器");
            LmsEquipInfo lmsEquipInfo = lmsEquipInfoService.getById(dto.getEquipId());
            PtAssert.fail(null == lmsEquipInfo, "需要查询的仪器不存在");
            builder.append(null==lmsEquipInfo.getLabNum()?"":lmsEquipInfo.getLabNum());
            builder.append(lmsEquipInfo.getName()+",");
        });

        LmsEquipMaintain maintain = new LmsEquipMaintain();
        maintain.setUserId(LoginHelper.getAccount().getUserId());
        maintain.setTempStatus(EquipDataStatusEnum.TEMP.getValue());
        LmsEquipMaintain temp = selectOne(maintain);
        if (null != temp) {
            lmsEquipMaintain.setId(temp.getId());
            lmsEquipMaintain.setTempStatus(1);
            updateById(lmsEquipMaintain);
        } else {
            lmsEquipMaintain.setUserId(LoginHelper.getAccount().getUserId());
            lmsEquipMaintain.setTempStatus(1);
            save(lmsEquipMaintain);
        }
        if (Integer.valueOf(1).equals(lmsEquipMaintain.getStatus())
                || Integer.valueOf(3).equals(lmsEquipMaintain.getStatus())) {
            submit(lmsEquipMaintain.getId());
        }
        LmsEquipMaintainHistory lmsEquipMaintainHistory = new LmsEquipMaintainHistory();
        lmsEquipMaintainHistory.setMaintainId(lmsEquipMaintain.getId());
        lmsEquipMaintainHistory.setType(0);
        lmsEquipMaintainHistory.setUname(LoginHelper.getAccount().getUserName());
        lmsEquipMaintainHistory.setRemark(lmsEquipMaintain.getRemark());
        lmsEquipMaintainHistory.setOperation("创建");
        lmsEquipMaintainHistory.setName(lmsEquipMaintain.getName());
        lmsEquipMaintainHistory.setDetails("创建的保养单详情为:"+builder);
        lmsEquipMaintainHistory.setNum(lmsEquipMaintain.getNum());
        lmsEquipMaintainHistoryService.save(lmsEquipMaintainHistory);
        return updateById(lmsEquipMaintain);

    }


    @Override
    public boolean submit(Long id) {
        try {
            LmsEquipMaintain lmsEquipMaintain = baseMapper.selectById(id);
            ArrayList<FlowInfo> flowInfoList = new ArrayList<>();
            Account account = LoginHelper.getAccount();
            flowInfoList.add(FlowInfo.convertFlowInfo(FlowType.EQUIP_MAINTAIN,
                    account, lmsEquipMaintain.getId(), lmsEquipMaintain.getApplyReason()));
            flowProcessService.saveTask(flowInfoList,account);
            //更新采购单状态
            lmsEquipMaintain.setStatus(1);
            lmsEquipMaintain.setApplyId(LoginHelper.getAccount().getUserId());
            lmsEquipMaintain.setApplyName(LoginHelper.getAccount().getUserName());
            lmsEquipMaintain.setApplyTime(new Date());
            baseMapper.updateById(lmsEquipMaintain);
        } catch (Exception ex) {
            PtAssert.fail("流程提交失败，原因：" + ex.getMessage());
        }

        return true;
    }


    @Override
    public LmsEquipMaintain selectOne(LmsEquipMaintain lmsEquipMaintain) {
        return super.getOne(Wrappers.<LmsEquipMaintain>query().eq("User_id", lmsEquipMaintain.getUserId()).eq("Temp_status", 0).last("LIMIT 1"));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean approve(String taskId, String status, String reason) {
        FlowVariables flowVariables = new FlowVariables(taskId);
        FlowInfo flowInfo = null;
        Map<String, Object> map = new HashMap<>(2);
        if ("success".equals(status))  {
            // 确认审批完成
            map.put(FlowInfo.APPLY_ID, LoginHelper.getAccount().getUserId());
            map.put("technicalDirectorAduitPass", true);
            flowVariables.setVariables(map);
            flowInfo = flowProcessService.complete(flowVariables);
            if (null == flowInfo) {
                PtAssert.fail("确认审批失败！");
                return false;
            } else {
                LmsEquipMaintain lmsEquipMaintain = getById(flowInfo.getId());
                List<LmsEquipMaintainDetail> detailList = lmsEquipMaintainDetailService.list(Wrappers.<LmsEquipMaintainDetail>query().eq("maintain_id", flowInfo.getId()));
                List<LmsEquipFile> fileList = lmsEquipFileService.list(Wrappers.<LmsEquipFile>query().eq("rel_id", flowInfo.getId()));

                for (LmsEquipMaintainDetail detail : detailList) {
                    //保存保养管理信息
                    LmsEquipMaintainManage lmsEquipMaintainManage = new LmsEquipMaintainManage();
                    lmsEquipMaintainManage.setDetailId(detail.getId());
                    //待保养
                    lmsEquipMaintainManage.setStatus(0);
                    lmsEquipMaintainManageService.save(lmsEquipMaintainManage);

                    //保存日志信息
                    lmsEquipLogService.saveLogs(detail.getMaintainStartTimePlan(), detail.getMaintainEndTimePlan(), detail.getEquipId(), detail.getId(), EquipLogStatusEnum.ORDER_MAINTAIN.getValue(), EquipLogDataTypeEnum.PLAN.getValue());

                    //保存电子文档信息
                    List<LmsEquipElectronicDocuments> list = Lists.newArrayList();
                    for (LmsEquipFile file : fileList) {
                        LmsEquipElectronicDocuments doc = new LmsEquipElectronicDocuments();
                        doc.setEquipId(detail.getEquipId());
                        doc.setType(0);
                        doc.setDocumentName(file.getOrginName());
                        doc.setDocumentPath("equip/flow/maintain/" + LoginHelper.getAccount().getCompanyId() + "/" + file.getFilePath());
                        doc.setPlanName(lmsEquipMaintain.getName());
                        doc.setApplyReason(lmsEquipMaintain.getApplyReason());
                        doc.setApplyId(lmsEquipMaintain.getApplyId());
                        doc.setApplyName(lmsEquipMaintain.getApplyName());
                        doc.setCreateTime(lmsEquipMaintain.getApplyTime());
                        doc.setRemark(lmsEquipMaintain.getRemark());
                        list.add(doc);
                    }
                    if (list.size() > 0) {
                        lmsEquipElectronicDocumentsService.saveBatch(list);
                    }

                    //发送消息提醒
                    if (StringUtils.isNotBlank(detail.getMaintainerIds())) {
                        sendMsg(detail);
                    }
                }
            }
        } else if ("false".equals(status)) {
            flowInfo = flowProcessService.complete(flowVariables);
        } else if ("2".equals(status)) {
            //技术主管审批通过
            map.put(FlowInfo.APPLY_ID, LoginHelper.getAccount().getUserId());
            map.put("technicalDirectorAduitPass", true);
            flowVariables.setVariables(map);
            flowInfo = flowProcessService.complete(flowVariables);
        } else if ("3".equals(status)) {
            //技术主管审批驳回
            map.put(FlowInfo.APPLY_ID, LoginHelper.getAccount().getUserId());
            map.put("technicalDirectorAduitPass", false);
            flowVariables.setVariables(map);
            flowInfo = flowProcessService.complete(flowVariables);
        } else if ("5".equals(status)) {
            //技术主管审批终止
            map.put(FlowInfo.APPLY_ID, LoginHelper.getAccount().getUserId());
            map.put("technicalDirectorAduitPass", false);
            flowVariables.setVariables(map);
            flowInfo = flowProcessService.complete(flowVariables);
        } else {
            flowInfo = null;
        }


        if (null != flowInfo) {
            Integer count = updateMaintain(flowInfo, status, reason);
            if (null == count) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }


    private Integer updateMaintain(FlowInfo flowInfo, String status, String reason) {
        LmsEquipMaintain lmsEquipMaintain = new LmsEquipMaintain();
        lmsEquipMaintain.setId(flowInfo.getId());
        if ("success".equals(status)) {
            lmsEquipMaintain.setStatus(4);
        } else if ("false".equals(status)){
            lmsEquipMaintain.setStatus(3);
        } else if ("2".equals(status)) {
            //技术主管审批通过
            getLmsEquipMaintain(lmsEquipMaintain, reason, 2);
        } else if ("3".equals(status)) {
            //技术主管审批驳回
            getLmsEquipMaintain(lmsEquipMaintain, reason, 3);
        } else if ("5".equals(status)) {
            //技术主管审批终止
            getLmsEquipMaintain(lmsEquipMaintain, reason, 5);
        } else {
            return null;
        }

        return baseMapper.updateById(lmsEquipMaintain);
    }


    private void getLmsEquipMaintain(LmsEquipMaintain lmsEquipMaintain, String reason, Integer status) {
        lmsEquipMaintain.setStatus(status);
        lmsEquipMaintain.setFirstStepId(LoginHelper.getAccount().getUserId());
        lmsEquipMaintain.setFirstStepTime(new Date());
        lmsEquipMaintain.setFirstStepAdvice(reason);
        lmsEquipMaintain.setFirstStepName(LoginHelper.getAccount().getUserName());
    }



    public void sendMsg(LmsEquipMaintainDetail lmsEquipMaintainDetail) {
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try {
//            Long maintainId = lmsEquipMaintainDetail.getMaintainId();
//            LmsEquipMaintain maintain = lmsEquipMaintainService.getById(maintainId);
//            StringBuilder content = new StringBuilder();
//            StringBuilder title = new StringBuilder();
//            title.append("仪器保养通知:").append(maintain.getName());
//            content.append("保养项目：").append(lmsEquipMaintainDetail.getProjectName());
//            content.append("保养内容：").append(lmsEquipMaintainDetail.getMaintainContent());
//            content.append("计划保养开始时间:").append(sdf.format(lmsEquipMaintainDetail.getMaintainStartTimePlan()));
//            content.append("计划保养结束时间:").append(sdf.format(lmsEquipMaintainDetail.getMaintainEndTimePlan()));
//            MqMsgDTO mqMsg = new MqMsgDTO();
//            mqMsg.setUid(LoginHelper.getAccount().getUserId());
//            mqMsg.setCompanyId(LoginHelper.getAccount().getCompanyId());
//            mqMsg.setSender(LoginHelper.getAccount().getUserName());
//            mqMsg.setTitle(title.toString());
//            mqMsg.setContent(content.toString());
//            mqMsg.setType(1);
//            mqMsg.setBeginTime(lmsEquipMaintainDetail.getMaintainStartTimePlan());
//            mqMsg.setEndTime(lmsEquipMaintainDetail.getMaintainEndTimePlan());
//            mqMsg.setSender("系统发送");
//            if (StringUtils.isNotBlank(lmsEquipMaintainDetail.getMaintainerIds())) {
//                List<Long> idList = Lists.newArrayList();
//                String[] maintainerArr = lmsEquipMaintainDetail.getMaintainerIds().split(",");
//                for (String maintainerStr : maintainerArr) {
//                    Long maintainerId = Long.valueOf(maintainerStr);
//                    idList.add(maintainerId);
//                }
//                mqMsg.setReceiverIds(idList);
//            }
//            amqpTemplate.convertAndSend(mqProperties.getTopic().getPushMsg(), mqMsg);
//        } catch (AmqpException e) {
//            logger.error("仪器保养发送消息失败", lmsEquipMaintainDetail.getProjectName(), e);
//        }
    }


    @Override
    public LmsEquipMaintainVO getVOById(Long id) {
        LmsEquipMaintainVO lmsEquipMaintainVO = new LmsEquipMaintainVO();
        LmsEquipMaintain lmsEquipMaintain = getById(id);
        if (null != lmsEquipMaintain) {
            //获取详情
            LmsEquipMaintainDetailVO lmsEquipMaintainDetailVO = new LmsEquipMaintainDetailVO();
            lmsEquipMaintainDetailVO.setMaintainId(lmsEquipMaintain.getId());
            List<LmsEquipMaintainDetailVO> detailVOList = lmsEquipMaintainDetailService.listVO(lmsEquipMaintainDetailVO);
            BeanUtils.copyProperties(lmsEquipMaintain, lmsEquipMaintainVO);
            lmsEquipMaintainVO.setLmsEquipMaintainDetailVOList(detailVOList);

            //获取附件
            LmsEquipFile lmsEquipFile = new LmsEquipFile();
            lmsEquipFile.setRelId(lmsEquipMaintain.getId());
            List<LmsEquipFile> lmsEquipFileList = lmsEquipFileService.list(lmsEquipFile);
            lmsEquipMaintainVO.setLmsEquipFiles(lmsEquipFileList);
        }

        return lmsEquipMaintainVO;
    }

}
