package com.fourdage.dingding.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Repository;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fourdage.base.common.HttpHelper;
import com.fourdage.dingding.entity.DingDingSearchBean;
import com.fourdage.dingding.entity.ProcessInstance;
import com.fourdage.system.entity.DataDictionary;
import com.fourdage.system.entity.User;
import com.fourdage.system.service.IDataDictionaryService;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;


@Repository
public class DingDingUtil {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private IDataDictionaryService dataDictionaryService;
	
	@Autowired  
	private EhCacheCacheManager ehCacheCacheManager;
	
	public  String getTaskResult(String taskResult) {
		switch (taskResult) {
		case "AGREE":
			taskResult = "同意";
			break;
		case "REFUSE":
			taskResult = "拒绝";
			break;
		case "REDIRECTED":
			taskResult = "转交";
			break;
		default:
			taskResult = "";
			break;
		}
		return taskResult;
	}
	
	public  JSONObject getDingDingJSONResult(String processInstanceId, String accessToken) {
    	Map<String, Object> processMap = new HashMap<String, Object>();
    	processMap.put("method", "dingtalk.smartwork.bpms.processinstance.get");
    	processMap.put("session", accessToken);
    	processMap.put("timestamp", Long.valueOf(System.currentTimeMillis()).toString());
    	processMap.put("format", "json");
    	processMap.put("v", "2.0");
    	processMap.put("process_instance_id", processInstanceId);
    	
    	String resultStr = HttpHelper.sendGetByUrlConnection("https://eco.taobao.com/router/rest", processMap, "UTF-8");
    	JSONObject resultStrObject = JSON.parseObject(resultStr);
    	JSONObject jsonResult = resultStrObject.getJSONObject("dingtalk_smartwork_bpms_processinstance_get_response").getJSONObject("result");
    	return jsonResult;
    }

	public  String getStatus(String status){
    	switch (status) {
		case "NEW":
			return "刚创建";
		case "RUNNING":
			return "运行中";
		case "TERMINATED":
			return "被终止";
		case "COMPLETED":
			return "完成";
		case "CANCELED":
			return "取消";
		default:
			return "";
		}
    }
	
	public  boolean isJSONValid(String test) {
        try {
            JSONObject.parseObject(test);
        } catch (Exception ex) {
            try {
                JSONObject.parseArray(test);
            } catch (Exception ex1) {
                return false;
            }
        }
        return true;
    }
	
	public List<ProcessInstance> getProcesses(List<ProcessInstance> processes, DingDingSearchBean searchBean){
		logger.info("run getProcesses");
    	
    	DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    	
		Map<String, Object> processMap = new HashMap<String, Object>();
		processMap.put("method", "dingtalk.smartwork.bpms.processinstance.list");
		processMap.put("session", getAccessToken());
		processMap.put("timestamp", Long.valueOf(System.currentTimeMillis()).toString());
		processMap.put("format", "json");
		processMap.put("v", "2.0");
		processMap.put("process_code", searchBean.getProcessCode());
		processMap.put("start_time", searchBean.getStartTime());
		processMap.put("cursor", searchBean.getPage() == null ? 0 : searchBean.getPage());
		
		String resultStr = HttpHelper.sendGetByUrlConnection("https://eco.taobao.com/router/rest", processMap, "UTF-8");
		JSONObject resultStrObject = JSON.parseObject(resultStr);
		JSONObject jsonResult = resultStrObject.getJSONObject("dingtalk_smartwork_bpms_processinstance_list_response").getJSONObject("result");
		System.out.println("jsonResult:" + jsonResult);
		
		if (jsonResult.getBoolean("success")){
			JSONObject result = jsonResult.getJSONObject("result");
			JSONObject list =  result.getJSONObject("list");
			JSONArray processInstanceTop = list.getJSONArray("process_instance_top_vo");
			if (processInstanceTop != null){
				for (Object obj : processInstanceTop){
					JSONObject jobj = (JSONObject)obj;
					
					String processInstanceResult = jobj.getString("process_instance_result");
					String status = jobj.getString("status");
					if (StringUtils.isEmpty(processInstanceResult) || StringUtils.isEmpty(status)
							|| !"COMPLETED".equals(status)
							|| !"agree".equals(processInstanceResult)
					){
						continue;
					}
					if (jobj.getString("finish_time") == null){
						continue;
					}
					
					DateTime de = DateTime.parse(jobj.getString("finish_time"), format);
					if (de.isAfter(searchBean.getStartTimeSearch()) && de.isBefore(searchBean.getEndTimeSearch())){
						if (StringUtils.isNotEmpty(searchBean.getBusinessNum()) 
								&& !jobj.getString("business_id").contains(searchBean.getBusinessNum())){
							continue;
						}
						
						if (StringUtils.isNotEmpty(searchBean.getCompany())){
							try {
								String company = jobj.getJSONObject("form_component_values").getJSONArray("form_component_value_vo").getJSONObject(0).getString("value");
								if (searchBean.getCompany().equals(company)){
									processes.add(getProcessInstance(format, jobj, processInstanceResult, status));
								}
							}catch(Exception e){}
						}else{
							processes.add(getProcessInstance(format, jobj, processInstanceResult, status));
						}
					}
				}

				// 查询下一页
				if (result.get("next_cursor") != null){
					searchBean.setPage(String.valueOf(result.getInteger("next_cursor")));
					getProcesses(processes, searchBean);
				}
			}
		}
		return processes;
    }

