package com.iamberry.wechat.handles.pay;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.xml.sax.InputSource;

import com.iamberry.app.tool.log.RatFWLogger;
import com.iamberry.wechat.core.entity.coupon.CouponItem;
import com.iamberry.wechat.core.entity.drp.PlaceInfo;
import com.iamberry.wechat.core.entity.drp.PlaceOrder;
import com.iamberry.wechat.core.entity.member.CashLog;
import com.iamberry.wechat.core.entity.member.Member;
import com.iamberry.wechat.core.entity.mq.MQMessage;
import com.iamberry.wechat.core.entity.order.Order;
import com.iamberry.wechat.core.entity.wx.WxPayResult;
import com.iamberry.wechat.face.cart.CartService;
import com.iamberry.wechat.face.coupon.CouponItemService;
import com.iamberry.wechat.face.drp.PlaceInfoService;
import com.iamberry.wechat.face.drp.PlaceOrderService;
import com.iamberry.wechat.face.member.CashLogService;
import com.iamberry.wechat.face.member.MemberService;
import com.iamberry.wechat.face.order.AdminOrderService;
import com.iamberry.wechat.face.qrcode.QrcodeService;
import com.iamberry.wechat.face.reback.RebackServices;
import com.iamberry.wechat.handles.mq.MQServiceProxy;
import com.iamberry.wechat.tools.StaticInfo;

/**
 * @author 何秀刚
 * Class Description: 微信支付回调handler,所有的支付回调，都在本类完成
 * Create Date:2016年4月19日
 * Update Date:2016年4月19日
 */
@Controller
@RequestMapping("/callback")
public class ResponseWechatPayHandler {

	@Autowired
	private RatFWLogger ratFWLogger;
	
	private Object lock = new Object();
	
	@Autowired
	private CartService cartService;
	
	@Autowired
	private PlaceOrderService placeOrderService;
	
	@Autowired
	private PlaceInfoService placeInfoService;
	
	@Autowired
	private MemberService memberService;

	
	
	@Autowired
	private AdminOrderService adminOrderService;
	
	@Autowired
	private MQServiceProxy mQservice;
	
	@Autowired
	private RebackServices rebackServices;
	
	@Autowired
	private QrcodeService qrcodeService;			//二维码处理
	
	@Autowired
	CashLogService cashLogService;
	@Autowired
	CouponItemService couponItemService;

