package com.td.Dawa.game.comusers.controller;

import cn.hutool.json.JSONObject;
import com.td.Dawa.annotation.Decrypt;
import com.td.Dawa.annotation.Encrypt;
import com.td.Dawa.common.controller.*;
import com.td.Dawa.common.pojo.Result;
import com.td.Dawa.config.exception.AuthorizeException;
import com.td.Dawa.game.complayersattri.service.ComPlayersAttriService;
import com.td.Dawa.game.complayersattri.vo.ComPlayersAttriClientVo;
import com.td.Dawa.game.complayersattri.vo.ComPlayersAttriVo;
import com.td.Dawa.game.comusers.vo.ComUsersClientVo;
import com.td.Dawa.game.comusers.vo.ComUsersLoginVo;
import com.td.Dawa.config.enums.ResultEnum;
import com.td.Dawa.game.comusers.pojo.ComUsers;
import com.td.Dawa.game.comusers.vo.ComUsersVo;
import com.td.Dawa.game.comusers.service.ComUsersService;
import com.td.Dawa.game.excelparameter.service.ExcelParameterService;
import com.td.Dawa.game.excelparameter.vo.ExcelParameterVo;
import com.td.Dawa.sys.syssetting.vo.SysSettingVo;
import com.td.Dawa.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/game/comUsers/")
public class ComUsersController extends CommonController<ComUsersVo, ComUsers, String> {
    @Autowired
    private ComUsersService comUsersService;

    @Autowired
    private ComPlayersAttriService comPlayersAttriService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;


    @Value("${spring.profiles.active}")
    private String active;

    @Value(value = "classpath:static/dapp/dapp-plugin.min.js")
    private Resource dappPluginFile;
    @Value(value = "classpath:static/dapp/dapp.js")
    private Resource dappFile;

    @Autowired
    private RedisLock redisLock;

    @Autowired
    private ExcelParameterService excelParameterService;

    @Autowired
    private RedisSettingMap redisSettingMap;

    /**
     * 接口需要token放行
     *
     * @return
     */
    @PostMapping("RSAConfig")
    public Result<Map> publicKeyAndSys() {
        //存储在redis上
        Map map = new HashMap();
        map.put("active", active);
        map.put("publicKey", redisSettingMap.getRSAPublicKeyBase64());
        SysSettingVo sysSettingVo = redisSettingMap.getSysSettingMap();
        map.put("apiEncrypt", sysSettingVo.getSysApiEncrypt());
        return Result.of(map);
    }

