package com.platform.yijia.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.platform.yijia.param.request.AppUserInfoRequest;
import com.platform.yijia.pojo.AppUserInfo;
import com.platform.yijia.pojo.CustomerElectronicCard;
import com.platform.yijia.pojo.CustomerPoints;
import com.platform.yijia.pojo.StationPayManage;
import com.platform.yijia.service.*;
import com.platform.yijia.utils.CodeMsg;
import com.platform.yijia.utils.ResultData;
import com.platform.yijia.utils.redis.RedisCacheUtil;
import com.platform.yijia.utils.weixinapp.AesDecryptUtil;
import com.platform.yijia.utils.weixinapp.WeiXinUserUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/demo")
public class AppUserInfoController {
    private static Logger logger =(Logger) LoggerFactory.getLogger(AppUserInfoController.class);
    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private AppUserInfoService appUserInfoService;
    @Resource
    private StationService stationService;
    @Resource
    private CustomerPointsService customerPointsService;
    @Resource
    private RedisCacheUtil redisCacheUtil;
    @Resource
    private ElectronicMembershipCardService electronicMembershipCardService;

//    String appId = "wxe1135cd390b38a54";        //微信小程序appID
//    String appSecret = "0532c7d9ae876c4ad636df0b1e3b9ddb";      //微信小程序密钥

    /*
     * 微信小程序根据code获取用户openId和sessionKey
     * @param code
     * @param stationId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getSessionKeyAndOpenID")
    public Map<String, Object> getSessionKeyAndOpenID(@RequestParam("code") String code, @RequestParam("stationId") Integer stationId){
        logger.info("微信小程序获取用户openId和sessionKey入参code和stationId: "+code +"-----" +stationId);
        String appId = "";        //微信小程序appID
        String appSecret = "";      //微信小程序密钥
        if(stationId !=null){
            Map<String, String> map = stationService.getStationAppIdAndAppSecret(stationId);
            appId = map.get("appId");        //微信小程序appID
            appSecret = map.get("appSecret");      //微信小程序密钥
            logger.info("油站信息："+map.toString());
        }
        //获取session_key 和 openid
        return WeiXinUserUtil.getUserSessionKeyAndOpenID(appId, appSecret, code);
    }

    /*
     * 解密 encryptedData
     * @param sessionKey
     * @param encryptedData
     * @param iv
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/decryptEncryptedData", method = RequestMethod.POST, consumes = "application/json")
    public String decryptEncryptedData(@RequestBody JSONObject jsonObject){
        logger.info("解密获取手机号前台传入参数：" +jsonObject.toString());
        return AesDecryptUtil.decryptEncryptedData(jsonObject.get("encryptedData").toString(), jsonObject.get("sessionKey").toString(), jsonObject.get("iv").toString(), "UTF-8").toString();
    }

    /*
     * JS-SDK使用权限签名算法
     * @param noncestr  随机字符串
     * @param timestamp 时间戳
     * @param url   页面访问路径
     * @param stationId 油站ID
     * @return
     */
    @RequestMapping(value = "/getSignature", method = RequestMethod.GET)
    @ResponseBody
    public String getSignature(@RequestParam String noncestr, String timestamp, String url, Integer stationId){
        Gson gson =new Gson();
        //返回结果集
        ResultData resultData = null;
        logger.info("JS-SDK使用权限签名算法前台传来参数: "+"油站ID："+stationId+"; noncestr: " +noncestr+"; timestamp: " +timestamp + "; url: "+url);
        Map<String, String> m = stationService.getStationAppIdAndAppSecret(stationId);
        String gzhAppId ="";
        String gzhAppSecret ="";
        String accessToken ="";
        if(m !=null && m.containsKey("gzhAppId") && m.containsKey("gzhAppSecret")){
            gzhAppId = m.get("gzhAppId");
            gzhAppSecret = m.get("gzhAppSecret");
            accessToken  = this.getTokenByRedisCache(gzhAppId, gzhAppSecret);
            //当前用户登录的公众号redis缓存中的jsapi_ticket
            String appIdTicket =gzhAppId + "-ticket";
            String jsapiTicket ="";
            if(redisCacheUtil.hasKey(appIdTicket)){
                jsapiTicket = redisCacheUtil.getCacheObject(appIdTicket);
            }else {
                //获取jsapi_ticket
                net.sf.json.JSONObject gzhJsapiTicket = WeiXinUserUtil.getGzhJsapiTicket(accessToken);
                if(gzhJsapiTicket.containsKey("ticket")){
                    redisCacheUtil.setCacheObject(appIdTicket, gzhJsapiTicket.get("ticket"));
                    redisCacheUtil.expire(appIdTicket, 7200, TimeUnit.SECONDS);
                    jsapiTicket = gzhJsapiTicket.get("ticket").toString();
                }
            }
            String string1 = "jsapi_ticket="+jsapiTicket + "&noncestr=" +noncestr +"&timestamp=" +timestamp +"&url=" +url;
            logger.info("签名参数拼接："+ string1);
            //sha1加密
            String signature = DigestUtils.sha1Hex(string1);
            logger.info("JS-SDK签名参数sha1加密后："+ signature);
            resultData = ResultData.success(signature);
        }
        return gson.toJson(resultData);
    }

