package com.iamberry.wechat.tools;

import java.util.SortedMap;
import java.util.TreeMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.iamberry.app.tool.des.MD5;
import com.iamberry.app.tool.log.RatFWLogger;


/**
 * 支付核心类
 */
@Component
public class WxPayUtil {
	//微信支付商户开通后 微信会提供appid和appsecret和商户号partner
	public String appid = NameUtils.appId;
	public String appsecret = NameUtils.appSecret;
	public String partner = NameUtils.partner;
	//这个参数partnerkey是在商户后台配置的一个32位的key,微信商户平台-账户设置-安全设置-api安全
	public String partnerkey = NameUtils.partnerkey;
	//public static String openId = "oE5vNvk_xqtNgDORneoz3b6Dw7RU";
	//微信支付成功后通知地址 必须要求80端口并且地址不能带参数
//	public static String notifyurl = "http://wx.jiancat.com/goods/order/notifyPay";
	//ip地址
	public String ipAddress = NameUtils.ipAddress;
	
	@Autowired
	private MD5 md5;
	@Autowired
	private RatFWLogger inLongLogger;
	@Autowired
	private RequestHandler reqHandler;
	@Autowired
	private GetWxOrderno getWxOrderno;

	public void setMd5(MD5 md5) {
		this.md5 = md5;
	}
	public void setGetWxOrderno(GetWxOrderno getWxOrderno) {
		this.getWxOrderno = getWxOrderno;
	}
	public void setReqHandler(RequestHandler reqHandler) {
		this.reqHandler = reqHandler;
	}
	public void setInLongLogger(RatFWLogger inLongLogger) {
		this.inLongLogger = inLongLogger;
	}
	
	public static void main(String[] args) {
		WxPayUtil payUtil = new WxPayUtil();;
		System.out.println(payUtil.getPackage("o-icas1BDo7PxGMZgcFpL12jL-A4", "1rsjklsjflasjf", 1, NameUtils.ipAddress, "测试的飞机是多久", NameUtils.appId, NameUtils.GET_OPENID_DEAL_URL));
	}
	