	private ProcessInstance getProcessInstance(DateTimeFormatter format, JSONObject jobj, String processInstanceResult,
			String status) {
		ProcessInstance process = new ProcessInstance();
		process.setBusinessId(jobj.getString("business_id"));
		
		if (jobj.getString("create_time") != null){
			process.setCreateTime(DateTime.parse(jobj.getString("create_time"), format).toDate());
		}
		if (jobj.getString("finish_time") != null){
			process.setFinishTime(DateTime.parse(jobj.getString("finish_time"), format).toDate());
		}
		process.setOriginatorDeptId(jobj.getString("originator_dept_id"));
		process.setOriginatorUserId(jobj.getString("originator_userid"));
		process.setProcessInstanceId(jobj.getString("process_instance_id"));
		process.setResult(processInstanceResult);
		process.setStatus(status);
		process.setTitle(jobj.getString("title"));
		return process;
	}
	
	public String getRegion(){
		Subject subject = SecurityUtils.getSubject();
        Object principal = subject.getPrincipal();
        String region = "zh";
        if (principal != null) {
        	region = ((User) principal).getAddress();
        }
        return region;
	}
    
    public String getAccessToken() {
        String region = getRegion();
    	
    	DataDictionary searchCondition = new DataDictionary();
		searchCondition.setCode("dingding_corp_code");
		searchCondition.setParam1(region);
    	
    	Cache cache = ehCacheCacheManager.getCacheManager().getCache("accessToken");
    	Element sessionKey = cache.get(searchCondition.getParam1());
    	if (sessionKey != null){
    		return (String) sessionKey.getObjectValue();
    	}
    	
    	List<DataDictionary> datas = dataDictionaryService.findByCondition(searchCondition);
    	
    	Map<String, Object> tokenMap = new HashMap<String, Object>();
    	tokenMap.put("corpid", datas.get(0).getDataKey());
    	tokenMap.put("corpsecret", datas.get(0).getDataValue());
    	
    	String accessTokenStr = HttpHelper.sendGetByHttpUrlConnection("https://oapi.dingtalk.com/gettoken", tokenMap, "UTF-8");
    	JSONObject jsonObject = JSON.parseObject(accessTokenStr);
    	String accessToken = jsonObject.getString("access_token");
    	
    	Element elementSession = new Element(searchCondition.getParam1(), accessToken);
    	cache.put(elementSession);
    	cache.flush();
    	
    	return accessToken;
    }
    
    public String getFileName(String processCode, String title, String businessId){
		StringBuffer sb = new StringBuffer();
		sb.append(processCode).append("/").append(title).append(businessId);
		return sb.toString();
		
	}

	public static void main(String[] args) {
		DingDingUtil util = new DingDingUtil();
		System.out.println(util.getAccessToken());
	}

	public void getWorkflowInfo(String accessToken, String processInstanceId){
		String api = StrUtil.format("https://api.dingtalk.com/v1.0/workflow/processInstances?processInstanceId={}", processInstanceId);
		HttpResponse response = HttpUtil.createGet(api).header("x-acs-dingtalk-access-token", accessToken).execute();
		logger.info("钉钉返回值：{}", response.body());


	}

}