    /*
     * 判断使用小程序支付的用户是否关注公众号
     * @param unionId
     * @param stationId
     * @return
     */
    @RequestMapping(value = "/whetherFollowGzh", method = RequestMethod.GET)
    @ResponseBody
    public String whetherFollowGzh(@RequestParam String unionId, Integer stationId){
        Gson gson =new Gson();
        //返回结果集
        ResultData resultData = null;
        if (unionId !=null){
            Map<String, String> param = new HashMap<>();
            param.put("unionId", unionId);
            param.put("userType", "1");
            param.put("stationId", stationId.toString());
            String openId = appUserInfoService.whetherFollowGzh(param);
            if(openId !=null){
                Map<String, String> m = stationService.getStationAppIdAndAppSecret(stationId);
                String gzhAppId ="";
                String gzhAppSecret ="";
                String accessToken ="";
                if(m !=null && m.containsKey("gzhAppId") && m.containsKey("gzhAppSecret")){
                    gzhAppId = m.get("gzhAppId");
                    gzhAppSecret = m.get("gzhAppSecret");
                    accessToken  = this.getTokenByRedisCache(gzhAppId, gzhAppSecret);
                    net.sf.json.JSONObject unionIdInfo = WeiXinUserUtil.getUnionIdInfo(accessToken, openId);
                    logger.info("用户公众号信息：" + unionIdInfo);
                    if(unionIdInfo.containsKey("subscribe") && unionIdInfo.get("subscribe").equals(1)){
                        resultData = ResultData.success(CodeMsg.SUCCESS);
                    }else {
                        resultData = ResultData.error(CodeMsg.NO_FollowGzh);
                    }
                }else {
                    resultData = ResultData.error(CodeMsg.SEARCH_APPID_FAIL);
                }
            }else {
                resultData = ResultData.error(CodeMsg.USERGZHINFO_EXSIST);
            }
        }
        return gson.toJson(resultData);
    }

    /*
     * 获取公众号授权后的信息
     * @param code
     * @param stationId
     * @return
     */
    @RequestMapping(value = "/getGzhAuthorizeInfo", method = RequestMethod.GET)
    @ResponseBody
    public String getGzhAuthorizeInfo(@RequestParam String code, Integer stationId){
        logger.info("获取公众号授权后的信息前端传递参数：code："+ code );
        logger.info("获取公众号授权后的信息前端传递参数：stationId：" +stationId);
        Gson gson =new Gson();
        //返回结果集
        ResultData resultData = null;
        if(code != null && stationId !=null){
            String gzhAppId ="";
            String gzhAppSecret ="";
            Map<String, String> m = stationService.getStationAppIdAndAppSecret(stationId);
            if(m !=null && m.containsKey("gzhAppId") && m.containsKey("gzhAppSecret")){
                gzhAppId = m.get("gzhAppId");
                gzhAppSecret = m.get("gzhAppSecret");
                net.sf.json.JSONObject gzhAuthorizeInfo = WeiXinUserUtil.getGzhAuthorizeInfo(gzhAppId, gzhAppSecret, code);
                logger.info("授权获取到信息：" + gzhAuthorizeInfo.toString());
                resultData = ResultData.success(gzhAuthorizeInfo);
            }else {
                resultData = ResultData.error(CodeMsg.REQUEST_FAIL);
            }
        }else {
            resultData = ResultData.error(CodeMsg.REQUEST_FAIL);
        }
        return gson.toJson(resultData);
    }


