/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.oaall.service;

import com.google.common.collect.Maps;
import com.jeeplus.common.oss.OSSClientUtil;
import com.jeeplus.common.persistence.Page;
import com.jeeplus.common.service.CrudService;
import com.jeeplus.common.utils.Collections3;
import com.jeeplus.common.utils.MenuStatusEnum;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.act.entity.Act;
import com.jeeplus.modules.act.service.ActTaskService;
import com.jeeplus.modules.act.utils.ActUtils;
import com.jeeplus.modules.oaall.dao.OaAllDao;
import com.jeeplus.modules.oaall.entity.OaAll;
import com.jeeplus.modules.sys.dao.UserDao;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.entity.Workattachment;
import com.jeeplus.modules.sys.service.WorkattachmentService;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workapprovalcopy.entity.ApprovalCopy;
import com.jeeplus.modules.workapprovalcopy.service.ApprovalCopyService;
import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
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 java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用审批功能Service
 * @author mpb
 * @version 2018-01-11
 */
@Service
@Transactional(readOnly = true)
public class OaAllService extends CrudService<OaAllDao, OaAll> {

	@Autowired
	private WorkProjectNotifyService workProjectNotifyService;

	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	protected TaskService taskService;
	@Autowired
	protected HistoryService historyService;
	@Autowired
	protected RepositoryService repositoryService;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private OaAllDao oaAllDao;
	@Autowired
	private ActTaskService actTaskService;
	@Autowired
	private ApprovalCopyService approvalCopyService;
	@Autowired
	private UserDao userDao;
	@Autowired
	private WorkClientAttachmentDao workClientAttachmentDao;
	@Autowired
	private WorkattachmentService workattachmentService;

	public OaAll get(String id) {
		OaAll oaAll = oaAllDao.get(id);
		WorkClientAttachment workClientAttachment = new WorkClientAttachment();
		workClientAttachment.setAttachmentId(id);
		workClientAttachment.setAttachmentFlag("67");
		List<WorkClientAttachment> list = workClientAttachmentDao.findList(workClientAttachment);
		if(list.size() > 0){
			oaAll.setWorkAttachments(list);
		}
		Map<String,Object> variables=null;
		if(oaAll != null){
			HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(oaAll.getProcessInstanceId()).singleResult();
			if(historicProcessInstance!=null) {
				variables = Collections3.extractToMap(historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(), "variableName", "value");
			} else {
				variables = runtimeService.getVariables(runtimeService.createProcessInstanceQuery().processInstanceId(oaAll.getProcessInstanceId()).active().singleResult().getId());
			}
			oaAll.setVariables(variables);
		}
		return oaAll;
	}
	
	public List<OaAll> findList(OaAll oaAll) {
		return super.findList(oaAll);
	}
	
	public Page<OaAll> findPage(Page<OaAll> page, OaAll oaAll) {
		oaAll.getSqlMap().put("dsf", dataScopeFilter(oaAll.getCurrentUser(), "o", "u","s", MenuStatusEnum.OA_ALL.getValue()));
		oaAll.setPage(page);
		page.setList(findList(oaAll));
		return page;
	}
	
