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

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.google.common.collect.Lists;
import com.patzn.cloud.commons.api.RestAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.oss.OssClient;
import com.patzn.lims.res.service.ILmsPropertyService;
import com.patzn.lims.frame.dto.LmsFrameComplaintRegisterDTO;
import com.patzn.lims.frame.entity.*;
import com.patzn.lims.frame.enums.ComplaintRegisterEnum;
import com.patzn.lims.frame.enums.FrameFileTypeEnum;
import com.patzn.lims.frame.enums.LmsInnerStatusEnum;
import com.patzn.lims.frame.enums.ManageCheckEnum;
import com.patzn.lims.frame.mapper.LmsFrameComplaintRegisterMapper;
import com.patzn.lims.frame.service.*;
import com.patzn.lims.frame.vo.LmsFrameComplaintRegisterVO;
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.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 投/申诉登记 服务实现类
 * </p>
 *
 * @author patzn123
 * @since 2018-01-09
 */
@Service
public class LmsFrameComplaintRegisterServiceImpl extends BaseServiceImpl<LmsFrameComplaintRegisterMapper, LmsFrameComplaintRegister> implements ILmsFrameComplaintRegisterService {

    @Autowired
    private ILmsFrameFileService lmsFrameFileService;
    @Autowired
    private ILmsFrameLogService lmsFrameLogService;
    @Autowired
    private ILmsFrameComplaintManageService lmsFrameComplaintManageService;
    @Autowired
    private ILmsPropertyService lmsPropertyService;
    @Autowired
    private ILmsFrameComplaintRegisterRecordService lmsFrameComplaintRegisterRecordService;
    @Autowired
    private OssClient ossClient;
    @Autowired
     private IFlowProcessService flowProcessClient;
    @Override
    public Page<LmsFrameComplaintRegister> page(Page<LmsFrameComplaintRegister> page, LmsFrameComplaintRegisterDTO lmsFrameComplaintRegisterDTO) {
        lmsFrameComplaintRegisterDTO.setTempStatus(1);
         QueryWrapper wrapper = Wrappers.<LmsFrameComplaintRegister>query(lmsFrameComplaintRegisterDTO);
        wrapper.like("complaint_unit", lmsFrameComplaintRegisterDTO.getComplaintUnit());
        wrapper.like("complaint_name", lmsFrameComplaintRegisterDTO.getComplaintName());
        if (null != lmsFrameComplaintRegisterDTO.getQueryStartTime()) {
            wrapper.ge("check_time", lmsFrameComplaintRegisterDTO.getQueryStartTime());
            lmsFrameComplaintRegisterDTO.setQueryStartTime(null);
        }
        if (null != lmsFrameComplaintRegisterDTO.getQueryEndTime()) {
            wrapper.le("check_time", lmsFrameComplaintRegisterDTO.getQueryEndTime());
            lmsFrameComplaintRegisterDTO.setQueryEndTime(null);
        }

        lmsFrameComplaintRegisterDTO.setComplaintUnit(null);
        lmsFrameComplaintRegisterDTO.setComplaintName(null);
        wrapper.orderBy(true,true,"receiver_time");
        return page(page, wrapper);
    }


    @Override
    public List<LmsFrameComplaintRegister> list(LmsFrameComplaintRegister lmsFrameComplaintRegister) {
        lmsFrameComplaintRegister.setTempStatus(1);
        return list(Wrappers.<LmsFrameComplaintRegister>query(lmsFrameComplaintRegister));
    }

    @Override
    public LmsFrameComplaintRegisterVO getVOById(Long id) {
        LmsFrameComplaintRegisterVO vo = new LmsFrameComplaintRegisterVO();
        LmsFrameComplaintRegister entity = getById(id);
        if (null != entity) {
            BeanUtils.copyProperties(entity, vo);
            //获取附件
            LmsFrameFile lmsFrameFile = new LmsFrameFile();
            lmsFrameFile.setRelId(entity.getId());
            List<LmsFrameFile> list = lmsFrameFileService.list(lmsFrameFile);
            list.forEach(e->{
                e.setFilePath(ossClient.getUrl(e.getFilePath()).toString());
            });
            vo.setLmsFrameFileList(list);
        }

        return vo;
    }

