//QUICK
var https = require('https');
var http = require('http');
var mysql = require('mysql');
var config = require('../../pay/config');
var crypto = require('crypto');
var qs = require('querystring');
var checkorder = require('../checkorder');
var url = require('url');

var xml2js = require('xml2js');
var parser = new xml2js.Parser();   //xml -> json
var builder = new xml2js.Builder(); // JSON->xml

//md5加密
var md5 = function (str){
	var md5sum = crypto.createHash('md5');
	md5sum.update(str);
	str = md5sum.digest('hex');
	return str;
};

//quick解密操作
function stringToBytes (str) {
	var ch, st, re = [];  
  	for (var i = 0; i < str.length; i++ ) {
    	ch = str.charCodeAt(i);
    	st = []; 
    	do {  
      		st.push( ch & 0xFF );
      		ch = ch >> 8;
    	}while ( ch );  
    	re = re.concat( st.reverse() );  
	}  
  	return re;  
} 

function bytesToString(array) {
  return String.fromCharCode.apply(String, array);
}

//将quick的加密文件解密成XML文件
function decode(str,key){
	if(str.length <= 0){
		return '';
	}

	var list = new Array();
	var resultMatch = str.match(/\d+/g);
	for(var i= 0;i<resultMatch.length;i++){
		list.push(resultMatch[i]);
	}

	if(list.length <= 0){
		return '';
	}
	
	var keysByte = stringToBytes(key);
	var dataByte = new Array();
	for(var i = 0 ; i < list.length ; i++){
		dataByte[i] = parseInt(list[i]) - (0xff & parseInt(keysByte[i % keysByte.length]));
	}

	if(dataByte.length <= 0){
		return '';
	}

	var parseStr = bytesToString(dataByte);
	return parseStr;
}

//充值成功的时候修改库中数据
var sql_update_quick = function(order_no,timestamp,flag,ordermoney,cfida,platform,channel,payment_type,moneytype,sdcustomno){  
	//填充充值信息				
	 var sql_2 = "UPDATE payinfo SET channel_order_id=?,overtime=?,flag=?,money=?,cfid=?,platform=?,channel=?,payment_type=?,moneytype=?,talkingdata=? WHERE orderid=? AND flag=2";
	 var timestamp = Date.parse(new Date()) / 1000;
	 var cfid = ordermoney; 
	 var values_2 = [order_no,timestamp,1,ordermoney,cfida,platform,channel,payment_type,moneytype,1,sdcustomno];
	 var sql = mysql.format(sql_2, values_2);
	 return sql;
 }
 
