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

import com.google.common.collect.Maps;
import com.jeeplus.common.persistence.Page;
import com.jeeplus.common.service.CrudService;
import com.jeeplus.common.utils.DateUtils;
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.act.utils.ProcessDefCache;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.OfficeService;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workactivity.entity.Activity;
import com.jeeplus.modules.workactivity.entity.WorkActivityProcess;
import com.jeeplus.modules.workactivity.service.ActivityService;
import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
import com.jeeplus.modules.workactivitymenu.service.WorkActivityMenuService;
import com.jeeplus.modules.workfullmanage.dao.WorkFullManageDao;
import com.jeeplus.modules.workfullmanage.dao.WorkFullPayDao;
import com.jeeplus.modules.workfullmanage.entity.WorkFullManage;
import com.jeeplus.modules.workfullmanage.entity.WorkFullPay;
import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
import com.jeeplus.modules.workprojectnotify.util.UtilNotify;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
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 java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 工程计量支付Service
 * @author mapengbo
 * @version 2017-11-03
 */
@Service
@Transactional(readOnly = true)
public class WorkFullPayService extends CrudService<WorkFullPayDao, WorkFullPay> {

	@Autowired
	private WorkFullPayDao workFullPayDao;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	protected TaskService taskService;
	@Autowired
	protected HistoryService historyService;
	@Autowired
	protected RepositoryService repositoryService;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private ActTaskService actTaskService;
	@Autowired
	private WorkFullManageDao workFullManageDao;
	@Autowired
	private WorkProjectNotifyService workProjectNotifyService;
	@Autowired
	private WorkActivityMenuService workActivityMenuService;
	@Autowired
	private WorkActivityProcessService workActivityProcessService;
	@Autowired
	private ActivityService activityService;
	@Autowired
	private OfficeService officeService;

	public WorkFullPay get(String id) {
		return super.get(id);
	}
	
	public List<WorkFullPay> findList(WorkFullPay workFullPay) {
		return super.findList(workFullPay);
	}
	
	public Page<WorkFullPay> findPage(Page<WorkFullPay> page, WorkFullPay workFullPay) {
		page = super.findPage(page,workFullPay);
		List<WorkFullPay> list = page.getList();
		if(list!=null && list.size()>0){
			for (int i = 0; i < list.size(); i++) {
				WorkFullPay pay = list.get(i);

				//流程结束state=false，未结束state=true
				boolean state = true;
				if(StringUtils.isNotBlank(pay.getProcessInstanceId())){
					state = actTaskService.isProcessEnd(pay.getProcessInstanceId());
				}else{
					state = false;
				}
				pay.setProcessEnded(state);
			}
		}
		return page;
	}
	
	@Transactional(readOnly = false)
	public void save(WorkFullPay workFullPay,Map<String, Object> variables) {
		super.save(workFullPay);
		// 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
		identityService.setAuthenticatedUserId(UserUtils.getUser().getId());

		String workFullManageId2 = workFullPay.getWorkFullManageId();
		String officeId = workFullManageDao.get(workFullManageId2).getOfficeId();
		WorkActivityMenu workActivityMenu = workActivityMenuService.findByParentAndOffice("f5f37f9906374d5abbf57c95dfa28869",officeService.get(officeId));
		// 启动流程
		String businessKey = workFullPay.getId().toString();
		String processType = workActivityMenu.getProcessType();
		StringBuffer buffer1 = new StringBuffer();
		Activity activity = new Activity();
		if(StringUtils.isNotBlank(workActivityMenu.getId())){
			workActivityMenu = workActivityMenuService.get(workActivityMenu.getId());
			List<Activity> activities = workActivityMenu.getActivities();
			for (Activity a:activities){
				//审批任务的第一个人(角色)
				if (a.getDelFlag().equals("0") && a.getCount() == 1){
					activity = a;
					break;
				}
			}
			buffer1.append(activity.getRole().getEnname());
			variables.put("type", workActivityMenu.getProcessType());
		}else{
			processType = ActUtils.PD_WORKFULLPAY[0];
			variables.put("type", processType);
		}

		variables.put("busId", businessKey);
		variables.put("title", "审批单："+workFullPay.getApplyUnit());//设置标题；
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processType, businessKey, variables);
		workFullPay.setProcessInstance(processInstance);
		// 更新流程实例ID
		workFullPay.setProcessInstanceId(processInstance.getId());
		workFullPayDao.updateProcessInstanceId(workFullPay);