    @Override
    public LmsFrameComplaintRegisterVO getTempVO() {
        LmsFrameComplaintRegisterVO vo = new LmsFrameComplaintRegisterVO();
        LmsFrameComplaintRegister entity = new LmsFrameComplaintRegister();
        entity.setUserId(LoginHelper.getAccount().getUserId());
        entity.setTempStatus(0);
        LmsFrameComplaintRegister lmsFrameComplaintRegister = baseMapper.selectOne(Wrappers.query(entity));
        if (null != lmsFrameComplaintRegister) {
            BeanUtils.copyProperties(lmsFrameComplaintRegister, vo);
            //获取附件
            LmsFrameFile lmsFrameFile = new LmsFrameFile();
            lmsFrameFile.setRelId(lmsFrameComplaintRegister.getId());
            List<LmsFrameFile> list = lmsFrameFileService.list(lmsFrameFile);
            list.forEach(e -> {
                e.setFilePath(ossClient.getUrl(e.getFilePath()).toString());
            });
            vo.setLmsFrameFileList(list);
        } else {
            LmsFrameComplaintRegister register = new LmsFrameComplaintRegister();
            register.setTempStatus(0);
            register.setStatus(ComplaintRegisterEnum.DRAFT);
            register.setUserId(LoginHelper.getAccount().getUserId());
            save(register);
            BeanUtils.copyProperties(register, vo);
        }

        return vo;
    }

    @Override
    @Transactional
    public Boolean edit(LmsFrameComplaintRegister lmsFrameComplaintRegister) {
        RestAssert.fail(null == lmsFrameComplaintRegister.getId(), "编辑请传递id");
        //提交数据操作日志保存
        LmsFrameComplaintRegister entity = getById(lmsFrameComplaintRegister.getId());
        if ("EXAMINE".equals(entity.getStatus().getDisplay())) {
            LmsFrameLog log = new LmsFrameLog();
            log.setUserId(LoginHelper.getAccount().getUserId());
            log.setUserName(LoginHelper.getAccount().getUserName());
            log.setTableName("lms_frame_complaint_register");
            log.setOrginParams(entity.toString());
            log.setParams(lmsFrameComplaintRegister.toString());
            log.setCreateTime(new Date());
            lmsFrameLogService.save(log);
        }
        String remark = lmsPropertyService.getObjectCompareDifferent(lmsFrameComplaintRegister, entity, "投申诉登记信息对比", "投申诉登记信息修改：");
        if (StringUtils.isNotBlank(remark)) {
            LmsFrameComplaintRegisterRecord registerRecord = new LmsFrameComplaintRegisterRecord();
            registerRecord.setComplaintId(entity.getId());
            registerRecord.setLiable(LoginHelper.getAccount().getUserName());
            registerRecord.setOperator(LoginHelper.getAccount().getUserName());
            registerRecord.setType(2);
            registerRecord.setRemark(remark);
            registerRecord.setOrigin("草稿");
            registerRecord.setTarget("草稿");
            lmsFrameComplaintRegisterRecordService.save(registerRecord);
        }

        return updateById(lmsFrameComplaintRegister);
    }

    @Override
    public boolean add(LmsFrameComplaintRegister lmsFrameComplaintRegister) {
        LmsFrameComplaintRegister entity = new LmsFrameComplaintRegister();
        entity.setUserId(LoginHelper.getAccount().getUserId());
        entity.setTempStatus(0);
        LmsFrameComplaintRegister temp = baseMapper.selectOne(Wrappers.query(entity));
        if (null != temp) {
            lmsFrameComplaintRegister.setId(temp.getId());
            lmsFrameComplaintRegister.setTempStatus(1);
            return updateById(lmsFrameComplaintRegister);
        }
        lmsFrameComplaintRegister.setUserId(LoginHelper.getAccount().getUserId());
        lmsFrameComplaintRegister.setTempStatus(1);
        return save(lmsFrameComplaintRegister);
    }

    @Override
    public Boolean delete(Long[] ids) {
        if (lmsFrameComplaintManageService.existByIds(ids)) {
            RestAssert.fail("请先删除该条数据下所有的评审内容数据！");
        }

        lmsFrameFileService.deleteBatch(ids);
        return super.remove(Wrappers.<LmsFrameComplaintRegister>query().in("id", ids));
    }

    @Override
    public LmsFrameFile uploadFile(MultipartFile file, LmsFrameComplaintRegister lmsFrameComplaintRegister) {
        Long companyId = LoginHelper.getAccount().getCompanyId();
        String folderPath = "frame/InnerCheckManage/" + companyId + "/";
        return lmsFrameFileService.saveAndUpload(file, "lims", folderPath, lmsFrameComplaintRegister.getId(), FrameFileTypeEnum.COMPLAINT_REGISTER.getValue());
    }

    @Override
    public void downloadFile(Long id, HttpServletResponse response) {
        LmsFrameFile lmsFrameFile = lmsFrameFileService.getById(id);
        String fileUrl = lmsFrameFile.getFilePath();
        String orgFileName = lmsFrameFile.getOrginName().replaceAll("\\s*", "");
        lmsFrameFileService.downloadFile(response, "lims", fileUrl, orgFileName);
    }