exports.quick_pay_success = function(args,query,res,quick_proto){
	var obj = qs.parse(args);
	var nt_data = obj.nt_data;  				//通知数据(XML格式)
	var sign = obj.sign;        				//签名串
	var md5Sign = obj.md5Sign;  				//string 签名计算方法为MD5
	var outputname = quick_proto.outputname 	//使用quick的渠道
	var callback_key = quick_proto.callback_key //quick解密编码
	var md5_key = quick_proto.md5_key			//MD5加密编码
	console.log(outputname+"quick回调来了");

	//将加密文件解密成XML文件
	var xml = decode(nt_data,callback_key);
	console.log(xml);

    //解析xml文件转json
	parser.parseString(xml, function (err, result)
	{
		if (err)
		{
			console.log("err:%s",err);
			try{res.send("FAILED");}
			catch(e){}
		}
		else
		{
			var aa = JSON.stringify(result);
			var dat_js = JSON.parse(aa);

			var jsons = dat_js.quicksdk_message.message[0];
			var nt_dat_js = jsons;

			var is_test = nt_dat_js.is_test[0];			//是否为测试订单 1为测试 0为线上正式订单
			console.log("is_test:%s",is_test);
			var pay_channel = nt_dat_js.channel[0];		//渠道标示ID
			var channel_uid = nt_dat_js.channel_uid[0];	//渠道用户唯一标示,该值从客户端GetUserId()中可获取
			var game_order = nt_dat_js.game_order[0];	//游戏在调用QucikSDK发起支付时传递的游戏方订单,这里会原样传回
			var order_no = nt_dat_js.order_no[0];		//QuickSDK唯一订单号
			var pay_time = nt_dat_js.pay_time[0];		//支付时间
			var amount = nt_dat_js.amount[0];			//成交金额，单位元
			var status = nt_dat_js.status[0];			//充值状态 0成功 1失败(为1时 应返回FAILED失败)
			var extras_params = nt_dat_js.extras_params[0];//额外参数，现在使用的配置sid
			console.log("status:%s",status);

			if (status==1)
			{
				try{
					console.log(outputname+"quick支付失败，state=%s",status);
					var sql = "UPDATE payinfo SET flag=? WHERE orderid=?";
					var values = [-2,game_order]; //玩家获取了订单，但是支付失败，因此把flag设置为-2
					sql = mysql.format(sql, values);
					query(sql,function(_qerr,_vals,_fields){});			
				}catch(err){}
				try{res.send("FAILED");}
				catch(e){}
                return
			}
			else
			{
			    try{
					var sql_1 = mysql.format("SELECT * FROM payinfo where orderid=?", [game_order]);//在mysql库中检查订单号
					query(sql_1,function(qerr,vals,fields_)
					{
						console.log("quick_pay_success,1");
						if(qerr){
							//"逻辑错误，请检查数据表结构和sql语句"
							console.log(outputname+"quick逻辑错误，请检查数据表结构和sql语句");
							try{res.send("FAILED");}
							catch(e){}
							return;
						}

						if (vals[0]==null){
							console.log(outputname+"quick没有找到该订单");
							try{res.send("FAILED");}
							catch(e){}
							return;
						}

						if (vals[0].overtime>0){
							console.log(outputname+"quick已经处理的订单");
							try{res.send("SUCCESS");}
							catch(e){}
							return;
						}

						var genSign = md5(nt_data+sign+md5_key);
                        if(md5Sign != genSign){
							console.log(outputname+"quick支付签名验证失败,md5Sign:%s,genSign:%s",md5Sign,genSign);
							try{res.send("FAILED");}
							catch(e){}
                            return;
                        }

                        //var des = "null";//描述订单支付成功或失败的系统备注
						var platform = 'android';					// 只存储 ios 和 android
						var channel = quick_proto.channel;			// 只存储 qianxun、zaya、limayao, zhangyu, friday, wudiyongshi, banli, zhiyu, cloud
						var payment_type = pay_channel.toString();	// 具体的子渠道，比如 quick 的 微信、手Q、UC、应用宝等， 新增一个 paymentType 字段来填充
                        var timestamp = Date.parse(new Date()) / 1000;
						var option = config.parse(platform,channel,extras_params)//extras_params
                        var cfid = option.cfid//config.quick_dollar(parseInt(amount));//购买商品ID--parseInt转int
                        if (cfid == 0){
                            console.log(outputname+"QUICK获取cfid失败为:%s,extras_params:%s", cfid,extras_params);
                            try{res.send("FAILED");}
                            catch(e){}
                            return;
						}

						if (amount != option.price){
                            console.log(outputname+"QUICK金额不一致为amount:%s,option.price:%s", amount,option.price);
                            try{res.send("FAILED");}
                            catch(e){}
                            return;
						}
	
                        var sql_2 = sql_update_quick(order_no,timestamp,1,amount,cfid,platform,channel,payment_type,option.typename,game_order)
                        query(sql_2,function(qerr,rows,fields_)
                        {
                            if (qerr){
                                console.log(qerr);
                                try{res.send("FAILED");} //"逻辑错误，请检查数据表结构和sql语句"}
                                catch(e){}
                                return;
                            }
                            
                            if (rows.affectedRows <= 0){//判断修改了多少个记录
							    console.log(outputname+"quick已经处理的订单");
                                try{res.send("SUCCESS");}
                                catch(e){}
                                return;
                            }

                            console.log(outputname+"quick支付成功了，现在通知游戏服务器, game_order:%s, username:%s, playerid:%s, serverid:%s ,cfid:%s",
                            game_order,vals[0].username,vals[0].playerid,vals[0].serverid,cfid);
                            //send_2_game(query,game_order,vals[0].username,vals[0].playerid,vals[0].serverid,cfid, function(ok){
							checkorder.pushproduct(query,game_order,vals[0].uid,vals[0].serverid,cfid, function(ok){
                                    if (ok) {
                                        console.log(outputname+"QUICK 订单 %s: 成功发货!", game_order);
                                        try{res.send("SUCCESS");}
                                        catch(e){}
                                    } else{
                                        console.log(outputname+"QUICK 订单 %s: 发货地址无效!", game_order);
                                        try{res.send("FAILED");}
                                        catch(e){}
                                    }
                                });

							// 向 TalkingData 报告充值数据
							var appId = config.getAppID(channel);
							checkorder.pushtalkingdata(query,appId,platform,vals[0].uid,game_order,option.price,option.typename,option.diamond,timestamp,payment_type,vals[0].serverid);
							
                        })
					});
				}catch(err){
					console.log(outputname+"quick_err ,%s",err);
					try{res.send("FAILED");}
					catch(e){}
				}
			}
		}
	})
}