package com.ylx.web.controller.massage;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ylx.common.constant.Constants;
import com.ylx.common.core.controller.BaseController;
import com.ylx.common.core.domain.R;
import com.ylx.common.core.domain.model.WxLoginUser;
import com.ylx.common.utils.MessageUtils;
import com.ylx.common.utils.StringUtils;
import com.ylx.framework.manager.AsyncManager;
import com.ylx.framework.manager.factory.AsyncFactory;
import com.ylx.framework.web.service.WxTokenService;
import com.ylx.massage.domain.TWxUser;
import com.ylx.coupon.service.CouponReceiveService;
import com.ylx.massage.service.IMaTechnicianService;
import com.ylx.massage.service.TWxUserService;
import com.ylx.massage.utils.VirtualTechnicianNicknameGenerator;
import com.ylx.massage.utils.WeChatUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author b16mt
 */
@Slf4j
@RestController
@Api(tags = {"微信公众号sq"})
@RequestMapping("/sq")
public class WeSqController extends BaseController {

    private final static String ACCESS_TOKEN = "access_token";
    private final static String REFRESH_TOKEN = "refresh_token";
    private final static String OPEN_ID = "openid";


    @Resource
    private WeChatUtil weChatUtil;

    @Resource
    private TWxUserService wxUserService;

    @Resource(name = "commonAsyncExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private CouponReceiveService couponReceiveService;

    @Resource
    private WxTokenService wxTokenService;

    @Autowired
    public RedisTemplate redisTemplate;
    @Autowired
    private IMaTechnicianService maTechnicianService;
    @Autowired
    private WxMaService wxMaService;

    /**
     * 通过微信code获取token和userInfo
     *
     * @param code 微信授权码
     * @return R<WxLoginUser> 访问令牌
     */
    @GetMapping("/getAccessToken")
    @ResponseBody
    //@Log(title = "公众号网页登录", businessType = BusinessType.OTHER)
    public R<WxLoginUser> getAccessToken(@RequestParam String code) {
        // 发送get请求获取 AccessToken
        try {
            Map<?, ?> result = weChatUtil.getAccessToken(code);
            log.info("result的值：{}", result);
            String accessToken = result.get(ACCESS_TOKEN).toString();
            log.info("accessToken的值：{}", accessToken);
            String refreshToken = result.get(REFRESH_TOKEN).toString();
            String openid = result.get(OPEN_ID).toString();

            // 如果用户是第一次进行微信公众号授权
            // 进行这一步时用户应点击了同意授权按钮
            String userInfoJsom = weChatUtil.getUserInfo(accessToken, openid);
            // 解析JSON数据
            JSONObject jsonObject = new JSONObject(userInfoJsom);
            log.info("公众号网页登录：{}", jsonObject);
            // 将用户信息保存到数据库中
            LambdaQueryWrapper<TWxUser> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
            objectLambdaQueryWrapper.eq(TWxUser::getcOpenid, openid);
            TWxUser user = wxUserService.getOne(objectLambdaQueryWrapper);
            if (user == null || StringUtils.isEmpty(user.getcNickName())) {
                if (user == null) {
                    user = new TWxUser();
                    user.setcOpenid(openid);
                    TWxUser finalUser = user;
                    //异步 添加新人优惠卷
                    //                threadPoolTaskExecutor.submit(() -> couponReceiveService.submit(new CouponReceive().setOpenid(finalUser.getcOpenid()).setCouponId("1")));
                }
                user.setcOpenid(openid);
                user.setcNickName(jsonObject.get("nickname").toString());
                user.setcIcon(jsonObject.get("headimgurl").toString());
                user.setcSessionKey(refreshToken);
                //            user.setcPhone(phoneNumber);
                wxUserService.saveOrUpdate(user);
                user.setId(user.getId());
            }

            WxLoginUser wxUser = new WxLoginUser();
            BeanUtils.copyProperties(user, wxUser);
            // 生成并返回令牌
            String token = wxTokenService.createToken(wxUser);
            log.info("token的值：{}", token);
            if (token == null || token.isEmpty()) {
                return R.fail("生成令牌失败");
            }
            //给我把token的值保存到redis中
            redisTemplate.opsForValue().set(wxUser.getCOpenid(), token, 180, TimeUnit.MINUTES);
            wxUser.setToken(token);
            // 返回用户信息
            // 记录登录信息
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(wxUser.getCOpenid(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
            return R.ok(wxUser);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过微信code获取token和userInfo
     *
     * @param code 微信授权码
     * @return R<WxLoginUser> 访问令牌
     */
    @GetMapping("/getTechnicianToken")
    @ResponseBody
    public R<WxLoginUser> getTechnicianToken(@RequestParam String code) {
        // 发送get请求获取 AccessToken(前端是静默登录)
        try {
            Map<?, ?> result = weChatUtil.getAccessToken(code);
            log.info("result的值：{}", result);
            String accessToken = result.get(ACCESS_TOKEN).toString();
            log.info("accessToken的值：{}", accessToken);
            String refreshToken = result.get(REFRESH_TOKEN).toString();
            String openid = result.get(OPEN_ID).toString();

            //获取用户的信息
            /*String userInfoJsom = weChatUtil.getUserInfo(accessToken, openid);
            log.info("用户信息的json字符串：{}", userInfoJsom);
            JSONObject jsonObject = new JSONObject(userInfoJsom);
            //log.info("公众号网页登录：{}", jsonObject);
            String nickName = jsonObject.get("nickname").toString();
            String avatarUrl = jsonObject.get("headimgurl").toString();*/

            // 将用户信息保存到数据库中
            LambdaQueryWrapper<TWxUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TWxUser::getcOpenid, openid).eq(TWxUser::getRole,1);
            TWxUser user = wxUserService.getOne(queryWrapper);
            if (user == null || StringUtils.isEmpty(user.getcNickName())) {
                if (user == null) {
                    user = new TWxUser();
                    user.setcOpenid(openid);
                    //生成一个随机昵称
                    user.setcNickName(VirtualTechnicianNicknameGenerator.generateNickname());
                    user.setAuditStatus(-1);
                    wxUserService.saveOrUpdate(user);
                    user.setId(user.getId());
                }
            }
            WxLoginUser wxUser = new WxLoginUser();
            BeanUtils.copyProperties(user, wxUser);
            // 生成并返回令牌
            String token = wxTokenService.createToken(wxUser);
            log.info("token的值：{}", token);
            if (token == null || token.isEmpty()) {
                return R.fail("生成令牌失败");
            }
            //给我把token的值保存到redis中
            redisTemplate.opsForValue().set(wxUser.getCOpenid(), token, 3, TimeUnit.DAYS);
            wxUser.setToken(token);
            // 返回用户信息
            // 记录登录信息
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(wxUser.getCOpenid(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
            return R.ok(wxUser);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}
