package com.winsun.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.winsun.auth.core.base.controller.BaseController;
import com.winsun.bean.YxtCoupon;
import com.winsun.bean.YxtOrder;
import com.winsun.bean.YxtOrderDetail;
import com.winsun.bean.YxtSalesLimit;
import com.winsun.mapper.YxtCouponMapper;
import com.winsun.mapper.YxtOrderDetailMapper;
import com.winsun.mapper.YxtOrderMapper;
import com.winsun.mapper.YxtSalesLimitMapper;
import com.winsun.utils.HTTPSClient;
import com.winsun.utils.WXPayUtil;
import com.winsun.utils.WxInterfacesUtil;
import com.winsun.utils.XmlParser;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 院线通销售Controller
 * @author 董有沛
 * @date  2018年1月22日 
 *
 */
@Slf4j
@RestController
@RequestMapping("/wxpay") //
public class YxtWxPayController extends BaseController {

	@Autowired
	private YxtOrderMapper yxtOrderMapper;
	@Autowired
	private YxtCouponMapper yxtCouponMapper;
	@Autowired
	private YxtSalesLimitMapper yxtSalesLimitMapper;
	@Autowired
	private YxtOrderDetailMapper yxtOrderDetailMapper;

	@Autowired
	private RedisTemplate redisTemplate;

	public static Lock lock = new ReentrantLock();
	
