package com.hotent.portal.jms.impl;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import cn.hutool.json.JSONObject;
import com.aliyun.dingtalktodo_1_0.models.CreateTodoTaskHeaders;
import com.aliyun.dingtalktodo_1_0.models.CreateTodoTaskRequest;
import com.aliyun.dingtalktodo_1_0.models.CreateTodoTaskResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.hotent.base.feign.BpmRuntimeFeignService;
import com.hotent.base.feign.UCFeignService;
import com.hotent.base.jms.JmsActor;
import com.hotent.base.jms.JmsHandler;
import com.hotent.base.jms.JmsMessage;
import com.hotent.base.util.JsonUtil;
import com.hotent.portal.model.PortalDingTodoTask;
import com.hotent.portal.service.PortalDingTodoTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request.ActionCard;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request.Msg;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;

import com.hotent.base.jms.NoticeMessageType;
import com.hotent.base.util.BeanUtils;

import com.hotent.portal.model.MsgTemplate;
import com.hotent.portal.persistence.manager.MessageLogManager;
import com.hotent.portal.persistence.manager.MsgTemplateManager;
import com.hotent.portal.service.impl.TemplateServiceImpl;
import com.hotent.portal.util.DingTalkUtil;
import com.hotent.system.consts.DingTalkConsts;
import com.hotent.system.model.SysExternalUnite;
import com.hotent.system.persistence.manager.SysExternalUniteManager;
import com.hotent.system.util.DingTalkTokenUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * 阿里钉钉消息处理类
 *
 * @author pangq
 *
 */
@Service
public class DingTalkHandler implements JmsHandler {
	private static final Logger logger = LoggerFactory.getLogger(DingTalkHandler.class);
	@Resource
	MessageLogManager messageLogManager;
	@Resource
	SysExternalUniteManager sysExternalUniteManager;
	@Resource
	MsgTemplateManager msgTemplateManager;
	@Resource
	TemplateServiceImpl templateServiceImpl;
	@Resource
	UCFeignService uCFeignService;

	@Value("${dingSetting.dingPcTodoUrl}")
	private String dingPcTodoUrl;

	@Value("${dingSetting.dingAppTodoUrl}")
	private String dingAppTodoUrl;

	@Resource
	PortalDingTodoTaskService portalDingTodoTaskService;

	@Resource
	BpmRuntimeFeignService bpmRuntimeFeignService;

	@Override
	public String getType() {
		return NoticeMessageType.DINGTALK.key();
	}

	@Override
	public String getTitle() {
		return "钉钉消息";
	}

	@Override
	public boolean getIsDefault() {
		return false;
	}

	@Override
	public boolean getSupportHtml() {
		return true;
	}