		List<Activity> list= workActivityMenu.getActivities();
		if (list!=null && list.size()!=0){
			workActivityProcessService.saveList(list,processInstance.getId());
		}else {
			WorkActivityProcess workActivityProcess = new WorkActivityProcess();
			workActivityProcess.setProcessKey(processType);
			workActivityProcess.setCount(1);
			workActivityProcess.setProcessInstanceId(processInstance.getId());
			workActivityProcess.setIsApproval("0");
			workActivityProcess.setActivity(new Activity("cde385ec18734780b3870f6a54e1b53e"));
			workActivityProcessService.save(workActivityProcess);
		}

		if(workActivityMenu!=null&&StringUtils.isNotBlank(workActivityMenu.getId())&&StringUtils.isNotBlank(activity.getId())){
			WorkProjectNotify workProjectNotify = new WorkProjectNotify();
			workProjectNotify.setTitle("工程计量支付申请,请审批!");
			workProjectNotify.setNotifyId(workFullPay.getId());
			String workFullManageId = workFullPay.getWorkFullManageId();
			workProjectNotify.setCompanyId(workFullManageDao.get(workFullManageId).getCompanyId());
			workProjectNotify.setContent(UserUtils.get(workFullPay.getCreateBy().getId()).getName()+"发起了工程计量支付申请，请审批!");
			workProjectNotify.setRemarks("待审批");
			workProjectNotify.setType("14");
			workProjectNotify.setStatus("0");
			workProjectNotify.setNotifyRole("");
			workProjectNotify.setUser(new User(""));

			//角色审批
			if(StringUtils.isNotBlank(activity.getRole().getEnname())){
				workProjectNotify.setNotifyRole(buffer1.toString());
			}
			//人员审批
			if(StringUtils.isNotBlank(activity.getUser().getId())){
				workProjectNotify.setUser(new User(activity.getUser().getId()));
			}
			workProjectNotifyService.save(workProjectNotify);
		}else {
			String workFullManageId = workFullPay.getWorkFullManageId();
			workProjectNotifyService.save(UtilNotify.saveNotify(workFullPay.getId(),
					null,
					workFullManageDao.get(workFullManageId).getCompanyId(),
					"工程计量支付申请,请审批",
					UserUtils.get(workFullPay.getCreateBy().getId()).getName()+"工程计量支付申请,请审批!",
					"14",
					"0",
					"待审批",
					variables.get("SSRHbmzr").toString()
			));
		}


	}
	
	@Transactional(readOnly = false)
	public void delete(WorkFullPay workFullPay) {
		super.delete(workFullPay);
	}

	/**
	 * 查询记录数
	 * @return
	 */
	public String queryCount(WorkFullPay workFullPay){
		return workFullPayDao.queryCount(workFullPay)+"";
	}

	/**
	 * 查询累计支付金额
	 * @return
	 */
	public String querySum(WorkFullPay workFullPay){
		return workFullPayDao.querySum(workFullPay);
	}

	/**
	 * 获取流程详细信息
	 * @param processInstanceId
	 */
	@SuppressWarnings("unchecked")
	public WorkFullPay getByProcessInstanceId(String processInstanceId) {
		WorkFullPay workFullPay = workFullPayDao.getByProcessInstanceId(processInstanceId);
		return workFullPay;
	}

	/**
	 * 获取已办任务
	 * @return
	 */
	public List<WorkFullPay> historicList(Act act){
		String userId = UserUtils.getUser().getId();
		HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery().finished().taskAssignee(userId);
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			query.processDefinitionKey(act.getProcDefKey());
		}
		if (act.getBeginDate() != null){
			query.taskCompletedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			query.taskCompletedBefore(act.getEndDate());
		}
		List<HistoricTaskInstance> list = query.list();
		List<WorkFullPay> list1 = new ArrayList<>();
		Office office = UserUtils.getSelectCompany();
		String companyId = office==null?"":office.getId();
		for (HistoricTaskInstance histTask : list) {
			WorkFullPay workFullPay = this.getByProcessInstanceId(histTask.getProcessInstanceId());
			if (workFullPay != null ){
				WorkFullManage workFullManage = workFullManageDao.get(workFullPay.getWorkFullManageId());
				if(workFullManage.getCompanyId().equals(companyId)){
					workFullPay.setCreateBy(UserUtils.get(workFullPay.getCreateBy().getId()));
					historyService.getHistoricIdentityLinksForProcessInstance(histTask.getProcessInstanceId());
					act.setHistTask(histTask);
					act.setVars(histTask.getProcessVariables());
					act.setProcDef(ProcessDefCache.get(histTask.getProcessDefinitionId()));
					act.setStatus("finish");
					workFullPay.setAct(act);
					list1.add(workFullPay);
				}
			}
		}
		return list1;
	}

	/**
	 * 审核流程
	 */
	@Transactional(readOnly = false)
	public String auditSave(WorkFullPay workFullPay, String status[]) {
		try{
			// 对不同环节的业务逻辑进行操作
			String taskDefKey = workFullPay.getAct().getTaskDefKey();
			if(!"modifyApply".equals(taskDefKey)){
				actTaskService.claim(workFullPay.getAct().getTaskId(), UserUtils.getUser().getId());
			}

			//业务逻辑对应的条件表达式
			String exp = "";
			String str = "";
			String notifyRole = "";
			User user = null;
			String comment = ("yes".equals(workFullPay.getAct().getFlag())?"[同意] ":"[驳回] ")+workFullPay.getAct().getComment();
			//WorkActivityMenu workActivityMenu = workActivityMenuService.findByParentAndOffice("f5f37f9906374d5abbf57c95dfa28869",UserUtils.getSelectOffice());
			List<Activity> activitieList = activityService.getByProcessInstanceId(workFullPay.getProcessInstanceId());
			WorkActivityMenu workActivityMenu = new WorkActivityMenu();
			if (activitieList!=null && activitieList.size()!=0){
				workActivityMenu.setProcessType(activitieList.get(0).getProcessKey());
				workActivityMenu.setActivities(activitieList);
			}

			WorkActivityProcess workActivityProcess = new WorkActivityProcess();
			WorkActivityProcess selectedProcess = new WorkActivityProcess();
			selectedProcess.setProcessInstanceId(workFullPay.getProcessInstanceId());
			List<WorkActivityProcess> workActivityProcesses = workActivityProcessService.findList(selectedProcess);

			workFullPay.setFullPayStatus("2");
			//是自定义流程
			boolean isCustomProcess = StringUtils.isNotBlank(workActivityMenu.getProcessType()) && !workActivityMenu.getProcessType().equals(ActUtils.PD_WORKFULLPAY[0]);
			String taskCount = "";
			int key = 0;
			WorkProjectNotify workProjectNotify = new WorkProjectNotify();
			workProjectNotify.setNotifyId(workFullPay.getId());
			workProjectNotifyService.readByNotifyId(workProjectNotify);//每执行一步审核操作，都把已发出的通知变更为"已读"
			List<Activity> activities = workActivityMenu.getActivities();
			// 1 暂存 2 审核中 3 未通过 4 已通过 5已撤销
			if (isCustomProcess) {
				key = 1;

				for (int i =0;i<workActivityProcesses.size();i++){
					WorkActivityProcess activityProcess = workActivityProcesses.get(i);
					String count = taskDefKey.replace("task","").replace("audit","");
					taskCount = count;
					//重申|撤销
					if(taskDefKey.contains("audit") && (activityProcess.getCount()+"").contains(count)){
						exp = "pass";
						workActivityProcess.setId("");
						workActivityProcess.setCount(0);
						if (!"yes".equals(workFullPay.getAct().getFlag())) {
							workFullPay.setFullPayStatus("5");//撤销
							workActivityProcess.setIsApproval("2");
						}else {
							workFullPay.setFullPayStatus("2");//重申
							workActivityProcess.setIsApproval("1");
							workProjectNotify.setTitle("工程计量支付：重新申请");
							workProjectNotify.setRemarks("待审批");
						}
						break;
					}
					else if ((activityProcess.getCount()+"").contains(count)){
						taskCount = count;
						workActivityProcess = activityProcess;
						workActivityProcess.setRemarks(comment);

						if (!workActivityProcess.getIsApproval().equals("0")){
							workActivityProcess.setId("");
						}
						exp = "pass";
						if (!"yes".equals(workFullPay.getAct().getFlag())) {
							workFullPay.setFullPayStatus("3");
							workActivityProcess.setIsApproval("2");
							workProjectNotify.setTitle("您的工程计量支付申请被驳回!");
							workProjectNotify.setNotifyRole("");
							workProjectNotify.setUser(workFullPay.getCreateBy());
							String returnBack = "-1";
							for (Activity activity:activities){
								if(activity.getCount()==Integer.parseInt(count)){
									returnBack = activity.getReturnBack();
									break;
								}
							}
							if (returnBack.equals("0")) {
								workActivityProcess.setId("");
							}
						}else {
							workActivityProcess.setIsApproval("1");
							workProjectNotify.setTitle("工程计量支付：待审批");
							//对通知的人(角色)的设定在 提交任务里完成
						}
					}
				}
			}else {

				workActivityMenu.setId(workActivityProcesses.get(0).getId());
				workActivityMenu.setProcessType(ActUtils.PD_WORKFULLPAY[0]);

				Role role = UserUtils.getSelectRole().get(0);
				StringBuffer buffer = DateUtils.getByEnnme(role.getEnname());

				for (int i = 0; i < workActivityProcesses.size(); i++) {
					WorkActivityProcess activityProcess = workActivityProcesses.get(i);
					String count = activityProcess.getCount() + "";

					// 部门负责人审核
					if ("deptLeaderAudit".equals(taskDefKey) && count.contains("1")){
						workActivityProcess = activityProcess;
						taskCount = "1";
						workActivityProcess.setProcessInstanceId(workFullPay.getProcessInstanceId());
						workActivityProcess.setProcessKey(ActUtils.PD_WORKFULLPAY[0]);
						workActivityProcess.setRemarks(comment);

						workFullPay.setFullPayStatus(("yes".equals(workFullPay.getAct().getFlag())?status[3]:status[2]));

						exp = "deptLeaderPass";
						user = workFullPay.getCreateBy();
						if("yes".equals(workFullPay.getAct().getFlag())){
							workActivityProcess.setIsApproval("1");
							str = "工程计量支付：待审批!";
						}else{
							workActivityProcess.setIsApproval("2");
							str = "工程计量支付：被驳回!";
						}
					}
					else if ("modifyApply".equals(taskDefKey) && count.contains("0")){
						taskCount = "1";
						workActivityProcess.setId("");
						workActivityProcess.setCount(0);

						exp = "modifyApply";
						if ("yes".equals(workFullPay.getAct().getFlag())){
							workActivityProcess.setIsApproval("1");
							//给部门负责人
							notifyRole = buffer.append("bmzr").toString();
							workFullPay.setFullPayStatus(status[1]);
							str = "工程计量支付：待审批!";
						}else{
							workActivityProcess.setIsApproval("2");
							workFullPay.setFullPayStatus(status[4]);
						}
						break;
					}
					else if ("apply_end".equals(taskDefKey)){
					}
					// 未知环节

				}
			}

			workActivityProcessService.updateProcess(workActivityProcess,workActivityMenu,key,taskCount,workFullPay.getProcessInstanceId(),taskDefKey,"modifyApply",workFullPay.getAct().getFlag(),comment, activities);

			// 设置意见
			workFullPay.getAct().setComment(comment);
			workFullPay.preUpdate();

			// 设置意见
			//workFullPay.getAct().setComment(("yes".equals(workFullPay.getAct().getFlag())?"[同意] ":"[驳回] ")+workFullPay.getAct().getComment());
			// 提交流程任务
			Map<String, Object> vars = Maps.newHashMap();
			vars.put(exp, "yes".equals(workFullPay.getAct().getFlag())? true : false);
			// 提交流程任务
			actTaskService.complete(workFullPay.getAct().getTaskId(), workFullPay.getAct().getProcInsId(), workFullPay.getAct().getComment(), vars);
			workFullPayDao.update(workFullPay);
			boolean state = actTaskService.isProcessEnd(workFullPay.getAct().getProcInsId());
			WorkFullManage workFullManage = workFullManageDao.get(workFullPay.getWorkFullManageId());
			if(!state) {

				if(isCustomProcess){
					if("yes".equals(workFullPay.getAct().getFlag())){
						workFullPay.setFullPayStatus("4");
						workProjectNotify.setTitle("您的工程计量支付审核：已通过");
					}else{
						if(! "3".equals(workFullPay.getFullPayStatus())) {
							workFullPay.setFullPayStatus("5");
						}else {
							workProjectNotify.setTitle("您的工程计量支付审核：未通过");
						}
					}
					workProjectNotify.setRemarks("待通知");
					workProjectNotify.setUser(workFullPay.getCreateBy());
					workProjectNotify.setCompanyId(workFullManage.getCompanyId());
					workProjectNotify.setContent(workFullPay.getAct().getComment());
					workProjectNotify.setType("14");
					workProjectNotify.setStatus("0");
					//创建人如果做了撤销操作，无需发送通知
					if (!workFullPay.getFullPayStatus().equals("5")) {
						workProjectNotifyService.save(workProjectNotify);
					}

				}else{

					//str = "yes".equals(workFullPay.getAct().getFlag())?"您的工程计量支付审核：已通过":"您的工程计量支付审核：未通过";
					WorkProjectNotify notify = new WorkProjectNotify();
					notify.setNotifyId(workFullPay.getId());
					workProjectNotifyService.readByNotifyId(notify);
					if("yes".equals(workFullPay.getAct().getFlag())){
						workProjectNotifyService
								.save(UtilNotify
										.saveNotify(workFullPay.getId(),
												workFullPay.getCreateBy(),
												workFullManage.getCompanyId(),
												"您的工程计量支付审核：已通过",
												workFullPay.getAct().getComment(),
												"14",
												"0",
												"待通知",
												""));
					}else {
						if ("3".equals(workFullPay.getFullPayStatus())){
							workProjectNotifyService
									.save(UtilNotify
											.saveNotify(workFullPay.getId(),
													workFullPay.getCreateBy(),
													workFullManage.getCompanyId(),
													"您的工程计量支付审核：未通过",
													workFullPay.getAct().getComment(),
													"14",
													"0",
													"待通知",
													""));
						}
					}
				}

			}else{

				if (isCustomProcess) {
					String count = taskDefKey.replace("audit","").replace("task","");
					Activity activity = new Activity();
					////撤销到某一步
					if (taskDefKey.contains("audit")) {
						if (activities.size() == 1 || count.equals("1")){
							activity = activities.get(0);
						}else if (activities.size()==Integer.parseInt(count)){
							activity = activities.get(activities.size()-1);
							String returnBack = activity.getReturnBack();
							if (returnBack.equals("1")){
								activity = activities.get(Integer.parseInt(count)-2);
							}else if (returnBack.equals("2")){
								activity = activities.get(0);
							}
						}else {
							activity = activities.get(Integer.parseInt(count)-1);
							String returnBack = activity.getReturnBack();
							if (returnBack.equals("1")){
								activity = activities.get(Integer.parseInt(count)-2);
							}else if (returnBack.equals("2")){
								activity = activities.get(0);
							}
						}
					}
					//中间步骤驳回
					else if(!"yes".equals(workFullPay.getAct().getFlag())){
						//驳回之后，创建人可以发起重申|撤销;将通知消息归类到审批列表，这一步必须
						//对通知的人（创建人）的设定在前面已完成
						workProjectNotify.setRemarks("重新申请");
						activity = new Activity();//驳回后将id置空
					}
					//中间某步骤同意
					else {
						//得到下一步要执行的activity
						activity = activities.get(Integer.parseInt(count));
						workProjectNotify.setRemarks("待审批");
					}
					//发送审批消息给下一步的人(角色)
					if(StringUtils.isNotBlank(activity.getId())){//在驳回时不走这一步，判断id必须
						workProjectNotify.setUser(activity.getUser());
						workProjectNotify.setNotifyRole(activity.getRole().getEnname());
					}

					workProjectNotify.setCompanyId(workFullManage.getCompanyId());
					workProjectNotify.setContent(workFullPay.getAct().getComment());
					workProjectNotify.setType("14");
					workProjectNotify.setStatus("0");
					//创建人如果做了撤销操作，无需发送通知
					if (!workFullPay.getFullPayStatus().equals("5")) {
						workProjectNotifyService.save(workProjectNotify);
					}
				}
				//如果是默认流程，
				else{
					//下一步的执行人(角色)已在前面设置
					WorkProjectNotify notify = new WorkProjectNotify();
					notify.setNotifyId(workFullPay.getId());
					workProjectNotifyService.readByNotifyId(notify);
					if (!"yes".equals(workFullPay.getAct().getFlag())){
						workProjectNotifyService
								.save(UtilNotify
										.saveNotify(workFullPay.getId(),
												user,
												workFullManage.getCompanyId(),
												str,
												workFullPay.getAct().getComment(),
												"14",
												"0",
												"重新申请",
												notifyRole));
					}else{
						workProjectNotifyService
								.save(UtilNotify
										.saveNotify(workFullPay.getId(),
												user,
												workFullManage.getCompanyId(),
												str,
												workFullPay.getAct().getComment(),
												"14",
												"0",
												"待审批",
												notifyRole));
					}
				}

			}
			workFullPayDao.update(workFullPay);
			return "保存审核意见成功！";
		}catch (ActivitiObjectNotFoundException e){
			logger.error("ActivitiObjectNotFoundException e:"+e);
			return "流程已审批，不能重新审批！";
		}catch (Exception e){
			logger.error("Exception e:"+e);
			return "保存审核意见失败！！";
		}
	}

	/**
	 * 获取第一条记录
	 * @param workFullPay
	 * @return
	 */
	public WorkFullPay getFirstRecord(WorkFullPay workFullPay){
		return workFullPayDao.getFirstRecord(workFullPay);
	}

	/**
	 * 查询是否存在状态不为已通过的数据
	 * @param workFullPay
	 * @return
	 */
	public int getStatusNotFour(WorkFullPay workFullPay){
		return workFullPayDao.getStatusNotFour(workFullPay);
	}
}