package com.highdatas.mdm.service.act.impl;

import com.highdatas.mdm.entity.TUser;
import com.highdatas.mdm.mapper.TableInfoMapper;
import com.highdatas.mdm.pojo.CodeMsg;
import com.highdatas.mdm.pojo.Result;
import com.highdatas.mdm.util.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class IdentityServiceImpl extends BaseServiceImpl implements com.highdatas.mdm.service.act.IdentityService{
	@Autowired
	IdentityService identityService;
	@Autowired
	RuntimeService runtimeService;
	@Autowired
	RepositoryService repositoryService;
	@Autowired
	TableInfoMapper tableInfoMapper;
	@Autowired
	RedisClient redisClient;

	/**
	 *
	 * @description:  启动流程
	 * @param businessId 业务id
	 * @param key 流程key
	 * @return: 实例id
	 *
	 */
    @Override
	public String startProcess(String businessId, String key) {
		return startProcess(businessId, key, null, null);
	}
	/**
	 *
	 * @description:  启动流程
	 * @param businessId 业务id
	 * @param key 流程key
	 * @param variables 额外参数
	 * @return: 实例id
	 *
	 */
    @Override
	public String startProcess(String businessId, String key, String workflowStall, HashMap<String, Object> variables) {
    	TUser user = getOnlineUser();
        if (user == null) {
			error(" user is null");
			return "";
		}
		
		ProcessInstance processInstance = null;
        try {
        	// add workflowstall

        	if (StringUtils.isEmpty(workflowStall)) {
				workflowStall = "1";
			}

			if (variables == null) {
                variables = new HashMap<>();
            }

        	int workflowStallInt = Integer.parseInt(workflowStall);
        	variables.put("workflowstall", workflowStallInt);
        	
        	identityService.setAuthenticatedUserId(user.getUserId());
			Date startDate = new Date();
            //get max version processDefinition
            List<Model> modelList = repositoryService.createModelQuery().modelKey(key).orderByModelVersion().desc().list();
			Date endDate = new Date();
			log.info("process load model:" + (endDate.getTime() - startDate.getTime()) +"ms");
            ProcessDefinition processDefinition = null;
            
            for (Model model : modelList) {
				if (processDefinition == null && model.getDeploymentId() != null) {
					String deploymentId = model.getDeploymentId();
					processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
					break;
				}
			}
			startDate = new Date();
			log.info("process load processDef:" + (startDate.getTime() - endDate.getTime()) +"ms");
            processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessId, variables);

			endDate = new Date();
			log.info("process start process :" + (endDate.getTime() - startDate.getTime()) +"ms");

            String processInstanceId = processInstance.getId();
            //TODO db
//            NamedSQL updateActinstUserSql = NamedSQL.getInstance("updateActinstUser");
//            updateActinstUserSql.setParam("userid", user.getId());
//            updateActinstUserSql.setParam("id", processInstanceId);
//            SQLRunner.execSQL(updateActinstUserSql);
            
            return processInstanceId;
           
    	}
    	finally {
    		identityService.setAuthenticatedUserId(null);
    	}
	}

	/**
	 *
	 * @description:  添加工作流用户
	 * @param id 用户id
	 * @return: 添加结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result addUser(String id) {
		User preUser = identityService.createUserQuery().userId(id).singleResult();
		if (preUser != null) {
			return  Result.error(new CodeMsg(6002, "已有相同id的用户存在"));
		}
		try {
			User user = identityService.newUser(id);
			identityService.saveUser(user);
			return Result.success(null);
		}catch (Exception e){
			e.printStackTrace();
			return Result.error(new CodeMsg(6002, e.getMessage()));
		}

	}

	/**
	 *
	 * @description:  添加工作流角色
	 * @param id 角色id
	 * @return: 添加结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result addRole(String id) {
		Group preGroup = identityService.createGroupQuery().groupId(id).singleResult();
		if (preGroup != null) {
			return  Result.error(new CodeMsg(6002, "已有相同id的角色存在"));
		}
		try {
			Group group = identityService.newGroup(id);
			identityService.saveGroup(group);
			return Result.success(null);
		}catch (Exception e){
			e.printStackTrace();
			return Result.error(new CodeMsg(6002, e.getMessage()));
		}
	}

	/**
	 *
	 * @description:  添加工作流用户,角色关联
	 * @param roleId 觉得id
	 * @param userId 用户id
	 * @return: 添加结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result addUserRole(String roleId, String userId) {
    	try {
			User user = identityService.createUserQuery().userId(userId).singleResult();
			if (user == null) {
				return Result.error(new CodeMsg(3001, "当前用户不存在,请先创建用户"));
			}

            Map<String, String> memberShip = tableInfoMapper.selectActMemberShip(userId, roleId);
			if (memberShip != null) {
                return Result.success(null);
            }
            identityService.createMembership(userId,roleId);
			return Result.success(null);
		}
		catch (Exception e) {
    		e.printStackTrace();
			return Result.error(new CodeMsg(3002, e.getMessage()));
		}
	}
	/**
	 *
	 * @description:  删除工作流用户
	 * @param id 用户id
	 * @return: 删除结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result deleteUser(String id) {
		try {
			User user = identityService.createUserQuery().userId(id).singleResult();
			if (user == null) {
				return Result.error(new CodeMsg(3001, "当前用户不存在"));
			}
			List<Map<String, Object>> maps = tableInfoMapper.selectActMemberShipByUser(id);
			for (Map<String, Object> map : maps) {
				Object group_id_ = map.get("GROUP_ID_");
				Object user_id_ = map.get("USER_ID_");
				if (user_id_ == null || group_id_ == null) {
					continue;
				}
				identityService.deleteMembership(user_id_.toString(), group_id_.toString());
			}
			redisClient.delByCharacter(id);
			identityService.deleteUser(id);
			return Result.success(null);
		}catch (Exception e){
			e.printStackTrace();
			return Result.error(new CodeMsg(3002, e.getMessage()));
		}

	}
	/**
	 *
	 * @description:  删除工作流角色
	 * @param id 角色id
	 * @return: 删除结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result deleteRole(String id) {
		try {
			Group group = identityService.createGroupQuery().groupId(id).singleResult();
			if (group == null) {
				return Result.error(new CodeMsg(3001, "当前角色不存在"));
			}
			List<Map<String, Object>> maps = tableInfoMapper.selectActMemberShipByRole(id);
			for (Map<String, Object> map : maps) {
				Object group_id_ = map.get("GROUP_ID_");
				Object user_id_ = map.get("USER_ID_");
				if (user_id_ == null || group_id_ == null) {
					continue;
				}
				identityService.deleteMembership(user_id_.toString(), group_id_.toString());
				redisClient.delByCharacter(user_id_.toString());
			}
			identityService.deleteGroup(id);
			return Result.success(null);
		}catch (Exception e){
			e.printStackTrace();
			return Result.error(new CodeMsg(3002, e.getMessage()));
		}
	}

	/**
	 *
	 * @description:  删除工作流用户 角色关联
	 * @param userId 用户id
	 * @param roleId 角色id
	 * @return: 删除结果
	 *
	 */
	@Override
	@Transactional(rollbackFor = {RuntimeException.class, Error.class})
	public Result deleteUserRole(String roleId, String userId) {
		try {

            Map<String, String> memberShip = tableInfoMapper.selectActMemberShip(userId, roleId);
            if (memberShip == null) {
                return Result.success(null);
            }
			redisClient.delByCharacter(userId);
			identityService.deleteMembership(userId,roleId);
			return Result.success(null);
		}
		catch (Exception e) {
			e.printStackTrace();
			return Result.error(new CodeMsg(3002, e.getMessage()));
		}
	}
	/**
	 *
	 * @description:  通过user获取关联的角色
	 * @param userId 用户id
	 * @return: 角色id列表
	 *
	 */
	@Override
	public List<String> getRoleByUser(String userId) {
		List<Group> list = identityService.createGroupQuery().groupMember(userId).list();
		if (list == null || list.isEmpty()) {
			return null;
		}
		return  list.stream().map(group -> group.getId()).collect(Collectors.toList());
	}


}