package org.springblade.modules.resource.builder.sms.client;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.qcloudsms.SmsMultiSenderResult;
import org.springblade.core.sms.model.SmsData;
import org.springblade.core.sms.model.SmsResponse;
import org.springblade.core.sms.props.SmsProperties;
import org.springblade.core.tool.utils.StringUtil;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author: lianghanqiang
 * @description: 华为短信请求客户端
 * @since: 8/25/21 -- 4:02 PM
 */
public class HwClient {


	//短信配置
	private SmsProperties smsProperties;
	//无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
	private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";
	//无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
	private static final String AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"";
	//必填,请参考"开发准备"获取如下数据,替换为实际值
	private static final String url = "https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1"; //APP接入地址+接口访问URI

	public HwClient(SmsProperties smsProperties){
		this.smsProperties = smsProperties;
	}

	/**
	 * 	发送短信
	 * @return*/
	public SmsResponse  sendMessage(Collection<String> receiver, SmsData smsData){
		HttpResponse res = HttpRequest.post(url)
			.header(buildHeader())
			.body(buildRequestBody(
				smsProperties.getRegionId(),
				Convert.toStr(receiver).replace("[","").replace("]",""),
				smsProperties.getTemplateId(),
				fetchParams(smsData),
				"",
				smsProperties.getSignName()))
			.execute();
		JSONObject resObj = JSON.parseObject(res.body());
		System.out.println("华为云短信返回："+resObj.toString());
		return new SmsResponse(Objects.equals("000000",resObj.getString("code")), res.getStatus(), resObj.getString("description"));
	}

	/**
	 * 	封装短信参数
	 * @param smsData
	 * */
	private String fetchParams(SmsData smsData) {
		return JSON.toJSONString(smsData.getParams().values());
	}

	public static void main(String[] args) {
		System.out.println(Header.CONTENT_TYPE.getValue());
	}

	/**
	 * 	组装请求头
	 * */
	private Map<String,List<String>> buildHeader() {
		Map<String,List<String>> headers = new HashMap<>(8);
		headers.put(Header.CONTENT_TYPE.getValue(),Arrays.asList("application/x-www-form-urlencoded"));
		headers.put(Header.AUTHORIZATION.getValue(),Arrays.asList(AUTH_HEADER_VALUE));
		headers.put("X-WSSE",Arrays.asList(buildWsseHeader(smsProperties.getAccessKey(),smsProperties.getSecretKey())));
		return headers;
	}


	/**
	 * 构造请求Body体
	 * @param sender
	 * @param receiver
	 * @param templateId
	 * @param templateParas
	 * @param statusCallBack
	 * @param signature | 签名名称,使用国内短信通用模板时填写
	 * @return
	 */
	static String buildRequestBody(String sender, String receiver, String templateId, String templateParas,
								   String statusCallBack, String signature) {
		if (null == sender || null == receiver || null == templateId || sender.isEmpty() || receiver.isEmpty()
			|| templateId.isEmpty()) {
			System.out.println("buildRequestBody(): sender, receiver or templateId is null.");
			return null;
		}
		Map<String, String> map = new HashMap<String, String>();

		map.put("from", sender);
		map.put("to", receiver);
		map.put("templateId", templateId);
		if (null != templateParas && !templateParas.isEmpty()) {
			map.put("templateParas", templateParas);
		}
		if (null != statusCallBack && !statusCallBack.isEmpty()) {
			map.put("statusCallback", statusCallBack);
		}
		if (null != signature && !signature.isEmpty()) {
			map.put("signature", signature);
		}

		StringBuilder sb = new StringBuilder();
		String temp = "";

		for (String s : map.keySet()) {
			try {
				temp = URLEncoder.encode(map.get(s), "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			sb.append(s).append("=").append(temp).append("&");
		}

		return sb.deleteCharAt(sb.length()-1).toString();
	}

	/**
	 * 构造X-WSSE参数值
	 * @param appKey
	 * @param appSecret
	 * @return
	 */
	static String buildWsseHeader(String appKey, String appSecret) {
		if (null == appKey || null == appSecret || appKey.isEmpty() || appSecret.isEmpty()) {
			System.out.println("buildWsseHeader(): appKey or appSecret is null.");
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
		String time = sdf.format(new Date()); //Created
		String nonce = UUID.randomUUID().toString().replace("-", ""); //Nonce

		MessageDigest md;
		byte[] passwordDigest = null;

		try {
			md = MessageDigest.getInstance("SHA-256");
			md.update((nonce + time + appSecret).getBytes());
			passwordDigest = md.digest();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		//如果JDK版本是1.8,请加载原生Base64类,并使用如下代码
		String passwordDigestBase64Str = Base64.getEncoder().encodeToString(passwordDigest); //PasswordDigest
		//如果JDK版本低于1.8,请加载三方库提供Base64类,并使用如下代码
		//String passwordDigestBase64Str = Base64.encodeBase64String(passwordDigest); //PasswordDigest
		//若passwordDigestBase64Str中包含换行符,请执行如下代码进行修正
		//passwordDigestBase64Str = passwordDigestBase64Str.replaceAll("[\\s*\t\n\r]", "");
		return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
	}
}
