package com.izouma.awesomeadmin.web;

import com.izouma.awesomeadmin.dto.Result;
import com.izouma.awesomeadmin.model.UserInfo;
import com.izouma.awesomeadmin.service.UserInfoService;
import com.izouma.awesomeadmin.service.WeiXinService;
import com.izouma.awesomeadmin.shiro.WeiXinCodeToken;
import com.izouma.awesomeadmin.util.CookieUtil;
import com.izouma.awesomeadmin.util.PropertiesFileLoader;
import com.izouma.awesomeadmin.util.WeixinUtil;
import org.activiti.engine.IdentityService;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
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.Map;

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

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

    @Autowired
    private WeiXinService weiXinService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private IdentityService identityService;


    @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 = "/auth", method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView auth(@RequestParam("redirectUri") String redirectUri) {

        return new ModelAndView("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + PropertiesFileLoader.getProperties("weixinappid")
                + "&redirect_uri=" + PropertiesFileLoader.getProperties("base_domain") +"/wx/redirectLogin?redirectUri=" + redirectUri
                + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
    }


    @RequestMapping(value = "/redirectLogin", method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView redirectLogin(HttpServletRequest request, HttpServletResponse response,
                                      @RequestParam(required = true, value = "code") String code, @RequestParam(required = false, value = "redirectUri") String redirectUri) {

        ModelAndView mav = new ModelAndView("redirect:"+ PropertiesFileLoader.getProperties("base_domain") +"/index#/" + redirectUri);
        final String APP_ID = PropertiesFileLoader.getProperties("weixinappid");
        final String APP_SECRET = PropertiesFileLoader.getProperties("weixinsecret");
        try {

            // System.out.println("code : " + code);
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APP_ID + "&secret=" + APP_SECRET + "&code=" + code
                    + "&grant_type=authorization_code";
            JSONObject data = WeixinUtil.loadJSON(url);
            // System.out.println("data : " + data);

            // System.out.println(json.toString());

            String openId = (String) data.get("openid");

            /**
             * 新用户存储用户资料
             */
            String access_token = (String) data.get("access_token");
            String userDataUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openId;
            JSONObject userData = WeixinUtil.loadJSON(userDataUrl);
            String weixinInfo = userData.toString();
            // System.out.println("userDate : " + userData);


            System.out.println("loginUserInfo:" + weixinInfo);
            JSONObject userJson = new JSONObject(weixinInfo);
            System.out.println("userJson" + userJson);

            String headimgurl = userJson.getString("headimgurl");
            String sex = userJson.getInt("sex") != 0 ? "男" : "女";


            Subject subject = SecurityUtils.getSubject();

            WeiXinCodeToken weiXinCodeToken = new WeiXinCodeToken(code, openId, userJson.getString("nickname"), sex, headimgurl);
            try {
                subject.login(weiXinCodeToken);
            } catch (AuthenticationException e) {
                e.printStackTrace();
                logger.error(e);
            }
            UserInfo user = (UserInfo) subject.getPrincipal();
            identityService.setAuthenticatedUserId(user.getId().toString());
            HttpSession session = request.getSession();
            CookieUtil.addCookie(response, "JSESSIONID", session.getId(), 3 * 24 * 60 * 60);

        } catch (Exception e) {
            e.printStackTrace();
            return new ModelAndView("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APP_ID + "&redirect_uri="
                     + PropertiesFileLoader.getProperties("base_domain") +"/wx/redirectLogin?redirectUri=" + redirectUri
                    + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
        }
        return mav;
    }


    /**
     * 微信身份获取，登录验证
     *
     * @return
     */
    @RequestMapping(value = "/Login", method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView LoginService(HttpServletRequest request, HttpServletResponse response,
                                     @RequestParam(required = true, value = "code") String code) {

        ModelAndView mav = new ModelAndView("redirect:../index#/");
        final String APP_ID = PropertiesFileLoader.getProperties("weixinappid");
        final String APP_SECRET = PropertiesFileLoader.getProperties("weixinsecret");
        try {


            /**
             * 无缓存用户
             */
            // System.out.println("code : " + code);
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APP_ID + "&secret=" + APP_SECRET + "&code=" + code
                    + "&grant_type=authorization_code";
            JSONObject data = WeixinUtil.loadJSON(url);
            logger.error("Login微信身份获取，登录验证 data : " + data);

            String openId = (String) data.get("openid");


            /**
             * 新用户存储用户资料
             */
            String access_token = (String) data.get("access_token");
            String userDataUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openId;
            JSONObject userData = WeixinUtil.loadJSON(userDataUrl);
            String weixinInfo = userData.toString();
            // System.out.println("userDate : " + userData);


            System.out.println("loginUserInfo:" + weixinInfo);
            JSONObject userJson = new JSONObject(weixinInfo);
            System.out.println("userJson" + userJson);

            String headimgurl = userJson.getString("headimgurl");
            String sex = userJson.getInt("sex") != 0 ? "男" : "女";

            Subject subject = SecurityUtils.getSubject();

            WeiXinCodeToken weiXinCodeToken = new WeiXinCodeToken(code, openId, userJson.getString("nickname"), sex, headimgurl);
            try {
                subject.login(weiXinCodeToken);
            } catch (AuthenticationException e) {
                e.printStackTrace();
                logger.error(e);
            }
            UserInfo user = (UserInfo) subject.getPrincipal();
            identityService.setAuthenticatedUserId(user.getId().toString());
            HttpSession session = request.getSession();
            CookieUtil.addCookie(response, "JSESSIONID", session.getId(), 3 * 24 * 60 * 60);

        } catch (Exception e) {
            e.printStackTrace();
            return new ModelAndView("redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APP_ID + "&redirect_uri="
                     + PropertiesFileLoader.getProperties("base_domain") +"/wx/Login" + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
        }
        return mav;
    }


    @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) {
        }
        return new JSONObject(json.toString());
    }


}
