package com.fs.app.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.fs.app.annotation.Login;
import com.fs.app.utils.JwtUtils;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.OrderUtils;
import com.fs.store.param.LoginMpWxParam;
import com.fs.common.utils.IpUtil;
import com.fs.wx.miniapp.config.WxMaConfiguration;
import com.fs.wx.miniapp.config.WxMaProperties;
import com.fs.store.domain.FsUser;
import com.fs.store.param.LoginWxParam;
import com.fs.store.service.IFsUserService;
import com.fs.wx.mp.config.WxMpConfiguration;
import com.fs.wx.mp.config.WxMpProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Synchronized;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import me.chanjar.weixin.common.error.WxErrorException;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 微信小程序用户接口
 *
 */
@Api("微信接口")
@RestController
@RequestMapping(value="/app/wx")
public class WxUserController extends AppBaseController{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private WxMaProperties maProperties;

    @Autowired
    private WxMpProperties mpProperties;
    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private IFsUserService userService;
    @Autowired
    JwtUtils jwtUtils;

    /**
     * 登陆接口
     */
    @ApiOperation("登录")
    @PostMapping("/login")
    public R login( @RequestBody LoginMpWxParam param) {
        if (StringUtils.isBlank(param.getCode())) {
            return R.error("code不存在");
        }
        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(0).getAppid());
        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            // 解密
            WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
            FsUser user=userService.selectFsUserByMaOpenId(session.getOpenid());
            String ip = IpUtil.getRequestIp();
            if(user==null){
                //查询手机号是否存在，如果存在，更新
                FsUser checkPhone=userService.selectFsUserByPhone(phoneNoInfo.getPhoneNumber());
                if(checkPhone!=null){
                    if(checkPhone.getMaOpenId()==null){
                        user=checkPhone;
                        FsUser userMap=new FsUser();
                        userMap.setMaOpenId(session.getOpenid());
                        userMap.setUserId(checkPhone.getUserId());
                        userMap.setUpdateTime(new DateTime());
                        userMap.setLastIp(ip);
                        userService.updateFsUser(userMap);
                    }
                    else{
                        throw new CustomException("此手机号已存在");
                    }

                }
                else{
                    //写入
                    user=new FsUser();
                    if(StringUtils.isNotEmpty(param.getUserCode())){
                        FsUser tuiUser=userService.selectFsUserByUserCode(param.getUserCode());
                        if(tuiUser!=null){
                            user.setIsPromoter(1);
                            user.setSpreadUserId(tuiUser.getUserId());
                        }
                    }
                    user.setUserCode(OrderUtils.genUserCode());
                    user.setPhone(phoneNoInfo.getPhoneNumber());
                    user.setUsername(phoneNoInfo.getPhoneNumber());
                    user.setNickname("微信用户");
                    user.setStatus(1);
                    user.setMaOpenId(session.getOpenid());
                    user.setLastIp(ip);
                    user.setIsWeixinAuth(0);
                    user.setCreateTime(new Date());
                    userService.insertFsUser(user);
                }
           }
           else{
               FsUser userMap=new FsUser();
               userMap.setPhone(phoneNoInfo.getPhoneNumber());
               userMap.setUserId(user.getUserId());
               userMap.setUpdateTime(new DateTime());
               userMap.setLastIp(ip);
               userService.updateFsUser(userMap);
           }
           String token = jwtUtils.generateToken(user.getUserId());
           return R.ok("登录成功").put("token",token).put("user", user);
        } catch (WxErrorException e) {
            //this.logger.error(e.getMessage(), e);
            return R.error("授权失败,"+e.getMessage());
        }
    }

//    /**
//     * <pre>
//     * 获取微信用户信息
//     * </pre>
//     */
//    @Login
//    @ApiOperation("获取微信小程序用户信息")
//    @PostMapping("/getWeixinInfo")
//    public R getWeixinInfo(@RequestBody LoginMpWxParam param) {
//        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(0).getAppid());
//        try {
//            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
//            // 用户信息校验
//            if (!wxService.getUserService().checkUserInfo(session.getSessionKey(), param.getRawData(), param.getSignature())) {
//                return R.error("user check failed");
//            }
//            // 解密用户信息
//            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
//            FsUser user=userService.selectFsUserById(Long.parseLong(getUserId()));
//            user.setNickname(userInfo.getNickName());
//            user.setAvatar(userInfo.getAvatarUrl());
//            user.setIsWeixinAuth(1);
//            userService.updateFsUser(user);
//            return R.ok();
//        } catch (WxErrorException e) {
//            e.printStackTrace();
//        }
//        return R.ok("授权成功");
//    }

    @ApiOperation("小程序登录")
    @PostMapping("/loginByMiniApp")
    @Synchronized
    public R loginByMiniApp( @RequestBody LoginMpWxParam param) {
        if (StringUtils.isBlank(param.getCode())) {
            return R.error("code不存在");
        }
        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(0).getAppid());
        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            // 解密
