package com.heyu.api.controller.vv;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heyu.api.alibaba.request.mm.VvAnonymousUserLoginRequest;
import com.heyu.api.alibaba.request.mm.VvAppLoginRequest;
import com.heyu.api.alibaba.request.mm.order.VvActivityDTO;
import com.heyu.api.alibaba.request.vv.AppUserLoginRequest;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.dao.vv.VvBuyerDao;
import com.heyu.api.data.dto.BuyerDTO;
import com.heyu.api.data.dto.WeiChatLoginDTO;
import com.heyu.api.data.entity.vv.VvBuyerEntity;
import com.heyu.api.data.enums.UserLoginFlagEnums;
import com.heyu.api.data.service.impl.AppBaseRequest;
import com.heyu.api.data.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@Slf4j
@RestController
@RequestMapping("/app/user")
public class AppUserLoginController {

    @Autowired
    private VvBuyerDao vvBuyerDao;

    @Autowired
    private RedisUtils redisUtils;


    @Autowired
    private WeChatUtils weChatUtils;


    // http://localhost:8888/app/user/login
    @RequestMapping("/login")
    @Describe("微信用户登录")
    public R login(@RequestBody AppUserLoginRequest request) {
        WeiChatLoginDTO weiChatLoginDTO = weChatUtils.getOpenId(request.getCode());
        if (weiChatLoginDTO == null) {
            return R.error("code 失效");
        }
        VvBuyerEntity target = vvBuyerDao.selectVvBuyerOpenId(weiChatLoginDTO.getOpenid());
        if (target == null) {
            target = new VvBuyerEntity();
            target.setOpenid(weiChatLoginDTO.getOpenid());
            target.setIsTest(0);
            target.setCreateTimestamp(System.currentTimeMillis());
        }

        target.setSessionKey(weiChatLoginDTO.getSessionKey());

        vvBuyerDao.insertOrUpdateVvBuyer(target);

        // 默认24 小时
        BuyerDTO buyerDTO = buildBuyerLoginInfoCacheRedisDB(target, RedisUtils.DEFAULT_EXPIRE, null);
        replaceActivityInfo(request, "/app/user/login");
        return R.ok().put("buyer", buyerDTO);
    }


    // http://localhost:8888/app/user/anonymous/login
    @RequestMapping("/anonymous/login")
    @Describe("匿名用户登录")
    public R anonymousLogin(@RequestBody VvAnonymousUserLoginRequest request) {
        String deviceId = request.getDeviceId();
        String value = AesUtil.decrypt(deviceId, ApiConstants.AnonymousUserLogin_aes_password);

        if (StringUtils.isBlank(value) || !value.startsWith(ApiConstants.AnonymousUserLogin_pre)) {
            log.info("AnonymousUserLoginAesPassword anonymous value:{}", JSON.toJSONString(request));
            return R.error("设备号不对");
        }
        Random random = new Random(100000000L);
        VvBuyerEntity target = new VvBuyerEntity();
        target.setIsTest(UserLoginFlagEnums.anonymous_user.getFlag());
        target.setId(random.nextLong());
        BuyerDTO buyerDTO = buildBuyerLoginInfoCacheRedisDB(target, RedisUtils.thirty_minute, request.getDeviceId());

        replaceActivityInfo(request, "/app/user/anonymous/login");
        return R.ok().put("buyer", buyerDTO);
    }


    // http://localhost:8888/app/user/target/login
    @RequestMapping("/target/login")
    @Describe("目标用户登录")
    public R targetLogin(@RequestBody VvAppLoginRequest request) {
        VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerIsTestById(request.getBuyerId(), 1);
        if (vvBuyerEntity == null) {
            return R.error("你不是内部用户");
        }

        VvBuyerEntity target = vvBuyerDao.selectVvBuyerInfo(
                request.getTargetBuyer(),
                request.getTargetBuyer(),
                request.getTargetBuyer());

        // 默认24 小时
        BuyerDTO buyerDTO = buildBuyerLoginInfoCacheRedisDB(target, RedisUtils.DEFAULT_EXPIRE, null);
        replaceActivityInfo(request, "/app/user/target/login");
        return R.ok().put("buyer", buyerDTO);
    }


    public void replaceActivityInfo(AppBaseRequest request, String uri) {
        String activityTokenInfo = redisUtils.get(ApiConstants.token_activity + request.getToken());
        if (StringUtils.isNotEmpty(activityTokenInfo)) {
            log.info("AppUserLoginController replaceActivityInfo uri :{}, activityTokenInfo:{}", uri, activityTokenInfo);
            VvActivityDTO vvActivityDTO = JSONObject.parseObject(activityTokenInfo, VvActivityDTO.class);
            Long activityExpiredTime = (vvActivityDTO.getActivityExpiredTime() - System.currentTimeMillis()) / 1000;
            if (activityExpiredTime > 0) {
                redisUtils.set(ApiConstants.token_activity + request.getToken(), JSON.toJSONString(vvActivityDTO), activityExpiredTime);
            }
        }
    }

    public BuyerDTO buildBuyerLoginInfoCacheRedisDB(VvBuyerEntity target, Long expireTime, String deviceId) {
        BuyerDTO buyerDTO = new BuyerDTO();
        buyerDTO.setBuyerId(target.getId());
        buyerDTO.setBuyerName(target.getBuyerName());
        buyerDTO.setFlag(target.getIsTest());
        buyerDTO.setAvatar(target.getAvatar());
        buyerDTO.setBuyerPhone(target.getBuyerPhone());
        buyerDTO.setBuyerWeixin(target.getBuyerWeixin());

        String token = TokenUtils.generateToken(target.getId() + deviceId);
        redisUtils.set(token, JSON.toJSONString(buyerDTO), expireTime);
        buyerDTO.setToken(token);
        return buyerDTO;
    }


    @RequestMapping("/getPhoneNumber")
    public Object getPhoneNumber(@RequestBody VvAppLoginRequest request) {

        //  String sessionKey = userRepository.findByOpenId(request.getOpenId()).getSessionKey(); // 从数据库中获取 sessionKey


        //  JSONObject phoneInfo = JSONObject.parseObject(WxMaCryptUtils.decrypt(sessionKey, request.getEncryptedData(), request.getIv())); // 解密获取手机号信息
        //  String phoneNumber = phoneInfo.getString("phoneNumber");
        // 更新用户信息并存储到数据库

        // 返回给前端的手机号信息
        JSONObject result = new JSONObject();
        result.put("phoneNumber", null);
        return result;
    }


}