	@Transactional(readOnly = false)
	public void save(OaAll oaAll,Map<String, Object> variables) {
		super.save(oaAll);

		for (WorkClientAttachment workClientAttachment : oaAll.getWorkAttachments()){
			if (workClientAttachment.getId() == null){
				continue;
			}
			if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())){
				workClientAttachment.setAttachmentId(oaAll.getId());
				workClientAttachment.setAttachmentFlag("67");
				workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
				if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())){
					workClientAttachment.preInsert();
					workClientAttachmentDao.insert(workClientAttachment);
				}else{
					workClientAttachment.preUpdate();
					workClientAttachmentDao.update(workClientAttachment);
				}
			}else{
				workClientAttachmentDao.delete(workClientAttachment);
			}
		}
		// 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
		identityService.setAuthenticatedUserId(oaAll.getCurrentUser().getId());
		// 启动流程
		String businessKey = oaAll.getId().toString();
		variables.put("type", "allApprove");
		variables.put("busId", businessKey);
		variables.put("title", "通用审批");//设置标题；
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ActUtils.PD_ALLAPPROVE[0], businessKey, variables);
		oaAll.setProcessInstance(processInstance);
		// 更新流程实例ID
		oaAll.setProcessInstanceId(processInstance.getId());
		oaAllDao.updateProcessInstanceId(oaAll);
	}
	
	@Transactional(readOnly = false)
	public void delete(OaAll oaAll) {
		super.delete(oaAll);
	}

	@Transactional(readOnly = false)
	public void sendNotify(String chaosongIds,String shenpiId,String oaLeaveId) {
		if(StringUtils.isNotBlank(oaLeaveId)){
			if(StringUtils.isNotBlank(chaosongIds)){
				WorkProjectNotify notify = new WorkProjectNotify();
				notify.setTitle(UserUtils.getUser().getName()+"发起了通用审批申请");
				notify.setRemarks("待通知");
				notify.setContent(UserUtils.getUser().getName()+"的通用审批申请");
				notify.setNotifyRole("");
				notify.setNotifyId(oaLeaveId);
				notify.setStatus("0");
				notify.setCompanyId(UserUtils.getSelectCompany().getId());
				notify.setType("32");
				String[] arr = chaosongIds.split(",");
				for (String id : arr){
					if(StringUtils.isNotBlank(id)){
						notify.setId("");
						notify.setUser(new User(id));
						workProjectNotifyService.save(notify);
					}
				}
			}
			if(StringUtils.isNotBlank(shenpiId)){
				WorkProjectNotify notify = new WorkProjectNotify();
				notify.setTitle("您有新的通用审批申请待审批");
				notify.setRemarks("待审批");
				notify.setContent("通用审批申请--待审批");
				notify.setNotifyRole("");
				notify.setUser(new User(shenpiId));
				notify.setNotifyId(oaLeaveId);
				notify.setStatus("0");
				notify.setCompanyId(UserUtils.getSelectCompany().getId());
				notify.setType("32");
				workProjectNotifyService.save(notify);
			}
		}
	}


	@Transactional(readOnly = false)
	public void auditSave(OaAll oaAll) {
		// 设置意见
		oaAll.getAct().setComment(("yes".equals(oaAll.getAct().getFlag())?"[同意] ":"[驳回] ")+oaAll.getAct().getComment());
		// 对不同环节的业务逻辑进行操作
		String taskDefKey = oaAll.getAct().getTaskDefKey();
		//发送通知
		WorkProjectNotify notify = new WorkProjectNotify();
		notify.setNotifyId(oaAll.getId());
		notify.setCompanyId(UserUtils.getSelectCompany().getId());
		notify.setType("32");
		notify.setStatus("0");
		notify.setNotifyRole("");

		//业务逻辑对应的条件表达式
		String exp = "";
		// 审核环节
		if ("audit1".equals(taskDefKey)){
			exp = "pass";
		} else if ("audit2".equals(taskDefKey)) {
			exp = "pass";
		} else if ("audit3".equals(taskDefKey)){
			exp = "pass";
		}else if ("audit4".equals(taskDefKey)){
			exp = "pass";
		}else if ("audit5".equals(taskDefKey)){
			exp = "pass";
		}else if("apply_end".equals(taskDefKey)){
			exp = "pass";
		}
		// 未知环节，直接返回
		else{
			return;
		}
		// 提交流程任务
		Map<String, Object> vars = Maps.newHashMap();
		vars.put(exp, "yes".equals(oaAll.getAct().getFlag()) ? false : true);
		// 提交流程任务
		actTaskService.complete(oaAll.getAct().getTaskId(), oaAll.getAct().getProcInsId(), oaAll.getAct().getComment(), vars);
		boolean state = actTaskService.isProcessEnd(oaAll.getAct().getProcInsId());
		oaAll.setStatus("2");
		if (!state){
			if ("yes".equals(oaAll.getAct().getFlag())){
				oaAll.setStatus("3");
			}else {
				oaAll.setStatus("4");
			}
		}
		oaAll.preUpdate();
		oaAllDao.update(oaAll);

		//需在leave更新后 操作：
		//1待审核  2审核中 3通过 4驳回 5已撤销 6催办中
		if("2".equals(oaAll.getStatus())){
			oaAll = this.get(oaAll.getId());
			String userId = oaAll.getVariables().get("assignee").toString();
			if(StringUtils.isNotBlank(userId)){
				notify.setUser(UserUtils.get(userId));
			}
			notify.setTitle("您有新的通用审批申请待审批");
			notify.setRemarks("待审批");
			notify.setContent("通用审批申请--待审批");

		}else if("3".equals(oaAll.getStatus())){
			notify.setUser(oaAll.getCreateBy());
			notify.setTitle("您的通用审批申请已通过");
			notify.setRemarks("待通知");
			notify.setContent(oaAll.getAct().getComment());
		}else if("4".equals(oaAll.getStatus())){
			notify.setUser(oaAll.getCreateBy());
			notify.setTitle("您的通用审批申请被驳回");
			notify.setRemarks("待通知");
			notify.setContent(oaAll.getAct().getComment());
		}
		workProjectNotifyService.save(notify);

		//更新审核人的阅读状态
		WorkProjectNotify notify2 = new WorkProjectNotify();
		notify2.setUser(UserUtils.getUser());
		notify2.setNotifyId(oaAll.getId());
		workProjectNotifyService.readByNotifyIdAndNotifyUser(notify2);

		//抄送
		if("3".equals(oaAll.getStatus()) || "4".equals(oaAll.getStatus())){
			ApprovalCopy approvalCopy = approvalCopyService.getByApprovalId(oaAll.getId());
			if(approvalCopy!=null && StringUtils.isNotBlank(approvalCopy.getCCId())){
				WorkProjectNotify notify1= new WorkProjectNotify();
				notify1.setNotifyId(oaAll.getId());
				notify1.setCompanyId(UserUtils.getSelectCompany().getId());
				notify1.setType("32");
				notify1.setStatus("0");
				notify1.setNotifyRole("");
				notify1.setContent(oaAll.getAct().getComment());
				String[] ccIds = approvalCopy.getCCId().split(",");
				for(String ccId : ccIds){
					if(StringUtils.isNotBlank(ccId)){
						notify1.setUser(new User(ccId));
						if("3".equals(oaAll.getStatus())){
							notify1.setTitle(UserUtils.get(oaAll.getCreateBy().getId()).getName()+"的通用审批申请已通过");
						}
						if("4".equals(oaAll.getStatus())){
							notify1.setTitle(UserUtils.get(oaAll.getCreateBy().getId()).getName()+"的通用审批申请被驳回");
						}
						notify1.setRemarks("待通知");
						notify1.setId("");
						workProjectNotifyService.save(notify1);
					}
				}
			}
		}
	}

	/**
	 * 获取流程详细Leave
	 * @param processInstanceId
	 */
	@SuppressWarnings("unchecked")
	public OaAll getByProcessInstanceId(String processInstanceId) {
		OaAll oaAll = oaAllDao.getByProcessInstanceId(processInstanceId);
		return oaAll;
	}

	/**
	 * 获取流程详细及工作流参数
	 * @param id
	 */
	@SuppressWarnings("unchecked")
	public OaAll getById(String id) {
		OaAll oaAll = oaAllDao.get(id);
		return oaAll;
	}

	@Transactional(readOnly = false)
	public void update(OaAll oaAll) {
		oaAll.preUpdate();
		oaAllDao.update(oaAll);
	}

	@Transactional(readOnly = false)
	public Map getLeaveById(String id,String type) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		OaAll oaAll = this.getById(id);
		Map<String,Object> map = Maps.newHashMap();
		String officeName = "";
		String officeId = "";
		if(oaAll!=null){
			User user = userDao.get(oaAll.getCreateBy());
			if(user!=null){
				map.put("userName", user.getName());
				map.put("photo",user.getPhoto());
				map.put("users", user.getId());
				Office office = user.getOffice();
				if(office!=null && office.getName()!=null){
					officeName = office.getName();
					officeId = office.getId();
				}
			}
			map.put("createDate",oaAll.getCreateDate()==null?"":sdf.format(oaAll.getCreateDate()));
			map.put("applyContent",oaAll.getApplyContent());
			map.put("filePath",oaAll.getFiles());
			List<Workattachment> workattachmentList = workattachmentService.getListByAttachmentIdAndFlag(oaAll.getId(),"67");
			String files = "";
			if (workattachmentList!=null && workattachmentList.size()!=0){
				for (Workattachment workattachment : workattachmentList){
					files += workattachment.getUrl()+",";
				}
				if (files.length() > 1) {
					files = files.substring(0, files.length() - 1);
				}
			}
			map.put("files", files);
			map.put("approveDetail",oaAll.getApproveDetail());
			map.put("companyId",oaAll.getCompanyId());
			map.put("officeName",officeName);
			map.put("officeId",officeId);
			map.put("approvalId",id);
			map.put("status",oaAll.getStatus());
			List<Act> list = actTaskService.histoicFlowList(oaAll.getProcessInstanceId(), "", "");
			List<Act> list2 = actTaskService.toMyStartedList(oaAll.getProcessInstanceId());
			if (list2!=null && list2.size()!=0){
				Act act1 = list2.get(list2.size()-1);
				map.put("taskId", act1.getTaskId());
				map.put("taskName",act1.getTaskName());
				map.put("procInsId", act1.getProcInsId());
				map.put("procDefId", act1.getProcDefId());
				map.put("actStatus", act1.getStatus()==null?"todo":act1.getStatus());
				map.put("taskDefKey", act1.getTaskDefKey());
				map.put("procDefKey", "allApprove");
			}
			List list1 = new ArrayList();
			String approvalStatus = "0";
			String assigneeName = "";
			if (list!=null && list.size()!=0) {
				if (list.get(0).getHistIns().getActivityName().contains("审批")) {
					for (int i = list.size() - 1; i > -1; i--) {
						Act act = list.get(i);
						Map<String, Object> maps = new HashMap<String, Object>();
						String state = "0";
						String activityName = "";
						if (act.getHistIns().getActivityName().contains("审批")) {
							if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
								activityName = "已审批";
								if (UserUtils.getUser().getName().equals(act.getAssigneeName())){
									approvalStatus = "1";
								}
							} else {
								activityName = "待审批";
								state = "2";
							}
						} else {
							activityName = act.getHistIns().getActivityName();
						}
						if (type.equals("1") || type.equals("2")) {
							maps.put("activityName", activityName);
							maps.put("assigneeName", UserUtils.getUser().getName().equals(act.getAssigneeName()) ? "我" : act.getAssigneeName());
						} else if (type.equals("3")) {
							maps.put("activityName", activityName);
							maps.put("assigneeName", act.getAssigneeName());
						}
						maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
						maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
						maps.put("durationTime", act.getDurationTime());
						maps.put("state", state);
						maps.put("userId", act.getCurrentUser().getId());
						list1.add(maps);
					}
				} else {
					if (oaAll.getStatus().equals("4") || oaAll.getStatus().equals("3")){
						for (int i = 0; i < list.size()-1; i++) {
							Act act = list.get(i);
							Map<String, Object> maps = new HashMap<String, Object>();
							String state = "0";
							String activityName = "";
							if (act.getHistIns().getActivityName().contains("发起申请")) {
								activityName = act.getHistIns().getActivityName();
								assigneeName = act.getAssigneeName();
							}else if (act.getHistIns().getActivityName().contains("审批")) {
								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
								}
								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
									activityName = "已审批";
									if (UserUtils.getUser().getName().equals(assigneeName)){
										approvalStatus = "1";
									}
									if (i == (list.size()-2) && oaAll.getStatus().equals("4")){
										activityName = "审核驳回";
										state = "1";
									}else if (i == (list.size()-2) && oaAll.getStatus().equals("3")){
										activityName = "审核成功";
									}
								} else {
									activityName = "待审批";
									state = "2";
								}
							}
							else {
								activityName = act.getHistIns().getActivityName();
								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
								}
							}
							maps.put("activityName", activityName);
							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
							maps.put("durationTime", act.getDurationTime());
							maps.put("state", state);
							maps.put("userId", act.getCurrentUser().getId());
							list1.add(maps);
						}
					}else {
						for (int i = 0; i < list.size(); i++) {
							Act act = list.get(i);
							Map<String, Object> maps = new HashMap<String, Object>();
							String state = "0";
							String activityName = "";
							if (act.getHistIns().getActivityName().contains("发起申请")) {
								activityName = act.getHistIns().getActivityName();
								assigneeName = act.getAssigneeName();
							}else if (act.getHistIns().getActivityName().contains("审批")) {
								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
								}
								if (act.getDurationTime() != null && !act.getDurationTime().equals("")) {
									activityName = "已审批";
									if (UserUtils.getUser().getName().equals(assigneeName)){
										approvalStatus = "1";
									}
								} else {
									activityName = "待审批";
									state = "2";
								}
							}
							else {
								activityName = act.getHistIns().getActivityName();
								if (UserUtils.get(act.getHistIns().getAssignee())!=null) {
									assigneeName = UserUtils.get(act.getHistIns().getAssignee()).getName();
								}
							}
							if (oaAll.getStatus().equals("5") && i == list.size() - 1) {
								activityName = "已撤销";
								state = "1";
							}
							maps.put("activityName", activityName);
							maps.put("assigneeName", UserUtils.getUser().getName().equals(assigneeName) ? "我" : assigneeName);
							maps.put("startTime", act.getHistIns().getStartTime() == null ? "" : sdf.format(act.getHistIns().getStartTime()));
							maps.put("endTime", act.getHistIns().getEndTime() == null ? "" : sdf.format(act.getHistIns().getEndTime()));
							maps.put("durationTime", act.getDurationTime());
							maps.put("state", state);
							maps.put("userId", act.getCurrentUser().getId());
							list1.add(maps);
						}
					}
				}
			}
			map.put("approvalStatus", approvalStatus);
			ApprovalCopy approvalCopy = new ApprovalCopy();
			approvalCopy.setApprovalId(id);
			List<ApprovalCopy> approvalCopyList = approvalCopyService.findList(approvalCopy);
			String CCName = "";
			String CCId = "";
			Boolean readFlag = false;
			if (approvalCopyList!=null && approvalCopyList.size()!=0) {
				ApprovalCopy approvalCopy1 = approvalCopyList.get(0);
				CCId = approvalCopy1.getCCId();
				String[] CCid = approvalCopy1.getCCId().split(",");
				readFlag = approvalCopy1.getReadFlag().equals("0");
				if (type.equals("3") && readFlag){
					approvalCopy1.setReadFlag("1");
					approvalCopyService.save(approvalCopy1);
				}
				for (String userId : CCid) {
					User CCUser = UserUtils.get(userId);
					if (CCUser != null) {
						CCName = CCUser.getName() + ",";
					}
				}
				if (CCName.length() > 1) {
					CCName = CCName.substring(0, CCName.length() - 1);
				} else {
					CCName = "";
				}
			}

			map.put("nameCopy",CCName);
			map.put("CCId",CCId);
			map.put("process",list1);
		}
		return map;
	}
	@Transactional(readOnly = false)
	public void saveFile(OaAll oaAll) {
		if (StringUtils.isBlank(oaAll.getId())){
			oaAll.preInsert();
			oaAllDao.insert(oaAll);
		}else{
			oaAll.preUpdate();
			oaAllDao.update(oaAll);
		}
	}

	//APP端使用，一次上传一个
	@Transactional(readOnly = false)
	public String uploadFile(OSSClientUtil ossClientUtil, MultipartFile file, OaAll oaAll, String flag) {
		String fileName = file.getOriginalFilename();
		String fileType = fileName.substring(fileName.lastIndexOf("."));
		String url = ossClientUtil.uploadFile2OSS(file,"oaAll");
		Workattachment workattachment = new Workattachment();
		workattachment.setUrl(url);
		workattachment.setAttachmentName(fileName);
		workattachment.setType(fileType);
		workattachment.setAttachmentId(oaAll.getId());
		workattachment.setAttachmentUser(UserUtils.getUser().getId());
		workattachment.setCompanyId(UserUtils.getSelectCompany().getId());
		workattachment.setAttachmentFlag(flag);
		workattachmentService.save(workattachment);
		return url;
	}
}