package com.house365.web;

import com.google.common.base.Strings;
import com.house365.common.constant.UrlConst;
import com.house365.common.util.RestTemplateBean;
import com.house365.config.HgsProp;
import com.house365.config.WeChatProperties;
import com.house365.domain.UserInfo;
import com.house365.service.interfaces.WechatClient;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URISyntaxException;

import static com.house365.common.constant.UrlConst.*;

/**
 * <p>Title: 登录 授权</p>
 * <p>Description: </p>
 * <p>Date: 2017/1/9</p>
 *
 * @author XN
 * @version 1.0
 */
@Controller
@EnableAutoConfiguration
public class AccountController {
    public static final String PREFIX = "HGS_";
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    WechatClient wechatClient;
    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private HgsProp hgsProp;

    /**
     * 验证用户 重定向到微信验证服务 回调时接收code信息
     */
    @RequestMapping("/oauth")
    public String oauth(Model model, HttpServletRequest request) {
        //可传递应用ID，用于后续userid转换openid
        String state = request.getParameter("state") == null ? "" : request.getParameter("state");
        final String GETCODE = getCodeURL(state);
        logger.info("===GETCODE url==={}", GETCODE);
        return "redirect:" + GETCODE;
    }

    /**
     * 根据code 和 accesstoken获取用户信息
     *
     * @param code  微信回调时传入
     * @param state
     * @return
     */
    @RequestMapping("/validUser")
    public String index(
            Model model, HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "code") String code,
            @RequestParam(value = "state", required = false) String state
    ) {
        model.addAttribute("code", code);
        model.addAttribute("state", state);

        String accessToken = wechatClient.getAccessToken(weChatProperties.getCorpId(), weChatProperties.getSecret());
        while (StringUtils.isBlank(accessToken)) {
            logger.debug("===retry get accessToken=====");
            accessToken = wechatClient.getAccessToken(weChatProperties.getCorpId(), weChatProperties.getSecret());
        }
        logger.debug("=code={}=state={}=access token={}===", code, state, accessToken);
        if (!Strings.isNullOrEmpty(code) && !Strings.isNullOrEmpty(accessToken)) {
            JSONObject object = wechatClient.getUserInfo(code, accessToken);
            logger.info("==========object:{}", object.toString());
            String userId = object.containsKey("UserId") ? String.valueOf(object.get("UserId")) : "";
            String deviceId = object.containsKey("DeviceId") ? String.valueOf(object.get("DeviceId")) : "";
            String openId = object.containsKey("OpenId") ? String.valueOf(object.get("OpenId")) : "";
            UserInfo userInfo = new UserInfo(userId, deviceId, openId);

            try {
                String url = UrlConst.getUserInfoURL + "access_token=" + accessToken + "&userid=" + userInfo.getUserId();
                String result = RestTemplateBean.doGet(url);
                JSONObject user = JSONObject.fromObject(result);
                logger.debug("======userInfo:{}", result);

                String phone = user.getString("mobile");
                String cookieKey = PREFIX + "weChat:userInfo:isValid:" + phone;
                System.out.println("====>>cookieKey>>:======" + cookieKey);
                if (!hasKey(cookieKey)) {
                    redisTemplate.execute(new RedisCallback<Object>() {
                        @Override
                        public Object doInRedis(RedisConnection connection) throws DataAccessException {
                            System.out.println("====>>addRedis>>:======" + cookieKey + "===success");
                            byte[] serialKey = redisTemplate.getStringSerializer().serialize(cookieKey);
                            connection.del(serialKey);
                            connection.set(serialKey, redisTemplate.getStringSerializer().serialize("1"));
                            connection.expire(serialKey, 86400);
                            return null;
                        }
                    });
                }

                Cookie phoneCookie = new Cookie("phone", phone);
                phoneCookie.setDomain(hgsProp.getDomain());
                phoneCookie.setPath("/");
                phoneCookie.setMaxAge(86400);
                response.addCookie(phoneCookie);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

//            //企业成员有userid没有openid
//            if (!Strings.isNullOrEmpty(userId) && Strings.isNullOrEmpty(openId)) {
//                JSONObject openInfo = wechatClient.getOpenId(userId, state, accessToken);
//                openId = object.containsKey("openid") ? String.valueOf(object.get("openid")) : "";
//                String appid = object.containsKey("appid") ? String.valueOf(object.get("appid")) : "";
//                userInfo.setOpenId(openId);
//                userInfo.setAppId(appid);
//            }
//
//            //非企业成员有openid没有userid
//            if (Strings.isNullOrEmpty(userId) && !Strings.isNullOrEmpty(openId)) {
//                JSONObject userIdInfo = wechatClient.getUserId(openId, accessToken);
//                String userid = object.containsKey("userid") ? String.valueOf(object.get("userid")) : "";
//                String errcode = object.containsKey("errcode") ? String.valueOf(object.get("errcode")) : "";
//                String errmsg = object.containsKey("errmsg") ? String.valueOf(object.get("errmsg")) : "";
//                if ("0".equals(errcode) && Strings.isNullOrEmpty(userid)) {
//                    userInfo.setUserId(userid);
//                } else {
//                    logger.error("get userId error : {}", errmsg);
//                }
//            }


            request.getSession().setAttribute(SESSIONUSER, userInfo);
            logger.info("==json object={}", object.toString());
        }

        return "redirect:" + state;
    }

    /**
     * 跳转到微信登录授权页
     *
     * @param request
     * @return
     */
    @RequestMapping("/doLogin")
    public String login(HttpServletRequest request) {
        String state = request.getParameter("state") == null ? "" : request.getParameter("state");
        final String url = getLoginURL(state, weChatProperties.getCorpId(), hgsProp.getDomain() + "/loginCallback");
        logger.debug("==dologin=URL==={}", url);
        return "redirect:" + url;
    }

    /**
     * 第三方登录授权接口URL 登录回调
     *
     * @param request
     * @return
     */
    @RequestMapping("/loginCallback")
    public String loginCallback(HttpServletRequest request) {
        logger.debug("---loginCallback---");
        String auth_code = request.getParameter("auth_code") == null ? "" : request.getParameter("auth_code");
        String expires_in = request.getParameter("expires_in") == null ? "" : request.getParameter("expires_in");
        UserInfo userInfo = new UserInfo();
        if (!Strings.isNullOrEmpty(auth_code) && !Strings.isNullOrEmpty(expires_in)) {
            if (request.getSession().getAttribute(SESSIONUSER) != null) {
                userInfo = (UserInfo) request.getSession().getAttribute(SESSIONUSER);
            }
            logger.debug("---login--auth_code-{}--expires_id-{}", auth_code, expires_in);

        }
        return "index";
    }

    /**
     * 根据userID获取用户信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/getUserInfo")
    public String getUserInfo(Model model, HttpServletRequest request) {
        UserInfo userInfo = null;
        if (request.getSession().getAttribute(SESSIONUSER) != null) {
            String accessToken = wechatClient.getAccessToken(weChatProperties.getCorpId(),
                    weChatProperties.getSecret());
            userInfo = (UserInfo) request.getSession().getAttribute(SESSIONUSER);

            try {
                String url = UrlConst.getUserInfoURL + "access_token=" + accessToken + "&userid=" + userInfo.getUserId();
                String result = RestTemplateBean.doGet(url);
                logger.debug("=userinfo={}=", result);
                JSONObject jsonObject = JSONObject.fromObject(result);
                model.addAttribute("result", result);
            } catch (URISyntaxException e) {
                logger.error(e.getMessage(), e);
            }
        }
        return "index";
    }

    public boolean hasKey(final String key) {
        return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] serialKey = redisTemplate.getStringSerializer().serialize(key);
                return connection.exists(serialKey);
            }
        });
    }
}
