package com.izouma.awesomeadmin.web;

import com.izouma.awesomeadmin.constant.AppConstant;
import com.izouma.awesomeadmin.dto.Result;
import com.izouma.awesomeadmin.dto.WxPaySendData;
import com.izouma.awesomeadmin.model.UserInfo;
import com.izouma.awesomeadmin.service.UserInfoService;
import com.izouma.awesomeadmin.service.UserOrderService;
import com.izouma.awesomeadmin.service.WeiXinService;
import com.izouma.awesomeadmin.shiro.WechatToken;
import com.izouma.awesomeadmin.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Controller
@RequestMapping("/wx")
public class WeiXinController {

    private static Logger logger = Logger.getLogger(WeiXinController.class);

    @Autowired
    private WeiXinService weiXinService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private UserOrderService userOrderService;

    @RequestMapping(value = "/auth", method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView auth(@RequestParam("redirectUri") String redirectUri) {
        if (StringUtils.isNotEmpty(redirectUri)) {
            redirectUri = Base64.getBase64(redirectUri);
        } else {
            redirectUri = "";
        }
        String wxRedirectUri = PropertiesFileLoader.getProperties("host")
                + "/wx/doAuth/" + redirectUri;
        return new ModelAndView("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                + PropertiesFileLoader.getProperties("weixinappid")
                + "&redirect_uri=" + wxRedirectUri
                + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
    }

    @RequestMapping("/doAuth/{redirectUri}")
    public ModelAndView doAuth(@RequestParam("code") String code, @PathVariable("redirectUri") String redirectUri) {
        ModelAndView modelAndView;
        if (StringUtils.isNotEmpty(redirectUri)) {
            redirectUri = Base64.getFromBase64(redirectUri);
            modelAndView = new ModelAndView("redirect:" + redirectUri);
        } else {
            redirectUri = "";
            modelAndView = new ModelAndView("redirect:/");
        }
        Subject subject = SecurityUtils.getSubject();
        WechatToken wechatToken = new WechatToken(code);
        try {
            subject.login(wechatToken);
        } catch (Exception e) {
            logger.error("doAuth", e);
            modelAndView = new ModelAndView("redirect:" + PropertiesFileLoader.getProperties("host")
                    + "/wx/auth?redirectUri=" + redirectUri);
        }
        return modelAndView;
    }

    @RequestMapping(value = "/getSignature", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, String> getSignature(HttpServletRequest request) {

        String shareUrl = request.getParameter("shareUrl");
        return weiXinService.getSignature(shareUrl);

    }

    @RequestMapping(value = "/checkSubscribe", method = RequestMethod.GET)
    @ResponseBody
    public Result checkSubscribe(@RequestParam("userId") String userId) {

        UserInfo userInfo = new UserInfo();
        userInfo.setId(Integer.valueOf(userId));
        userInfo = userInfoService.getUserInfo(userInfo);
        try {
            JSONObject jsonObject = WeixinUtil.loadJSON("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + weiXinService.getAccessToken()
                    + "&openid=" + userInfo.getOpenId());
            int subscribe = jsonObject.getInt("subscribe");
            if (subscribe == 1) {
                return new Result(true, null);
            } else {
                return new Result(false, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Result(false, null);
    }

    public static JSONObject loadJSON(String url) {

        StringBuilder json = new StringBuilder();
        try {
            URL oracle = new URL(url);
            URLConnection yc = oracle.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(), "UTF-8"));
            String inputLine = null;
            while ((inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
            in.close();
        } catch (MalformedURLException e) {
        } catch (IOException e) {
        }
        System.out.println("xxxxxxxxxxxx:" + json.toString());
        return new JSONObject(json.toString());
    }


    @RequestMapping(value = "/notify", method = RequestMethod.POST)
    @ResponseBody
    public ModelAndView notify(HttpServletRequest request, HttpServletResponse response) {

        userOrderService.payOrder(request, response);
        return null;
    }

    @RequestMapping(value = "/notifyRecharge", method = RequestMethod.POST)
    @ResponseBody
    public ModelAndView notifyRecharge(HttpServletRequest request, HttpServletResponse response) {

        userOrderService.recharge(request, response);
        return null;
    }


    @RequestMapping(value = "/recharge", method = RequestMethod.POST)
    @ResponseBody
    public Map recharge(@RequestParam(required = true, value = "userId") Integer userId, @RequestParam(required = true, value = "money") Integer money) {
        Map<String, String> result = new HashMap<String, String>();

        int total = money;

        //测试为一分
//     /*   total = 1;

        JSONObject attach = new JSONObject();
        attach.put("userId", userId);
        attach.put("money", money);

        WxPaySendData data = new WxPaySendData();
        data.setAppid(PropertiesFileLoader.getProperties("weixinappid"));
        data.setMch_id(PropertiesFileLoader.getProperties("weixin_mch_id"));
        data.setDevice_info(AppConstant.DEVICE_INFO);
        data.setNonce_str(MbappUtil.create_nonce_str());
        data.setBody("充值");
        data.setOut_trade_no(MbappUtil.create_out_trade_no());
        data.setNotify_url(PropertiesFileLoader.getProperties("weixin_notify_url_recharge"));
        data.setTotal_fee(total);
        data.setTrade_type(AppConstant.TRADE_TYPE_NATIVE);
        //data.setSpbill_create_ip("117.62.182.63");
        data.setSpbill_create_ip(MbappUtil.getHostAdderss());
        //扫码支付不需要openId
        //data.setOpenid(openId);

        data.setAttach(attach.toString());

        @SuppressWarnings("static-access")
        Map<String, String> unified = UnifiedorderService.unifiedOrder(data, "UTF-8");

        String timeStamp = MbappUtil.create_timestamp();
        String nonceStr = MbappUtil.create_nonce_str();
        String packageStr = "prepay_id=" + unified.get("prepay_id");
        //生成sign签名
        SortedMap<Object, Object> params = new TreeMap<Object, Object>();

        params.put("appId", PropertiesFileLoader.getProperties("weixinappid"));
        params.put("timeStamp", timeStamp);
        params.put("nonceStr", nonceStr);
        params.put("package", packageStr);
        params.put("signType", "MD5");

        result.put("appId", PropertiesFileLoader.getProperties("weixinappid"));
        result.put("timeStamp", timeStamp);
        result.put("nonceStr", nonceStr);
        result.put("myPackage", packageStr);
        result.put("signType", "MD5");
        result.put("paySign", MbappUtil.createSign("UTF-8", params));

        result.put("prepay_id", unified.get("prepay_id"));
        result.put("code_url",unified.get("code_url"));

        return result;
    }

    @RequestMapping(value = "/unifiedOrder", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, String> unifiedOrder(@RequestParam(required = true, value = "orderId") String orderId, @RequestParam(required = true, value = "coin") double coin,
                                            @RequestParam(required = true, value = "point") double point) {

        Map<String, String> result = new HashMap<String, String>();

        double cash = userOrderService.calculatedPrice(orderId, coin, point);
        int total = 0;

        //测试为一分
        //cash = 0.01;

        total = (int) (cash * 100);

        JSONObject attach = new JSONObject();
        attach.put("orderId", orderId);
        attach.put("coin", coin);
        attach.put("point", point);
        attach.put("cash", cash);
        attach.put("total", total);

        WxPaySendData data = new WxPaySendData();
        data.setAppid(PropertiesFileLoader.getProperties("weixinappid"));
        data.setMch_id(PropertiesFileLoader.getProperties("weixin_mch_id"));
        data.setDevice_info(AppConstant.DEVICE_INFO);
        data.setNonce_str(MbappUtil.create_nonce_str());
        data.setBody("商品");
        data.setOut_trade_no(MbappUtil.create_out_trade_no());
        data.setNotify_url(PropertiesFileLoader.getProperties("weixin_notify_url"));
        data.setTotal_fee(total);
        data.setTrade_type(AppConstant.TRADE_TYPE_NATIVE);
        //data.setSpbill_create_ip("117.62.182.63");
        data.setSpbill_create_ip(MbappUtil.getHostAdderss());
        //data.setOpenid(openId);
        data.setAttach(attach.toString());

        @SuppressWarnings("static-access")
        Map<String, String> unified = UnifiedorderService.unifiedOrder(data, "UTF-8");

        String timeStamp = MbappUtil.create_timestamp();
        String nonceStr = MbappUtil.create_nonce_str();
        String packageStr = "prepay_id=" + unified.get("prepay_id");
        //生成sign签名
        SortedMap<Object, Object> params = new TreeMap<Object, Object>();

        params.put("appId", PropertiesFileLoader.getProperties("weixinappid"));
        params.put("timeStamp", timeStamp);
        params.put("nonceStr", nonceStr);
        params.put("package", packageStr);
        params.put("signType", "MD5");

        result.put("appId", PropertiesFileLoader.getProperties("weixinappid"));
        result.put("timeStamp", timeStamp);
        result.put("nonceStr", nonceStr);
        result.put("myPackage", packageStr);
        result.put("signType", "MD5");
        result.put("paySign", MbappUtil.createSign("UTF-8", params));

        result.put("prepay_id", unified.get("prepay_id"));
        result.put("code_url",unified.get("code_url"));

        return result;

    }
}