	/**
	 * 销售订单支付回调方法
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping("/orderPayBack")
	public void orderPayBack(HttpServletRequest request, 
			HttpServletResponse response) throws IOException {
		synchronized (lock) {
			String inputLine;
			String notityXml = "";
			String resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
			try {
				//获取XML参数
				while ((inputLine = request.getReader().readLine()) != null) {
					notityXml += inputLine;
				}
				request.getReader().close();
				//解析XML格式的数据
				Map m = parseXmlToList2(notityXml);
				WxPayResult wpr = new WxPayResult();
				wpr=setWxPayResultObj(wpr,m);
				//判断
				if("SUCCESS".equalsIgnoreCase(wpr.getResultCode())){
					//resXml:返回给微信服务器的数据
					resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
					String orderIdMD5 = StaticInfo.orderIdMD5.decrypt(wpr.getAttach());
//System.out.println("===========pay 117==============");
					
					if (orderIdMD5.equals(wpr.getOutTradeNo())) {
						Date nowDate = new Date();
						// 组装数据
						Order order = new Order();
						order.setSalesOrderid(orderIdMD5);
						order.setSalesStatus(2); // 已支付
						order.setSalesTransactionId(wpr.getTransactionId()); // 微信支付ID
						order.setSalesTransactionDate(new Date()); // 微信支付时间
						order.setSalesOpenid(wpr.getOpenid());
						
						// 修改订单状态
						int count = cartService.updateOrderStatus(order);
						
//System.out.println("===========pay 132 修改订单状态==============");
						//修改优惠券状态
						order=cartService.selectOrderInfoById(order);
						
//System.out.println("===========pay 136 修改订单状态=============="+order.getSalesOrderid());
						String couponId=order.getCouponId();
						
						if(couponId!=null && !couponId.equals("")){
							CouponItem couponItem=new CouponItem();
							couponItem.setCouponItemId(couponId);
							couponItem.setCouponUseStatus(2);
							couponItem.setCouponUseDate(new Date());
							couponItemService.updateCouponItemById(couponItem);
						}
						//更新账户余额
						int balancePayAmount=order.getBalancePayAmount();
						if(balancePayAmount>0){
							Member member=new Member();
							member.setUserOpenid(order.getSalesOpenid());
							member.setUserIncome(-balancePayAmount);
							memberService.updateUserIncomeByOpenId(member);
							
							//现金使用记录
							CashLog log=new CashLog();
							log.setCashLogsIntroduction("订单支出");
							log.setCashLogsNum(balancePayAmount);
							log.setCashLogsOpenid(member.getUserOpenid());
							log.setCashLogsType(2);
							log.setCashLogsResType(3);
							log.setCashLogsOrderid(order.getSalesOrderid());
							log.setCashLogsCreateDate(nowDate);
							count=cashLogService.addCashLog(log);
						}
						if (count < 1) {
							resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
						}
//System.out.println("===========pay 168 快速插入=============="+count);
						// 给订单的回调修改状态
						try {
							MQMessage message = new MQMessage();
							message.setServiceToMessage(orderIdMD5);
							message.setServiceOtherMessage(wpr.getTransactionId());
							message.setServiceIsSend(2);			// 没有推送的信息
							message.setServiceStatus(1); 			// 推送成功
							message.setServiceHandlerObjectName("cartServiceImpl");
							message.setServiceHandlerMethodName("supdateStateByOrderId");
							message.setServiceType(1);
							mQservice.insertMQMessage(message);
						} catch (Exception e) {
							// TODO: handle exception
						}
//System.out.println("===========pay 182  插入返利到mq=============="+count);
						//rebackServices.loadSingleOrderReward(order);
						
						//添加到返利表
						//rebackServices.loadSingleOrderReward(order);
						// 给百胜推送信息
						try {
							MQMessage message = new MQMessage();
							message.setServiceToMessage(orderIdMD5);
							message.setServiceOtherMessage("efast.trade.new.add");
							message.setServiceIsSend(2);			// 没有推送的信息
							message.setServiceStatus(1); 			// 推送成功
							message.setServiceType(1); 				// 添加订单信息
							message.setServiceHandlerObjectName("efastOrderServiceImpl");
							message.setServiceHandlerMethodName("addOrderInfoToEfast");
							mQservice.insertMQMessage(message);
						} catch (Exception e) {
//System.out.println("===========pay 201  插入返利到百胜失败==============");		
						}
//System.out.println("===========pay 201  插入返利到百胜完成==============");		
						try {
							//给父节点推送返利消息
//							rewardsMessage(member,orderIdMD5);
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else {
						resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
						ratFWLogger.error(this, "订单:" + orderIdMD5 + "支付成功，但是没有通过校验!");
					}
				}else{
					resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
				}
				BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
				out.write(resXml.getBytes());
				out.flush();
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 销售订单支付回调方法
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping("/drpPayBack")
	public void drpPayBack(HttpServletRequest request, 
			HttpServletResponse response) throws IOException {
		synchronized (lock) {
			String inputLine;
			String notityXml = "";
			String resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
			try {
				//获取XML参数
				while ((inputLine = request.getReader().readLine()) != null) {
					notityXml += inputLine;
				}
				request.getReader().close();
				//解析XML格式的数据
				Map m = parseXmlToList2(notityXml);
				WxPayResult wpr = new WxPayResult();
				wpr=setWxPayResultObj(wpr,m);
				//判断
				if("SUCCESS".equalsIgnoreCase(wpr.getResultCode())){
					//resXml:返回给微信服务器的数据
					resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
					String orderIdMD5 = StaticInfo.orderIdMD5.decrypt(wpr.getAttach());
					if (orderIdMD5.equals(wpr.getOutTradeNo())) {
						PlaceOrder placeOrder=new PlaceOrder();
						placeOrder.setId(orderIdMD5);
						placeOrder.setStatus(2); //已付款
						 int count = placeOrderService.UpdateOrder(placeOrder);
						if (count < 1) {
							resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
						}
					} else {
						resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
						ratFWLogger.error(this, "订单:" + orderIdMD5 + "支付成功，但是没有通过校验!");
					}
				}else{
					resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
				}
				BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
				out.write(resXml.getBytes());
				out.flush();
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 解析xml片段为Map
	 * @param xml
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map parseXmlToList2(String xml) {
		Map retMap = new HashMap();
		try {
			StringReader read = new StringReader(xml);
			// 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
			InputSource source = new InputSource(read);
			// 创建一个新的SAXBuilder
			SAXBuilder sb = new SAXBuilder();

			// 防止XXE
			sb.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
			sb.setFeature("http://xml.org/sax/features/external-general-entities", false);
			sb.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
			sb.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

			// 通过输入源构造一个Document
			Document doc = (Document) sb.build(source);
			Element root = doc.getRootElement();// 指向根节点
			List<Element> es = root.getChildren();
			if (es != null && es.size() != 0) {
				for (Element element : es) {
					retMap.put(element.getName(), element.getValue());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return retMap;
	}
    
	//封装参数
	public WxPayResult setWxPayResultObj(WxPayResult wpr ,Map m){
		//解析参数
		wpr.setAppid(m.get("appid").toString());
		wpr.setBankType(m.get("bank_type").toString());
		wpr.setCashFee(m.get("cash_fee").toString());
		wpr.setFeeType(m.get("fee_type").toString());
		wpr.setIsSubscribe(m.get("is_subscribe").toString());
		wpr.setMchId(m.get("mch_id").toString());
		wpr.setNonceStr(m.get("nonce_str").toString());
		wpr.setOpenid(m.get("openid").toString());
		wpr.setOutTradeNo(m.get("out_trade_no").toString());
		wpr.setAttach(m.get("attach").toString());
		wpr.setResultCode(m.get("result_code").toString());
		wpr.setReturnCode(m.get("return_code").toString());
		wpr.setSign(m.get("sign").toString());
		wpr.setTimeEnd(m.get("time_end").toString());
		wpr.setTotalFee(m.get("total_fee").toString());
		wpr.setTradeType(m.get("trade_type").toString());
		wpr.setTransactionId(m.get("transaction_id").toString());
		return wpr;
	}
	
	/**
	 * 奖励提醒 下线成功购买后 提示直接上线
	 * create date 2016年5月14日
	 * @author 穆再兴
	 * @return
	 */
	private boolean rewardsMessage(Member member,String orderid){
		boolean result = false;
//		Integer i = cartService.getItemNumByOrderId(orderid);
//		if(i == null || i.intValue() == 0){return false;}
//		if(member == null || member.getUserResType() == null) return false;
//		
//		switch(member.getUserResType().intValue()){//用户来源
//			case 2:		//用户来源	微代理
////				if(member.getUserRefereeid() == null){return false;}
//				Member fatherMember = memberService.getMemberByUserId(member.getUserRefereeid());	//微代理父节点信息
//				if(fatherMember != null && StringUtils.isNotEmpty(fatherMember.getUserOpenid())){
//					String temp = ResultInfo.REWARDSREMINDTEMP;
//					temp = temp.replaceFirst("firstValueIamberry", ResultInfo.REWARDSWILLMESSAGE)
//						.replaceFirst("orderValueIamberry", orderid)
//						.replaceFirst("moneyValueIamberry", "￥" + new Integer(i.intValue() * 100).toString())
//						.replaceFirst("remarkValueIamberry", ResultInfo.INTOSHOP);
//					result = wxService.rewardsRemind(temp, fatherMember.getUserOpenid(), ResultInfo.INDEX_PAGE);
//				}
//				break;
//			case 3:		//用户来源	线下
////				if(member.getUserResOnline() == null ){return false;}
//				PlaceInfo fatherPlace = placeInfoService.getPlaceInfoById(member.getUserResOnline());//分销父节点信息
//				/*if(fatherPlace == null || fatherPlace.getPlaceRole() == 7){ return result; }*/
//				int num = getRewardsMoneyOfFather(fatherPlace);
//				if(num !=0 && StringUtils.isNotEmpty(fatherPlace.getOpenid())){
//					String temp = ResultInfo.REWARDSREMINDTEMP;
//					temp = temp.replaceFirst("firstValueIamberry", ResultInfo.REWARDSWILLMESSAGE)
//						.replaceFirst("orderValueIamberry", orderid)
//						.replaceFirst("moneyValueIamberry", "￥" + new Integer(i.intValue() * num / 100).toString())
//						.replaceFirst("remarkValueIamberry", ResultInfo.INTOSHOP);
//					result = wxService.rewardsRemind(temp, fatherPlace.getOpenid(), ResultInfo.INDEX_PAGE);
//				}
//				break;
//		}
		return result;
	}
	