    /*
     * 测试用来
     * 获取公众号授权后的信息测试
     * @param code
     * @param stationId
     * @return
     */
    @RequestMapping(value = "/getGzhAuthorizeInfoNew", method = RequestMethod.GET)
    @ResponseBody
    public String getGzhAuthorizeInfoNew(@RequestParam String code, Integer stationId){
        logger.info("获取公众号授权后的信息前端传递参数：code："+ code );
        logger.info("获取公众号授权后的信息前端传递参数：stationId：" +stationId);
        Gson gson =new Gson();
        //返回结果集
        ResultData resultData = null;
        if(code != null && stationId !=null){
            String gzhAppId ="";
            String gzhAppSecret ="";
            Map<String, String> m = stationService.getStationAppIdAndAppSecret(stationId);
            if(m !=null && m.containsKey("gzhAppId") && m.containsKey("gzhAppSecret")){
                gzhAppId = m.get("gzhAppId");
                gzhAppSecret = m.get("gzhAppSecret");
                net.sf.json.JSONObject gzhAuthorizeInfo = WeiXinUserUtil.getGzhAuthorizeInfo(gzhAppId, gzhAppSecret, code);
                logger.info("授权获取到信息：" + gzhAuthorizeInfo.toString());
                if(gzhAuthorizeInfo.containsKey("openid")){
                    String openId = gzhAuthorizeInfo.get("openid").toString();
                    String accessToken  = this.getTokenByRedisCache(gzhAppId, gzhAppSecret);
                    net.sf.json.JSONObject unionIdInfo = null;
                    unionIdInfo= WeiXinUserUtil.getUnionIdInfo(accessToken, openId);
                    if(unionIdInfo.containsKey("errcode")){
                        //删除原来key
                        redisCacheUtil.deleteObject(gzhAppId);
                        String token = WeiXinUserUtil.getToken(gzhAppId, gzhAppSecret).getAccessToken();
                        redisCacheUtil.setCacheObject(gzhAppId, token);
                        redisCacheUtil.expire(gzhAppId, 7200, TimeUnit.SECONDS);
                        unionIdInfo= WeiXinUserUtil.getUnionIdInfo(token, openId);
                    }
                    AppUserInfo appUserInfo = new AppUserInfo();
                    if(unionIdInfo.containsKey("openid")){
                        appUserInfo.setBlogOpenid(unionIdInfo.get("openid").toString());
                    }
                    if(unionIdInfo.containsKey("nickname")){
                        appUserInfo.setBlogNickName(unionIdInfo.get("nickname").toString());
                    }
                    if(unionIdInfo.containsKey("sex")){
                        appUserInfo.setSexFlag(unionIdInfo.get("sex").toString());
                    }
                    if(unionIdInfo.containsKey("headimgurl")){
                        appUserInfo.setBlogProfilePhoto(unionIdInfo.get("headimgurl").toString());
                    }
                    if(unionIdInfo.containsKey("unionid")){
                        appUserInfo.setUnionId(unionIdInfo.get("unionid").toString());
                    }
                    appUserInfo.setUserType("1");
                    Map<String, Object> params = new HashMap<>();
                    params.put("openId", openId);                   //注册用户openId
                    params.put("userType", appUserInfo.getUserType());  //用户类型
                    //判断该用户是否已存在
                    int count = appUserInfoService.isExistAppUser(params);
                    if(count > 0){
                        appUserInfoService.updateAppUserInfo(appUserInfo);
                    }else {
                        appUserInfoService.AddAppUserInfo(appUserInfo);
                    }
                    resultData = ResultData.success(unionIdInfo);
                }
            }else {
                resultData = ResultData.error(CodeMsg.REQUEST_FAIL);
            }
        }else {
            resultData = ResultData.error(CodeMsg.REQUEST_FAIL);
        }
        return gson.toJson(resultData);
    }


    /*
     * 获取公众号信息
     * @param openId
     * @param stationId
     * @return
     */
    @RequestMapping(value = "/getGzhUserInfo", method = RequestMethod.GET)
    @ResponseBody
    public String getGzhUserInfo(@RequestParam String openId, Integer stationId){
        Gson gson =new Gson();
        //返回结果集
        ResultData resultData = null;
        if(openId !=null && stationId !=null){
            String gzhAppId ="";
            String gzhAppSecret ="";
            String accessToken ="";
            Map<String, String> m = stationService.getStationAppIdAndAppSecret(stationId);
            if(m !=null && m.containsKey("gzhAppId") && m.containsKey("gzhAppSecret")){
                gzhAppId = m.get("gzhAppId");
                gzhAppSecret = m.get("gzhAppSecret");
                accessToken  = this.getTokenByRedisCache(gzhAppId, gzhAppSecret);
                net.sf.json.JSONObject unionIdInfo = null;
                unionIdInfo= WeiXinUserUtil.getUnionIdInfo(accessToken, openId);
                if(unionIdInfo.containsKey("errcode")){
                    //删除原来key
                    redisCacheUtil.deleteObject(gzhAppId);
                    String token = WeiXinUserUtil.getToken(gzhAppId, gzhAppSecret).getAccessToken();
                    redisCacheUtil.setCacheObject(gzhAppId, token);
                    redisCacheUtil.expire(gzhAppId, 7200, TimeUnit.SECONDS);
                    unionIdInfo= WeiXinUserUtil.getUnionIdInfo(token, openId);
                }
                resultData=ResultData.success(unionIdInfo);
            }
        }else {
            resultData=ResultData.error(CodeMsg.REQUEST_FAIL);
        }
        return gson.toJson(resultData);
    }