	@Override
	public boolean send(JmsMessage jmsMessage) {
		try {
			List<JmsActor> receivers = jmsMessage.getReceivers();
			String content = jmsMessage.getContent();
			content = content.replace("<p>", "");
			content = content.replace("</p>", "");
			jmsMessage.setContent(content);
			// 根据消息模板的key获取模板对象
			MsgTemplate msgTemplate = msgTemplateManager.getByKey(jmsMessage.getTemplateAlias());
			if (BeanUtils.isNotEmpty(msgTemplate)) {
				jmsMessage.getExtendVars().put("templateType", msgTemplate.getTypeKey());
			}
			// 发送钉钉信息
			SysExternalUnite dingtalkUnite = sysExternalUniteManager.getDingtalk();
//			if (BeanUtils.isNotEmpty(dingtalkUnite)) {
			List<String> users = new ArrayList<String>();
			for (JmsActor receiver : receivers) {
				users.add(receiver.getId());
			}
			if(BeanUtils.isNotEmpty(users)){
				users.stream().forEach(item->{
					sendDingApiMessage(msgTemplate,item,jmsMessage);
				});
			}
//			}
			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
			logger.error(ex.getMessage());
			messageLogManager.handLogByMsgHander(jmsMessage, false, ex.getMessage());
			return false;
		}
	}
	/**
	 * @description  发送钉钉通知和待办封装数据
	 * @author  yangzibin
	 * @date    2024/3/19 10:20
	 * @param	msgTemplate
	 * @param	userId
	 * @param	jmsMessage
	 * @return  void
	 */
	private void sendDingApiMessage(MsgTemplate msgTemplate,String userId,JmsMessage jmsMessage){

		String dingtalkIds="";
		String orgId="";
		String dingToken="";
		String dingAgentId="";
		String userDingUnionId="";//unionId
		String dingCorpId="";//钉钉企业id
		JsonNode jsonNode=uCFeignService.queryExtUserInfoByUserId(userId);//获取钉钉系统用户id
		if(jsonNode!=null){
			dingtalkIds=jsonNode.get("externalUserId").asText();//获取组织钉钉userId
			orgId=jsonNode.get("orgId").asText();
			if(jsonNode.get("externalUnionId")!=null){
				userDingUnionId=jsonNode.get("externalUnionId").asText();//获取组织钉钉unionId
			}
			if(BeanUtils.isEmpty(userDingUnionId)&&BeanUtils.isNotEmpty(dingtalkIds)&&BeanUtils.isNotEmpty(orgId)){
				JsonNode  unionJson=uCFeignService.getDingUserUnionId(orgId,dingtalkIds);
				if(unionJson.get("state").asBoolean()){
					userDingUnionId=unionJson.get("unionId").asText();
				}
			}
		}
		if(BeanUtils.isNotEmpty(orgId)){
			JsonNode dingSetting=uCFeignService.getOrgExtSetting(orgId);//获取组织钉钉参数
			if(BeanUtils.isNotEmpty(dingSetting)){
				String state=dingSetting.get("state").asText();
				if(state.equals("true")){
					JsonNode json1 = null;
					try {
						json1 = JsonUtil.toJsonNode(dingSetting.get("value"));
					} catch (IOException e) {
						e.printStackTrace();
					}
//					cn.hutool.json.JSONObject json1= new cn.hutool.json.JSONObject(dingSetting.get("value"));
					dingAgentId= json1.get("dingAgentId").asText();
					dingCorpId=json1.get("dingCorpId").asText();
				}

			}
			JsonNode jsonTokenOld=uCFeignService.getDingToken(orgId,"0");
			if(jsonTokenOld.get("state").asBoolean()){
				dingToken=jsonTokenOld.get("token").asText();
			}
		}
		if(BeanUtils.isNotEmpty(dingtalkIds)&&BeanUtils.isNotEmpty(dingToken)){
			sendDingMessage(dingtalkIds,dingAgentId,msgTemplate,jmsMessage,dingToken,dingCorpId);

			sendDingTodoTask(dingtalkIds,dingAgentId,msgTemplate,jmsMessage,dingToken,userDingUnionId,orgId,dingCorpId);
		}
	}
	/**
	 * @description  发送钉钉工作通知
	 * @author  yangzibin
	 * @date    2024/3/19 14:02
	 * @param	dingtalkIds
	 * @param	dingAgentId
	 * @param	msgTemplate
	 * @param	jmsMessage
	 * @param	dingToken
	 * @return  void
	 */
	private void sendDingMessage(String dingtalkIds,String dingAgentId,MsgTemplate msgTemplate,JmsMessage jmsMessage,String dingToken,String dingCorpId){

		Map<String,Object> mapParams=jmsMessage.getExtendVars();
		String senderId= (String) mapParams.get("senderId");//发送人id
		String taskSubject=(String) mapParams.get("taskSubject");//任务标题
		String taskId=(String) mapParams.get("taskId");//任务Id
		String processDefId= (String) mapParams.get("processDefId_");//1769666375558746112
		String instanceId= (String) mapParams.get("instanceId_");//1769987483226984448

		DingTalkClient client = new DefaultDingTalkClient(DingTalkConsts.getMsgSendUrl());
		OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
		req.setAgentId(Long.valueOf(dingAgentId));
		req.setUseridList(dingtalkIds);
		Msg msg = new Msg();
		msg.setMsgtype("oa");
		msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
		msg.getOa().setHead(new OapiMessageCorpconversationAsyncsendV2Request.Head());
		msg.getOa().getHead().setText("eip审批");
		msg.getOa().setBody(new OapiMessageCorpconversationAsyncsendV2Request.Body());
		msg.getOa().getBody().setContent(taskSubject);
		req.setMsg(msg);
		String url = dingPcTodoUrl+"?taskId="+taskId+"&instId="+instanceId+"&corpId="+dingCorpId;
		String result = url + "&ddtab=true";
		result = "dingtalk://dingtalkclient/page/link?url=" + URLEncoder.encode(result);
		msg.getOa().setPcMessageUrl(result);
		String mobilurl = dingAppTodoUrl+"/home?taskId="+taskId+"&instId="+instanceId+"&corpId="+dingCorpId;
		msg.getOa().setMessageUrl(mobilurl);

		req.setMsg(msg);
		try {
			OapiMessageCorpconversationAsyncsendV2Response rsp1 = client.execute(req, dingToken);
			System.out.println(rsp1.getBody());
			//rsp: {"errcode":0,"task_id":211776512894,"request_id":"6ov1uwi1x0lg"}
			OapiMessageCorpconversationAsyncsendV2Response rsp = new OapiMessageCorpconversationAsyncsendV2Response();
			rsp.setErrcode(0L);
			rsp.setMessage("模拟钉钉消息发送");
			messageLogManager.handLogByMsgHander(jmsMessage, rsp.isSuccess(), JsonUtil.toJson(rsp));
			logger.error(JsonUtil.toJson(rsp));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * @description  发送待办任务
	 * @author  yangzibin
	 * @date    2024/3/19 14:04
	 * @param	dingtalkIds
	 * @param	dingAgentId
	 * @param	msgTemplate
	 * @param	jmsMessage
	 * @param	dingToken
	 * @return  void
	 */
	private void sendDingTodoTask(String dingtalkIds,String dingAgentId,MsgTemplate msgTemplate,JmsMessage jmsMessage,String dingToken,String userDingUnionId,String orgId,String dingCorpId){
		com.aliyun.dingtalktodo_1_0.Client client = null;
		try {
			client = createClient();
		} catch (Exception e) {
			e.printStackTrace();
		}
		CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
		createTodoTaskHeaders.xAcsDingtalkAccessToken = dingToken;


		Map<String,Object> mapParams=jmsMessage.getExtendVars();
		String senderId= (String) mapParams.get("senderId");//发送人id
		String taskSubject=(String) mapParams.get("taskSubject");//任务标题
		String taskId=(String) mapParams.get("taskId");//任务Id
		String processDefId= (String) mapParams.get("processDefId_");//1769666375558746112
		String instanceId= (String) mapParams.get("instanceId_");//1769987483226984448
		try {
			List<ObjectNode>   nodeList=bpmRuntimeFeignService.getDataByDefId(processDefId);
			System.out.println(nodeList.size());
		} catch (Exception e) {
			e.printStackTrace();
		}
		String mobilurl = dingAppTodoUrl+"/home?taskId="+taskId+"&instId="+instanceId+"&corpId="+dingCorpId;
		String url = dingPcTodoUrl+"?taskId="+taskId+"&instId="+instanceId+"&corpId="+dingCorpId;

		String result = url + "&ddtab=true";
		result = "dingtalk://dingtalkclient/page/link?url=" + URLEncoder.encode(result);
		CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
				.setDingNotify("1");
		CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
				.setAppUrl(mobilurl)
				.setPcUrl(result);

		CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
				.setOperatorId(userDingUnionId)//当前操作者用户的unionId
				.setSourceId(taskId+dingtalkIds)//业务id
				.setSubject(taskSubject)//待办标题
				.setCreatorId(userDingUnionId)//创建者的unionId。
//				.setDescription("待办备注描述，最大长度4096。")
//				.setDueTime(1617675000000L)//截止时间
				.setExecutorIds(java.util.Arrays.asList(
						userDingUnionId
				))//执行者iunionId
				.setParticipantIds(java.util.Arrays.asList(
						userDingUnionId
				))//参与者iunionId
				.setDetailUrl(detailUrl)
				.setIsOnlyShowExecutor(true)//生成的待办是否仅展示在执行者的待办列表中。
				.setPriority(20)//优先级 10=较低 20=普通 30=紧急 40=非常紧急
				.setNotifyConfigs(notifyConfigs);//通知配置，是否发钉

		try {
			CreateTodoTaskResponse resultRsp= client.createTodoTaskWithOptions(userDingUnionId, createTodoTaskRequest, createTodoTaskHeaders, new RuntimeOptions());
			cn.hutool.json.JSONObject jsonObject= new cn.hutool.json.JSONObject(resultRsp.getBody());
			if(jsonObject!=null){
				messageLogManager.handLogByMsgHander(jmsMessage, true, JsonUtil.toJson(resultRsp.getBody()));
				String dingTodoTaskId= (String) jsonObject.get("id");
				PortalDingTodoTask taskEntity=new PortalDingTodoTask();
				taskEntity.setCreateTime(LocalDateTime.now());
				taskEntity.setDingTodoTaskId(dingTodoTaskId);
				taskEntity.setDingUserId(dingtalkIds);
				taskEntity.setDingUserUnionId(userDingUnionId);
				taskEntity.setTodoTaskId(taskId);
				taskEntity.setOrgId(orgId);
				portalDingTodoTaskService.save(taskEntity);
			}else{
				messageLogManager.handLogByMsgHander(jmsMessage, false, JsonUtil.toJson(resultRsp.getBody()));
				logger.error(JsonUtil.toJson(resultRsp.getBody()));
			}

		} catch (TeaException err) {
			err.printStackTrace();

			if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
				// err 中含有 code 和 message 属性，可帮助开发定位问题
				messageLogManager.handLogByMsgHander(jmsMessage, false, err.message);
				logger.error(err.message);
			}

		} catch (Exception _err) {
			_err.printStackTrace();
			TeaException err = new TeaException(_err.getMessage(), _err);
			if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
				// err 中含有 code 和 message 属性，可帮助开发定位问题
				messageLogManager.handLogByMsgHander(jmsMessage, false, err.message);
				logger.error(err.message);
			}

		}
	}
	/**
	 * 使用 Token 初始化账号Client
	 * @return Client
	 * @throws Exception
	 */
	public static com.aliyun.dingtalktodo_1_0.Client createClient() throws Exception {
		Config config = new Config();
		config.protocol = "https";
		config.regionId = "central";
		return new com.aliyun.dingtalktodo_1_0.Client(config);
	}

}