//            WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
            FsUser user=userService.selectFsUserByMaOpenId(session.getOpenid());
            String ip = IpUtil.getRequestIp();
            if(user==null){
                user=userService.selectFsUserByUnionId(session.getUnionid());
                if(user!=null){
                    FsUser userMap=new FsUser();
                    userMap.setUserId(user.getUserId());
                    userMap.setUpdateTime(new DateTime());
                    user.setMaOpenId(session.getOpenid());
                    userMap.setLastIp(ip);
                    userService.updateFsUser(userMap);
                }
                else{
                    //写入
                    user=new FsUser();
//                    if(param.getTuiUserId()!=null&&param.getTuiUserId()>0){
//                        FsUser tuiUser=userService.selectFsUserById(param.getTuiUserId());
//                        if(tuiUser!=null){
//                            user.setSpreadUserId(param.getTuiUserId());
//                        }
//                    }
                    user.setUsername("");
//                    user.setPhone(phoneNoInfo.getPhoneNumber());
                    user.setPhone("");
                    user.setNickname("微信用户");
                    user.setStatus(1);
                    user.setMaOpenId(session.getOpenid());
                    user.setLastIp(ip);
                    user.setIsWeixinAuth(0);
                    user.setCreateTime(new Date());
                    if(StringUtils.isNotEmpty(session.getUnionid())){
                        user.setUnionId(session.getUnionid());
                    }
                    userService.insertFsUser(user);
                }
            }
            else{
                FsUser userMap=new FsUser();
                userMap.setUserId(user.getUserId());
                userMap.setUpdateTime(new DateTime());
                userMap.setLastIp(ip);
                if(StringUtils.isNotEmpty(session.getUnionid())){
                    userMap.setUnionId(session.getUnionid());
                }
                userService.updateFsUser(userMap);
            }
            String token = jwtUtils.generateToken(user.getUserId());
            return R.ok("登录成功").put("token",token).put("user", user);
        } catch (WxErrorException e) {
            //this.logger.error(e.getMessage(), e);
            return R.error("授权失败,"+e.getMessage());
        }
    }
    @ApiOperation("公众号登录")
    @PostMapping("/loginByMp")
    @Synchronized
    public R loginByMp( @RequestBody LoginWxParam param) {
        if (StringUtils.isBlank(param.getCode())) {
            return R.error("code不存在");
        }
        try{

            WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
            WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
            //如果开启了UnionId
            FsUser user=userService.selectFsUserByMpOpenId(wxMpUser.getOpenid());
            String ip = IpUtil.getRequestIp();
            if(user==null){
                user=userService.selectFsUserByPhone(wxMpUser.getUnionId());
                if(user!=null){
                    FsUser userMap=new FsUser();
                    userMap.setUserId(user.getUserId());
                    userMap.setUpdateTime(new DateTime());
                    userMap.setLastIp(ip);
                    user.setMpOpenId(wxMpUser.getOpenid());
                    userService.updateFsUser(userMap);
                }
                else{
                    user=new FsUser();
                    user.setUsername("");
                    user.setNickname(wxMpUser.getNickname());
                    user.setStatus(1);
                    user.setMpOpenId(wxMpUser.getOpenid());
                    user.setLastIp(ip);
                    user.setCreateTime(new Date());
                    user.setAvatar(wxMpUser.getHeadImgUrl());
                    if(StringUtils.isNotEmpty(wxMpUser.getUnionId())){
                        user.setUnionId(wxMpUser.getUnionId());
                    }
                    userService.insertFsUser(user);
                }
            }
            else{
                FsUser userMap=new FsUser();
                userMap.setUserId(user.getUserId());
                userMap.setUpdateTime(new DateTime());
                userMap.setLastIp(ip);
                if(StringUtils.isNotEmpty(wxMpUser.getUnionId())){
                    userMap.setUnionId(wxMpUser.getUnionId());
                }
                userService.updateFsUser(userMap);
            }
            String token = jwtUtils.generateToken(user.getUserId());
            return R.ok("登录成功").put("token",token).put("user", user);
        }
        catch (WxErrorException e){
            if(e.getError().getErrorCode()==40163){
                return R.error(40163,e.getError().getErrorMsg());
            }
            else{
                return R.error("授权失败,"+e.getMessage());
            }
        }

    }

}