	/**
	 * 获取微信扫码支付二维码连接
	 */
	public String getCodeurl(WxPayDto tpWxPayDto, String notifyurl){
		// 1 参数
		// 订单号
		String orderId = tpWxPayDto.getOrderId();
		// 附加数据 原样返回
		String attach = "";
		// 总金额以分为单位，不带小数点
		String totalFee = getMoney(tpWxPayDto.getTotalFee());
		
		// 订单生成的机器 IP
		String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url = notifyurl;
		String trade_type = "NATIVE";

		// 商户号
		String mch_id = this.partner;
		// 随机字符串
		String nonce_str = getNonceStr();

		// 商品描述根据情况修改
		String body = tpWxPayDto.getBody();

		// 商户订单号
		String out_trade_no = orderId;

		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid);
		packageParams.put("mch_id", mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		packageParams.put("attach", attach);
		packageParams.put("out_trade_no", out_trade_no);

		// 这里写的金额为1 分到时修改
		packageParams.put("total_fee", totalFee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);

		packageParams.put("trade_type", trade_type);

		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(appid, appsecret, partnerkey);

		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>"
				+ mch_id + "</mch_id>" + "<nonce_str>" + nonce_str
				+ "</nonce_str>" + "<sign>" + sign + "</sign>"
				+ "<body><![CDATA[" + body + "]]></body>" 
				+ "<out_trade_no>" + out_trade_no
				+ "</out_trade_no>" + "<attach>" + attach + "</attach>"
				+ "<total_fee>" + totalFee + "</total_fee>"
				+ "<spbill_create_ip>" + spbill_create_ip
				+ "</spbill_create_ip>" + "<notify_url>" + notify_url
				+ "</notify_url>" + "<trade_type>" + trade_type
				+ "</trade_type>" + "</xml>";
		String code_url = "";
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		
		
		code_url = new GetWxOrderno().getCodeUrl(createOrderURL, xml);
//System.out.println("code_url----------------"+code_url);
		
		return code_url;
	}
	
	
	/**
	 * 获取请求预支付id报文
	 * @return
	 */
	@SuppressWarnings("static-access")
	public Object getPackage(
			String openid, 
			String orderid, 
			Integer total, 
			String ip, 
			String bodyStr,
			String appIdStr,
			String notifyurl) {
		
System.out.println("getPackage start....");
		
		String openId = openid;
		// 1 参数
		// 订单号
		String orderId = orderid;
		// 附加数据 原样返回,此处对订单idMD5加密
		
		String attach = null;
		try {
			attach = StaticInfo.orderIdMD5.encrypt(orderid);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 总金额以分为单位，不带小数点
		String totalFee = total.toString(); 
				//getMoney(total);
		// 订单生成的机器 IP
		String spbill_create_ip = ip;
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url = notifyurl;
		String trade_type = "JSAPI";
		// ---必须参数
		// 商户号
		String mch_id = partner;
		// 随机字符串
		String nonce_str = getNonceStr();
		// 商品描述根据情况修改
		String body = bodyStr;
		// 商户订单号
		String out_trade_no = orderId;
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appIdStr);
		packageParams.put("mch_id", mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		packageParams.put("attach", attach);
		packageParams.put("out_trade_no", out_trade_no);
		// 这里写的金额为1 分到时修改
		packageParams.put("total_fee", totalFee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);
		packageParams.put("trade_type", trade_type);
		packageParams.put("openid", openId);
		reqHandler.init(appid, appsecret, partnerkey);
		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>"
					+ "<appid>" + appid + "</appid>" 
					+ "<mch_id>" + mch_id + "</mch_id>" 
					+ "<nonce_str>" + nonce_str + "</nonce_str>" 
					+ "<sign>" + sign + "</sign>"
					+ "<body><![CDATA[" + body + "]]></body>" 
					+ "<out_trade_no>" + out_trade_no + "</out_trade_no>" 
					+ "<attach>" + attach + "</attach>"
					+ "<total_fee>" + totalFee + "</total_fee>"
					+ "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" 
					+ "<notify_url>" + notify_url + "</notify_url>" 
					+ "<trade_type>" + trade_type + "</trade_type>" 
					+ "<openid>" + openId + "</openid>"
				+ "</xml>";
		String prepay_id = "";
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		//判断
		Object string = getWxOrderno.getPayNo(createOrderURL, xml);
		if (string.getClass() == String.class) {
			prepay_id = string.toString();
		} else {
			WxPrepayIdErrorResult errorResult = (WxPrepayIdErrorResult) string;
			if (errorResult.getErr_code_des() != null && errorResult.getErr_code_des().equals("商户订单号重复")) {
				// 最大的可能意味着，此订单的金额发生改变
				errorResult.setErr_code_des("对不起，您的订单号重复，请重新下单!");
			} else {
				errorResult.setErr_code_des(errorResult.getReturn_msg());
			}
			return errorResult;
		}
		//获取prepay_id后，拼接最后请求支付所需要的package
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		String timestamp = Sha1Util.getTimeStamp();
		String packages = "prepay_id="+prepay_id;
		finalpackage.put("appId", appid);  
		finalpackage.put("timeStamp", timestamp);  
		finalpackage.put("nonceStr", nonce_str);  
		finalpackage.put("package", packages);  
		finalpackage.put("signType", "MD5");
		//签名
		String finalsign = reqHandler.createSign(finalpackage);
		String finaPackage = "\"appId\":\"" + appid + "\",\"timeStamp\":\"" + timestamp + "\",\"nonceStr\":\"" + nonce_str + "\",\"package\":\"" + packages + "\",\"signType\":\"MD5" + "\",\"paySign\":\"" + finalsign + "\"";
		return finaPackage;
	}

	/**
	 * 获取随机字符串
	 * @return
	 */
	public static String getNonceStr() {
		// 随机数
		String currTime = TenpayUtil.getCurrTime();
		// 8位日期
		String strTime = currTime.substring(8, currTime.length());
		// 四位随机数
		String strRandom = TenpayUtil.buildRandom(4) + "";
		// 10位序列号,可以自行调整。
		return strTime + strRandom;
	}

	/**
	 * 元转换成分
	 * @param money
	 * @return
	 */
	public static String getMoney(String amount) {
		if(amount==null){
			return "";
		}
		// 金额转化为分为单位
		String currency =  amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额  
        int index = currency.indexOf(".");  
        int length = currency.length();  
        Long amLong = 0l;  
        if(index == -1){  
            amLong = Long.valueOf(currency+"00");  
        }else if(length - index >= 3){  
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));  
        }else if(length - index == 2){  
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);  
        }else{  
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");  
        }  
        return amLong.toString(); 
	}
}