    /*
     * 从Redis缓存中获取 tokenCache
     * @param appId
     * @param appSecret
     * @return
     */
    public String getTokenByRedisCache(String appId, String appSecret){
        logger.info("appId参数: "+ appId+" ;appSecret参数: " +appSecret);
        if(!redisCacheUtil.hasKey(appId) || redisCacheUtil.getCacheObject(appId) ==null || redisCacheUtil.getCacheObject(appId).equals("")){
            String token = WeiXinUserUtil.getToken(appId, appSecret).getAccessToken();
            redisCacheUtil.setCacheObject(appId, token);
            redisCacheUtil.expire(appId, 7200, TimeUnit.SECONDS);
            logger.info("Redis缓存中token信息: " + token);
            return token;
        }else {
            return redisCacheUtil.getCacheObject(appId);
        }
    }

    /*
     * 添加用户信息
     * @param request
     * @return
     */
    @RequestMapping(value = "/addAppUserInfo", method = RequestMethod.POST)
    @ResponseBody
    @Transactional
    public String addAppUserInfo(@RequestBody AppUserInfoRequest request){
        Gson gson =new Gson();
        ResultData resultData=null;
        try{
            logger.info("前端传入参数：" +request.toString());
            AppUserInfo appUserInfo =new AppUserInfo();
            CustomerPoints customerPoints =  new CustomerPoints();
            CustomerElectronicCard customerElectronicCard = new CustomerElectronicCard();   //客户电子卡
            String openId = "";     //此参数用于查询该用户是否已注册过
            if(request.getUserType()!=null){
                //1-微信公众号
                if(request.getUserType().equals("1") &&StringUtils.isNotBlank(request.getOpenId())){
                    appUserInfo.setUserType(request.getUserType());
                    appUserInfo.setBlogToken(request.getBlogToken());
                    openId = request.getOpenId();
                    appUserInfo.setBlogOpenid(openId);
                    customerPoints.setBlogOpenId(openId);
                    customerElectronicCard.setBlogOpenid(openId);
                 //2-微信小程序
                }else if(request.getUserType().equals("2") &&StringUtils.isNotBlank(request.getOpenId())){
                    appUserInfo.setUserType(request.getUserType());
                    appUserInfo.setMinaToken(request.getMinaToken());
                    openId = request.getOpenId();
                    appUserInfo.setMinaOpenid(openId);
                    customerPoints.setMinaOpenId(openId);
                    customerElectronicCard.setMinaOpenid(openId);
                }
            }
            if(StringUtils.isNotBlank(request.getBlogNickName())){
                appUserInfo.setBlogNickName(request.getBlogNickName());
                customerPoints.setCustomerName(request.getBlogNickName());
                customerElectronicCard.setCustomerName(request.getBlogNickName());
            }
            if(StringUtils.isNotBlank(request.getMobilePhone())){
                appUserInfo.setMobilePhone(request.getMobilePhone());
                customerPoints.setMobilePhone(request.getMobilePhone());
                customerElectronicCard.setMobilePhone(request.getMobilePhone());
            }
            if(StringUtils.isNotBlank(request.getBlogProfilePhoto())){
                appUserInfo.setBlogProfilePhoto(request.getBlogProfilePhoto());
            }
            if(StringUtils.isNotBlank(request.getUnionId())){
                appUserInfo.setUnionId(request.getUnionId());
                customerPoints.setUnionId(request.getUnionId());
                customerElectronicCard.setUnionId(request.getUnionId());
            }

            appUserInfo.setStationId(request.getStationId());
            appUserInfo.setRegisteDate(new Date());
            appUserInfo.setUpdateDate(new Date());

            customerPoints.setCreateTime(new Date());
            customerPoints.setUnionId(request.getUnionId());
            customerPoints.setPoints(0);
            customerPoints.setConsumptionPoints(0);
            customerPoints.setAccumulatePoints(0);
            customerPoints.setInvalidPoints(0);
            customerPoints.setStationId(request.getStationId());
            customerPoints.setStationName(request.getStationName());

            customerElectronicCard.setCreateTime(new Date());
            customerElectronicCard.setStationId(request.getStationId());
            customerElectronicCard.setStationName(request.getStationName());

            if(StringUtils.isNotBlank(request.getSexFlag())){
                appUserInfo.setSexFlag(request.getSexFlag());
            }
            logger.info("插入数据库用户信息参数："+appUserInfo.toString());
            Map<String, Object> params = new HashMap<>();
            params.put("openId", openId);                   //注册用户openId
            params.put("userType", request.getUserType());  //用户类型
            //判断该用户是否已存在
            int count = appUserInfoService.isExistAppUser(params);
            if(count > 0){
                appUserInfoService.updateAppUserInfo(appUserInfo);
            }else {
                appUserInfoService.AddAppUserInfo(appUserInfo);
            }
            StationPayManage stationPayManage = new StationPayManage();
            stationPayManage.setStationId(request.getStationId());
            StationPayManage stationPayManageInfo = stationService.selectStationPayManage(stationPayManage);    //换取油站配置信息
            //是否开起积分功能
            if(stationPayManageInfo !=null && stationPayManageInfo.getIntegralFlag().equals("1")){
                this.insertCustomerPointsInfo(customerPoints, request);
            }
            //是否开起电子卡功能
            if(stationPayManageInfo !=null && stationPayManageInfo.getCardEnabledFlag().equals("1")){
                this.insertCustomerElectronicCard(customerElectronicCard, request);
            }
            resultData = ResultData.success(CodeMsg.SUCCESS);
        }catch (Exception e){
            resultData = ResultData.error(CodeMsg.INSERT_FAIL);
            e.printStackTrace();
        }
        return gson.toJson(resultData);
    }

