package com.yeejoin.amos.boot.biz.common.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.biz.common.service.IWorkflowExcuteService;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;

@Service
public class WorkflowExcuteServiceImpl implements IWorkflowExcuteService {

	@Autowired
	WorkflowFeignService workflowFeignService;

	@Transactional
	@Override
	public String startAndComplete(String key, String condition) throws Exception {
		JSONObject body = new JSONObject();
		String businessKey = buildOrderNo();
		body.put("businessKey", businessKey);
		body.put("processDefinitionKey", key);
		JSONObject jsonObject = workflowFeignService.startByVariable(body);
		if (jsonObject == null || jsonObject.getJSONObject("data") == null) {
			throw new RuntimeException("启动流程失败");
		}
		if (jsonObject != null) {
			JSONObject instance = jsonObject.getJSONObject("data");
			if (!excuteTask(instance.getString("id"), condition)) {
				throw new RuntimeException("初始执行任务失败");
			}
		}
		return jsonObject.getJSONObject("data").getString("id");
	}

	@Override
	public boolean checkTaskAuth(String processInstanceId) {
		Map<String, Object> map = checkTaskAuthMap(processInstanceId);
		return Boolean.parseBoolean(map.get("checkFlag").toString());
	}

	@Override
	public Map<String, Object> checkTaskAuthMap(String processInstanceId) {
		// 获取当前登录用户的角色
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("checkFlag", false);
		JSONObject teskObject = workflowFeignService.getTask(processInstanceId);
		if (ObjectUtils.isNotEmpty(teskObject.getJSONObject("data"))) {
			map.put("taskId", teskObject.getJSONObject("data").getString("id"));
			map.put("checkFlag", true);
			map.put("name", teskObject.getJSONObject("data").getString("name"));

		}
		/*
		 * JSONObject teskObject = workflowFeignService.getTaskList(processInstanceId);
		 * if (ObjectUtils.isNotEmpty(teskObject)) { JSONArray taskDetailArray =
		 * teskObject.getJSONArray("data"); for (Object obj : taskDetailArray) {
		 * JSONObject detail = JSONObject.parseObject(JSONObject.toJSONString(obj));
		 * JSONObject taskGroupNameObject =
		 * workflowFeignService.getTaskGroupName(detail.getString("id")); //
		 * 获取流程中原本设置的当前节点的执行权限 JSONArray taskGroupNameDetail =
		 * taskGroupNameObject.getJSONArray("data"); //
		 * 如果拿不到当前任务的执行角色，再去获取当前任务有没有默认的执行人，如果都没有则返回校验失败 if
		 * (ObjectUtils.isEmpty(taskGroupNameDetail)) { JSONObject taskAssignObject =
		 * workflowFeignService.getTaskAssign(detail.getString("id")); String assignUser
		 * = taskAssignObject.getJSONObject("data").getString("assignee"); if
		 * (StringUtils.isNotBlank(assignUser)) { // 如果当前登录人与当前任务的设定人不一定，则直接返回权限校验失败 if
		 * (!currentLoginUserId.equals(assignUser)) { return map; } else {
		 * map.put("taskId", detail.getString("id")); map.put("checkFlag", true);
		 * map.put("name", detail.getString("name")); map.put("assign", assignUser);
		 * return map; } } continue; } String defaultExecutionRoleProcess =
		 * taskGroupNameDetail.getJSONObject(0).getString("groupId"); //
		 * 判断当前登录人的角色是不是与流程中设置的当前任务节点权限一致，一致则执行，不一致则退出 if
		 * (!defaultExecutionRoleProcess.equals(currentLoginUserRole)) { continue; }
		 * map.put("taskId", detail.getString("id")); map.put("checkFlag", true);
		 * map.put("name", detail.getString("name"));
		 * map.put("groupName",currentLoginUserRole); } }
		 */

		return map;
	}

	public boolean excuteTask(String procressId, String condition) throws Exception {
		HashMap<String, Object> conditionMap = new HashMap<String, Object>();
		conditionMap.put("condition", condition);
		JSONObject teskObject = workflowFeignService.getTaskList(procressId);
		if (ObjectUtils.isNotEmpty(teskObject)) {
			JSONArray taskDetailArray = teskObject.getJSONArray("data");
			for (Object obj : taskDetailArray) {
				JSONObject detail = JSONObject.parseObject(JSONObject.toJSONString(obj));
				workflowFeignService.pickupAndCompleteTask(detail.getString("id"), conditionMap);
			}
		}
		return true;
	}

	@Override
	public Object setTaskAssign(String processInstanceId, String userId) {
		JSONObject teskObject = workflowFeignService.getTaskList(processInstanceId);
		if (ObjectUtils.isEmpty(teskObject)) {
			throw new RuntimeException("设置任务执行人失败, 任务不存在，请检查processInstanceId" + processInstanceId + "是否正确");
		}
		JSONArray taskDetailArray = teskObject.getJSONArray("data");
		for (Object obj : taskDetailArray) {
			JSONObject detail = JSONObject.parseObject(JSONObject.toJSONString(obj));
			JSONObject taskGroupNameObject = workflowFeignService.getTaskGroupName(detail.getString("id"));
			try {
				if (taskGroupNameObject.getJSONArray("data") == null
						&& taskGroupNameObject.getJSONArray("data").size() < 1) {
					workflowFeignService.setTaskUser(detail.getString("id"), userId);
				}
			} catch (Exception e) {
				throw new RuntimeException("设置任务执行人失败");
			}
		}
		return true;
	}

	@Override
	public boolean CompleteTask(String processInstanceId, String condition) {
		Map<String, Object> map = checkTaskAuthMap(processInstanceId);
		if (Boolean.parseBoolean(map.get("checkFlag").toString())) {
			HashMap<String, Object> conditionMap = new HashMap<String, Object>();
			conditionMap.put("condition", condition);
			try {
				workflowFeignService.pickupAndCompleteTask(map.get("taskId").toString(), conditionMap);
			} catch (Exception e) {
				throw new RuntimeException("完成任务失败");
			}
		} else {
			throw new RuntimeException("没有执行权限");
		}
		return true;
	}

	public static String buildOrderNo() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String newDate = sdf.format(new Date());
		String result = "";
		Random random = new Random();
		for (int i = 0; i < 3; i++) {
			result += random.nextInt(10);
		}
		return newDate + result;
	}
}