    @Override
    public Boolean deleteFile(Long id) {
        Long[] ids = new Long[]{id};
        return lmsFrameFileService.deleteBatch(ids);
    }

    @Override
    @Transactional
    public Boolean submit(List<Long> ids) {
        List<LmsFrameComplaintRegister> entityList = Lists.newArrayList();
        List<LmsFrameComplaintManage> manageList = Lists.newArrayList();
        for (Long id : ids) {
            LmsFrameComplaintRegister entity = new LmsFrameComplaintRegister();
            entity.setId(id);
            entity.setStatus(ComplaintRegisterEnum.EXAMINE);
            entityList.add(entity);

            LmsFrameComplaintManage manage = new LmsFrameComplaintManage();
            manage.setComplaintId(id);
            manage.setStatus(0);
            manageList.add(manage);
        }

        lmsFrameComplaintManageService.saveBatch(manageList);
        return updateBatchById(entityList);
    }


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

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

        List<LmsFrameComplaintRegister> updatecomplaintRegisterList = complaintRegisterList.
                stream().filter(complaintRegister -> null != complaintRegister).map(complaintRegister -> {
            flowInfoList.add(
                    FlowInfo.convertFlowInfo(FlowType.COMPLAINT_REGISTER,
                            account, complaintRegister.getId(), complaintRegister.getRemark())
            );
            // 设置状态为待审批
            LmsFrameComplaintRegister register = new LmsFrameComplaintRegister();
            register.setId(complaintRegister.getId());
            register.setStatus(ComplaintRegisterEnum.EXAMINE);

            LmsFrameComplaintRegisterRecord record = new LmsFrameComplaintRegisterRecord();
            record.setComplaintId(complaintRegister.getId());
            record.setOperator(account.getUserName());
            record.setLiable(account.getUserName());
            record.setRemark("投/申诉登记提交审批");
            record.setType(0);
            record.setTarget(ComplaintRegisterEnum.EXAMINE.getDisplay());
            record.setOrigin(ComplaintRegisterEnum.DRAFT.getDisplay());
            recordList.add(record);
            return register;

        }).collect(Collectors.toList());
        updateBatchById(updatecomplaintRegisterList);
        if (CollectionUtils.isNotEmpty(recordList)) {
            lmsFrameComplaintRegisterRecordService.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();
        RestAssert.fail(StringUtils.isBlank(status), "status不能为空");
        RestAssert.fail(!(status.equalsIgnoreCase("pass") || status.equalsIgnoreCase("back")), "通过状态为'pass'，驳回状态为'back'");
        //获取管理计划id
        LmsFrameComplaintRegister complaintRegister = new LmsFrameComplaintRegister();
        complaintRegister.setDealId(LoginHelper.getAccount().getUserId());
        complaintRegister.setDealName(LoginHelper.getAccount().getUserName());
        complaintRegister.setDealTime(new Date());
        complaintRegister.setDealAdvice(reason);

        LmsFrameComplaintRegisterRecord record = new LmsFrameComplaintRegisterRecord();
        record.setOperator(account.getUserName());
        record.setLiable(account.getUserName());
        record.setOrigin(LmsInnerStatusEnum.EXAMINE.getDisplay());
        if ("pass".equals(status)) {
            //管理评审审批通过
            map.put("complaintRegisterPass", true);
            complaintRegister.setStatus(ComplaintRegisterEnum.EXAMINE_PASS);
            record.setTarget(ComplaintRegisterEnum.EXAMINE_PASS.getDisplay());
            record.setRemark("投/申诉登记审批通过！");
            record.setType(0);

        } else if ("back".equals(status)) {
            //管理评审驳回
            map.put("complaintRegisterPass", false);
            complaintRegister.setStatus(ComplaintRegisterEnum.DRAFT);
            record.setTarget(ManageCheckEnum.EXAMINE_BACK.getDisplay());
            record.setRemark("投/申诉登记审批驳回！");
            record.setType(1);
        }
        map.put(FlowInfo.APPLY_ID, account.getUserId());
        flowVariables.setVariables(map);
        flowInfo = flowProcessClient.complete(flowVariables);
        RestAssert.fail(null == flowInfo, "流程审批错误");
        complaintRegister.setId(flowInfo.getId());
        updateById(complaintRegister);
        record.setComplaintId(flowInfo.getId());
        lmsFrameComplaintRegisterRecordService.save(record);
        return true;
    }
}