	// 公众号支付异步回调
	@RequestMapping(value = "/payNotify",method = {RequestMethod.GET, RequestMethod.POST})
	@ResponseBody
	public void payNotify(HttpServletResponse response, HttpServletRequest request){

		// 加入同步锁，防止重复操作导致数据紊乱
		lock.lock();

		try {
			InputStream in = request.getInputStream();
			Map<String, String> map = XmlParser.xmlToMap(in);
			Map<String, String> respMap = new HashMap<>();

			// 通信标识为SUCCESS，则会返回其它参数
			if("SUCCESS".equals(map.get("return_code"))){
				String sign = map.get("sign");
				// 统一下单加密参数
				SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
				parameters.put("appid", map.get("appid"));
				parameters.put("mch_id", map.get("mch_id"));
				parameters.put("nonce_str", map.get("nonce_str"));
				parameters.put("out_trade_no", map.get("out_trade_no"));
				parameters.put("total_fee",map.get("total_fee"));
				parameters.put("trade_type", map.get("trade_type"));
				parameters.put("openid", map.get("openid"));
				parameters.put("is_subscribe", map.get("is_subscribe"));
				parameters.put("fee_type", map.get("fee_type"));
				parameters.put("transaction_id", map.get("transaction_id"));
				parameters.put("result_code", map.get("result_code"));
				parameters.put("time_end", map.get("time_end"));
				parameters.put("bank_type", map.get("bank_type"));
				parameters.put("return_code", map.get("return_code"));
				parameters.put("cash_fee", map.get("cash_fee"));
				String newSign = WXPayUtil.createSign("UTF-8", parameters);

				// 验证支付结果签名
				if(null != newSign && sign.equals(newSign)){

					String orderNumber = map.get("out_trade_no");  // 获取订单号
					Wrapper<YxtOrder> orderWrapper = new EntityWrapper<>();
					orderWrapper.eq("order_num",orderNumber);
					List<YxtOrder> list = yxtOrderMapper.selectList(orderWrapper);

					// 检查该订单号是不是创建
					if(list.size()>0){
						YxtOrder yxtOrder = list.get(0);
						double totalPrice = yxtOrder.getTotalPrice() * 100;
						double totalFee =  Double.parseDouble(map.get("total_fee").toString());

						if(totalPrice <= totalFee+1){
							// 订单状态未修改，则修改
							if(!"2".equals(yxtOrder.getState().toString())){
								Wrapper<YxtOrder> wrapper = new EntityWrapper<>();
								orderWrapper.eq("order_num",orderNumber);
								orderWrapper.eq("del_flag",0);
								YxtOrder yxtOrder1 = new YxtOrder();
								yxtOrder1.setWxOrderNum(map.get("transaction_id"));
								yxtOrder1.setState(2);
								int num = yxtOrderMapper.update(yxtOrder1,wrapper);
								if("电子订单".equals(yxtOrder.getOrderType())){
									if(num > 0){
										// 更新兑换券状态
										Wrapper<YxtOrderDetail> orderDetailWrapper = new EntityWrapper<>();
										orderDetailWrapper.eq("order_id",yxtOrder.getId());
										List<YxtOrderDetail> orderDetails = yxtOrderDetailMapper.selectList(orderDetailWrapper);
										if(!(orderDetails.size()>0)){
											log.info("查找销售订单详情无数据！！！");
										}
										List<Integer> list1 = new ArrayList<>();
										for (YxtOrderDetail orderDetail : orderDetails) {
											list1.add(orderDetail.getYxtId());
										}
										Wrapper<YxtCoupon> couponWrapper = new EntityWrapper<>();
										couponWrapper.in("id",list1);
										List<YxtCoupon> couponList = yxtCouponMapper.selectList(couponWrapper);
										if(!(couponList.size()>0)){
											log.info("查找销售兑换券无数据！！！");
										}
										for (YxtCoupon coupon : couponList) {
											Wrapper<YxtCoupon> yxtCouponWrapper = new EntityWrapper<>();
											yxtCouponWrapper.eq("id",coupon.getId());
											yxtCouponWrapper.ne("state",2);
											YxtCoupon coupon1 = new YxtCoupon();
											coupon1.setState(2);
											yxtCouponMapper.update(coupon1,yxtCouponWrapper);
										}
										this.sendAccount(orderNumber,map.get("openid"));
										this.updateSalesLimit(orderNumber,map.get("openid"));
									}
								}
							}

							// 将应答结果返回给微信，让微信停止重复通知动作
							respMap.put("return_code", "SUCCESS");
							respMap.put("return_msg", "OK");
							String respStr = XmlParser.map2XmlString(respMap);
							log.info("  支付验证回调 ：" + new Date());

							response.getWriter().print(respStr);
						}else{
							log.info("回调接口：付款金额有误");
						}
					}else{
						log.info("回调接口：订单号异常");
					}
				}else{
					log.info("回调接口：支付结果签名验证失败！");
				}
			}else{
				log.info("回调接口：通信标识为FAIL");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	public void updateSalesLimit(String orderNumber,String openId){
		try{
			Wrapper<YxtOrder> yxtOrderWrapper = new EntityWrapper<>();
			yxtOrderWrapper.eq("order_num",orderNumber);
			List<YxtOrder> yxtOrderList = yxtOrderMapper.selectList(yxtOrderWrapper);

			Wrapper<YxtSalesLimit> yxtSalesLimitWrapper = new EntityWrapper<>();
			yxtSalesLimitWrapper.eq("open_id",openId);
			List<YxtSalesLimit> yxtSalesLimitList = yxtSalesLimitMapper.selectList(yxtSalesLimitWrapper);

			if(yxtOrderList.size() > 0){
				YxtOrder yxtOrder = yxtOrderList.get(0);
				int salesNum = yxtOrder.getGoodsNum();

				if(yxtSalesLimitList.size() > 0){
					YxtSalesLimit yxtSalesLimit = new YxtSalesLimit();
					yxtSalesLimit.setSalesNum(salesNum);
					Wrapper<YxtSalesLimit> limitEntityWrapper = new EntityWrapper<>();
					limitEntityWrapper.eq("open_id",openId);
					yxtSalesLimitMapper.update(yxtSalesLimit,limitEntityWrapper);
//					String sql = " update yx_yxt_sales_limit set sales_num = sales_num + "+ salesNum +",update_date = now() where open_id = '"+ openId +"' ";
//					jdbcTemplate.update(sql);
				}else{
					YxtSalesLimit yxtSalesLimit = new YxtSalesLimit();
					yxtSalesLimit.setSalesNum(salesNum);
					yxtSalesLimit.setOpenId(openId);
					yxtSalesLimit.setUpdateDate(new Date());
					yxtSalesLimitMapper.insert(yxtSalesLimit);
//					String sql = " insert into yx_yxt_sales_limit (open_id,sales_num,update_date) values('"+ openId +"',"+ salesNum +",now())  ";
//					jdbcTemplate.update(sql);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public void sendAccount(String orderNumber,String openId){

		try{
			String accessToken = WxInterfacesUtil.getAccessToken();
			String content = "";
			List<Map<String,Object>> list = yxtOrderMapper.getCardByNumber(orderNumber);
			
			for(int i=0; i<list.size(); i++){
				Map<String, Object> map = list.get(i);

				content += "账号："+ map.get("card_number") +"\n密码： "+ map.get("password") +"\n";
				
				if( (i+1) % 5 == 0 ){
					content += "请在15分钟内在院线通兑换，逾期有误，概不负责。";
					
					JSONObject object = new JSONObject();
					object.put("content", content);
					JSONObject obj = new JSONObject();
					obj.put("touser", openId);
					obj.put("msgtype", "text");
					obj.put("text", object);
					
					String dataStr = obj.toString();
					String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
					
					String result = HTTPSClient.sendPosts(url, dataStr);
					log.info(result);
					content = "";
				}else if(i+1 == list.size()){
					content += "请在15分钟内在院线通兑换，逾期有误，概不负责。";
					
					JSONObject object = new JSONObject();
					object.put("content", content);
					JSONObject obj = new JSONObject();
					obj.put("touser", openId);
					obj.put("msgtype", "text");
					obj.put("text", object);
					
					String dataStr = obj.toString();
					String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
					
					String result = HTTPSClient.sendPosts(url, dataStr);
					System.out.println(result);
					content = "";
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	
}
