package com.cftech.mp.reply.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cftech.accounts.model.MpAccountsEntity;
import com.cftech.core.config.MpGlobalConfig;
import com.cftech.core.sql.Conds;
import com.cftech.core.util.*;
import com.cftech.member.model.Member;
import com.cftech.member.service.MemberService;
import com.cftech.mp.fans.model.MpFanssEntity;
import com.cftech.mp.fans.service.MpFanssService;
import com.cftech.mp.reply.service.WxJsSdkService;
import lombok.extern.slf4j.Slf4j;
import org.mp.api.core.exception.WexinReqException;
import org.mp.api.third.JwThirdAPI;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.crypto.PlainText;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.UUID;

/**
 * Created by lisw on 2017/9/13.
 */
@RestController
@RequestMapping("/mobile/wxjs")
@Slf4j
public class MobileWxJsController {

    @Autowired
    private MpTokenUtil tokenUtil;

    @Autowired
    private MpFanssService fanssService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private WxJsSdkService wxJsSdkService;

    /**
     * 服务号授权
     * 增加两个COOKIE作为校验用，1个为authsignature JWT身份验证使用，另外一个 tokensign 则作为防止CSRF注入漏洞的TOKEN，需要前端进行加密，后台进行BASE64编码判断COOKIE中是否一致
     * KEY为随机产生的，作为移动端加密使用
     * 正式环境必须启用SECURITY_SECURE = true
     * @param code
     * @param appid
     * @return
     */
    @RequestMapping("/oauth")
    public JSONObject oauth(String code, String appid, HttpServletRequest request,HttpServletResponse response) {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorCode", "0");
        rtnJson.put("appId", appid);
        try {
            if (StringUtils.isNotBlank(code) && StringUtils.isNotBlank(appid)) {
                MpAccountsEntity mpAccount =tokenUtil.searchAccounts(appid);
                if (mpAccount != null) {


                    net.sf.json.JSONObject json = JwThirdAPI.oauth2(code, appid,mpAccount.getSecret()); // 获取openId
                    //JSONObject json = emuJson();

                    if(json.containsKey("errcode")){
                        rtnJson.put("errorCode", 3);
                        return rtnJson;  //授权信息错误
                    }
                    rtnJson.put("accountsId", mpAccount.getId());
                    String openId = json.getString("openid");
                    //返回粉丝昵称
                    Conds conds =new Conds();
                    conds.equal("mpaccountid", mpAccount.getId());
                    conds.equal("delflag",0);
                    conds.equal("openid", openId);
                    MpFanssEntity fanss=fanssService.fetchSearchByConds(conds);
                    if(fanss!=null){
                        rtnJson.put("province", fanss.getProvince());
                        rtnJson.put("city", fanss.getCity());
                        rtnJson.put("nickname", fanss.getNickname());
                        rtnJson.put("imageUrl", fanss.getHeadimgurl());
                    }
                    Conds memberConds = new Conds();
                    memberConds.equal("del_flag", "0");
                    memberConds.equal("open_id",openId);
                    memberConds.equal("accounts_id", mpAccount.getId());
                    Member member = memberService.fetchSearchByConds(memberConds);
                    if(member!=null){ //已注册
                        rtnJson.put("memberUid",member.getMember_uid());
                    }else{//用户未注册
                        rtnJson.put("memberUid","");
                        rtnJson.put("errorCode", 1);
                    }
                    rtnJson.put("openId",openId);
                    String requestId = UUID.randomUUID().toString();
                    WxLoginEntity wle = new WxLoginEntity(String.valueOf(mpAccount.getId()),rtnJson.get("nickname"),rtnJson.get("imageUrl")
                            ,rtnJson.get("memberUid"),rtnJson.getString("openId"));
                    String signature = JWTUtils.createJWT(requestId,wle);
                    rtnJson.put("nickname", "");

                    Cookie cookie = new Cookie("authsignature",URLEncoder.encode( signature,"UTF-8" ));
                    cookie.setHttpOnly(true);
                    cookie.setSecure(MpGlobalConfig.SECURITY_SECURE);
                    cookie.setMaxAge((int) (MpGlobalConfig.JWT_DURATION/1000));
                    cookie.setDomain(request.getServerName());
                    cookie.setPath(request.getContextPath());
                    response.addCookie(cookie);

                    String simpleSignature = simpleSignature(requestId,openId,rtnJson.getString("memberUid"));
                    String key =  EnDecryptUtils.createRandomCharData(16);
                    String tokenEncrypted = EnDecryptUtils.aesEncrypt(simpleSignature,key);

                    Cookie tokensign = new Cookie("tokensign", URLEncoder.encode( new BASE64Encoder().encodeBuffer(tokenEncrypted.getBytes()),"UTF-8" ) ) ;
                    tokensign.setHttpOnly(true);
                    tokensign.setSecure(MpGlobalConfig.SECURITY_SECURE);
                    tokensign.setMaxAge(( (int) ( MpGlobalConfig.JWT_DURATION/1000) )+60);
                    tokensign.setDomain(request.getServerName());
                    tokensign.setPath(request.getContextPath());
                    response.addCookie(tokensign);

                    rtnJson.put("signature", simpleSignature);
                    rtnJson.put("key", key);
                    rtnJson.put("requestId",requestId);
                } else {
                    rtnJson.put("errorCode", 2);  //公众号不存在
                }
            } else {//code参数错误
                rtnJson.put("errorCode", 3);
            }
            return rtnJson;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("授权异常:"+e.getMessage());
            rtnJson.put("errorCode", 4);
            return rtnJson;
        }
    }

    /**
     * 微信jsSdk签名接口
     * @param request
     * @return
     */
    @RequestMapping(value="signature",method = RequestMethod.GET, produces = { "application/json;charset=UTF-8" })
    public String signature(String appid,HttpServletRequest request){
        return wxJsSdkService.getParam(appid, request);
    }

    /**
     *微信H5线上发券签名接口
     */
    @RequestMapping(value="cardSignature",method = RequestMethod.POST, produces = { "application/json;charset=UTF-8" })
    public String cardSignature(Long accountsId,HttpServletRequest request,String openId,String[] cardIds,String outerStr) throws WexinReqException {
        return wxJsSdkService.getCardParam(accountsId, openId, cardIds, request,outerStr);
    }

    private JSONObject emuJson()
    {
        JSONObject obj = new JSONObject();
        obj.put("openid","openid-kk-openid");
        return obj;
    }


    private String simpleSignature(String requestId,String openId,String memberuid)
    {
        StringBuffer sb = new StringBuffer();
        sb.append("r:"+requestId);
        sb.append("openid:"+openId);
        sb.append("memuid:"+memberuid);
        return sb.toString();
    }
}