    //客户积分表信息操作
    public void insertCustomerPointsInfo(CustomerPoints customerPoints, AppUserInfoRequest request){
        boolean boo = customerPointsService.isExistCustomerPointsInfo(customerPoints);
        if(!boo){
            customerPointsService.insertCustomerPointsInfo(customerPoints);
        }else {
            //此处用于：如果客户积分信息存在可能会出现小程序ID或者公众号ID没有的情况
            CustomerPoints c = new CustomerPoints();
            c.setUnionId(customerPoints.getUnionId());
            if(request.getUserType().equals("1")){
                c.setBlogOpenId(customerPoints.getBlogOpenId());
            }else if(request.getUserType().equals("2")){
                c.setMinaOpenId(customerPoints.getMinaOpenId());
            }
            c.setStationId(request.getStationId());
            c.setStationName(request.getStationName());
            c.setMobilePhone(request.getMobilePhone());
            c.setStationId(request.getStationId());
            c.setCustomerName(request.getBlogNickName());
            c.setStationName(request.getStationName());
            customerPointsService.updateCustomerPointsInfo(c);
        }
    }

    //客户电子会员卡表操作
    public void insertCustomerElectronicCard(CustomerElectronicCard customerElectronicCard, AppUserInfoRequest request){
        List<CustomerElectronicCard> electronicCardList = electronicMembershipCardService.getElectronicCardList(customerElectronicCard);
        if(electronicCardList !=null && electronicCardList.size() ==2){
            electronicMembershipCardService.updateElectronicCardInfoByUnionId(customerElectronicCard);
        }else {
            //当前时间戳
            String currentTime = String.valueOf(System.currentTimeMillis());
            String customerNo = request.getStationId() + currentTime;
            customerElectronicCard.setStationName(request.getStationName());
            customerElectronicCard.setCustomerNo(customerNo);
            customerElectronicCard.setAmt(new BigDecimal(0));
            customerElectronicCard.setCardOilsType("1");
            electronicMembershipCardService.insetElectronicCard(customerElectronicCard);
            customerElectronicCard.setCardOilsType("2");
            String currentTime1 = String.valueOf(System.currentTimeMillis());
            String customerNo1 = request.getStationId() + currentTime1;
            customerElectronicCard.setCustomerNo(customerNo1);
            electronicMembershipCardService.insetElectronicCard(customerElectronicCard);
        }

    }

}