	/**
	 * 获取 返给父节点的 金额
	 * create date 2016年5月14日
	 * @author 穆再兴
	 * @param fatherplace	父节点
	 * @return
	 */
	private int getRewardsMoneyOfFather(PlaceInfo fatherplace){
		if(fatherplace == null ){return 0;}
		return 0;
		/*ShopSystemRule ruleMoney = null;
		switch(fatherplace.getType()){	//父节点类型
		case 2:		//二级的角色
			if(fatherplace.getPlaceRole() == 7){ 			//角色：奶粉厂	每台机器返利100元
				ruleMoney = this.adminOrderService.getReluByRid(97);
				break;
			}else if(fatherplace.getPlaceRole() == 4){		//角色：特殊渠道管理员	每台机器返利140元
				ruleMoney = this.adminOrderService.getReluByRid(98);
				break;
			}
		case 3:		//三级的角色
			if(fatherplace.getPlaceRole() == 5){			//角色：导购	每台机器返利40元
				ruleMoney = this.adminOrderService.getReluByRid(96);
				break;
			}else if(fatherplace.getPlaceRole() == 6){		//角色：分销员	每台机器返利100元
				ruleMoney = this.adminOrderService.getReluByRid(97);
				break;
			}
		}
		if(ruleMoney == null){return 0;}
		return ruleMoney.getRuleNum() == null ? 0 : ruleMoney.getRuleNum().intValue();
	*/
	}
}