    /**
     * 登录后返回一个token令牌
     *
     * @param comUsersLoginVo
     * @return
     */
    @PostMapping("login")
    @Decrypt
    @Encrypt
    public Result<Map> login(ComUsersLoginVo comUsersLoginVo) {
        log.info("login:"+comUsersLoginVo.toString());
        Map map = new HashMap();
        try {
            Map metaLoginInfo = WaDaNetUtil.MetaPalLogin(comUsersLoginVo.getUsername(), comUsersLoginVo.getPassword());
            if (!metaLoginInfo.get("code").equals(200)) {
                //登录失败
                return Result.of(metaLoginInfo, false, ResultEnum.META_LOGIN_ERROR.getMessage(), ResultEnum.META_LOGIN_ERROR.getCode());
            }
            JSONObject jsonObject = new JSONObject(metaLoginInfo.get("result"));
            if (jsonObject.get("accountStatus").equals(1)) {
                //禁止登录
                return Result.of(metaLoginInfo, false, ResultEnum.META_LOGIN_LIMIT.getMessage(), ResultEnum.META_LOGIN_LIMIT.getCode());
            }
            String uuid = jsonObject.getStr("uuid"), address = jsonObject.getStr("wallet");
            String _redisKey = "SNB_SAVE_" + uuid;
            //todo snb冻结加锁
            long time = System.currentTimeMillis() + RedisData.getSnbTimeout();
            //如果校验通过，生成用户数据，生成token
            ComUsersVo comUsersVo = comUsersService.findByUserId(uuid);
            if (comUsersVo == null) {
                //如果没有用户信息
                comUsersVo = new ComUsersVo();
                comUsersVo.setUserId(uuid);
                comUsersVo.setGold(0);
                comUsersVo.setDiamond(0);
                comUsersVo.setCnt(0);
                comUsersVo.setSnb(0);
                comUsersVo.setSnbPart(0d);
                comUsersVo.setName(jsonObject.getStr("userName"));
                comUsersVo.setRealName(jsonObject.getStr("realName"));
                comUsersVo.setEmail(jsonObject.getStr("email"));
                comUsersVo.setTelephone(jsonObject.getStr("telephone"));
                comUsersVo.setBirthday(jsonObject.getStr("birthday"));
                comUsersVo.setSex(jsonObject.getInt("sex"));
                comUsersVo.setWallet(address);
                comUsersVo.setLimitTran(0);
                comUsersVo.setLimitLogin(0);
                comUsersVo.setAddress(address);
                comUsersVo.setLastLogin(new Date());
                comUsersVo.setCreateTime(new Date());
                comUsersService.save(comUsersVo);
            } else {
                //如果是黑名单限制登录的用户，限制登录
                if (comUsersVo.getLimitLogin().equals(1)) {
                    map.put("msg", "当前用户限制登录，请联系游戏管理人员！");
                    return Result.of(map, false, ResultEnum.USER_LIMIT_LOGIN.getMessage(), ResultEnum.USER_LIMIT_LOGIN.getCode());
                }
                //记录一下用户的Address
                if (comUsersVo.getAddress() == null) {
                    comUsersVo.setWallet(address);
                    comUsersVo.setAddress(address);
                }
                //维护一个最后登录时间
                comUsersVo.setLastLogin(new Date());
                // 防止重复操作
                if (!redisLock.lock(_redisKey, String.valueOf(time))) {
                    return Result.of(map, false, ResultEnum.USER_LOGIN_LOCK.getMessage(), ResultEnum.USER_LOGIN_LOCK.getCode());
                }
                comUsersService.save(comUsersVo);
                redisLock.unlock(_redisKey, String.valueOf(time));

            }
            //获取一下用户属性，新增表
            ComPlayersAttriVo playersAttribute = comPlayersAttriService.findByUserId(comUsersVo.getUserId());
            if (playersAttribute == null) {
                // todo player 如果角色不存在的话，直接创建一个。
                playersAttribute = new ComPlayersAttriVo();
                playersAttribute.setUserId(comUsersVo.getUserId());
                playersAttribute.setStrength(0);
                playersAttribute.setLucky(0);
                playersAttribute.setResetStrength(DateUtil.getNowDate());
                playersAttribute.setCreateTime(DateUtil.getNowDate());
                playersAttribute.setUpdateTime(DateUtil.getNowDate());
                comPlayersAttriService.save(playersAttribute);
            } else {
                //todo 判断是否过了一天，是的话重置体力值
                if (playersAttribute.getResetStrength() == null) {
                    playersAttribute.setStrength(0);
                    playersAttribute.setResetStrength(DateUtil.getNowDate());
                    comPlayersAttriService.save(playersAttribute);
                } else {
                    Long _attributeTime = DateUtil.getOldDateAddDay(playersAttribute.getResetStrength(), 1).getTime() - DateUtil.getNowDate().getTime();
                    if (_attributeTime <= 0) {
                        playersAttribute.setStrength(0);
                        playersAttribute.setResetStrength(DateUtil.getNowDate());
                        comPlayersAttriService.save(playersAttribute);
                    }
                }

            }
            //todo 暂时是id=1为体力
            ExcelParameterVo excelParameterVo = excelParameterService.getVo(1);
            if (excelParameterVo.equals(null)) {
                //return Result.of(null, false, ResultEnum.SETTING_IS_NULL);
                throw new AuthorizeException(ResultEnum.SETTING_IS_NULL);
            }
            //计算一下体力值
            ComPlayersAttriClientVo clientVo =  comPlayersAttriService.setStrengthAttriClientVo(playersAttribute,excelParameterVo.getValue().intValue());

            //返回前端的体力值是读取一个配置的体力值，
            map.put("attribute", clientVo);

            //生成token
            final String token = jwtTokenUtil.generateToken(comUsersVo.getUserId());
            map.put("token", token);
            map.put("userInfo", CopyUtil.copy(comUsersVo, ComUsersClientVo.class));

            return Result.of(map);
        } catch (HttpClientErrorException e) {
            log.error(e.toString());
            //返回 402 错误
            map.put("active", active);
            map.put("response", e.toString());
            return Result.of(map, false, ResultEnum.USER_VERIFICATION_ERROR.getMessage(), ResultEnum.USER_VERIFICATION_ERROR.getCode());
        }
    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     */
    @PostMapping("getUserInfo")
    @Decrypt
    @Encrypt
    public Result<Map> getUserInfo(@RequestParam(value = "userId") String userId) {
        Map map = new HashMap();
        ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
        if (comUsersVo == null) {
            return Result.of(null, false, ResultEnum.USER_DOES_NOT_EXIST.getMessage(), ResultEnum.USER_DOES_NOT_EXIST.getCode());
        }
        map.put("gold", comUsersVo.getGold());
        map.put("address", comUsersVo.getAddress());
        return Result.of(map);
    }

}
