package com.td.boss.game.comsnbapply.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.td.boss.common.controller.*;
import com.td.boss.common.pojo.PageInfo;
import com.td.boss.common.pojo.Result;
import com.td.boss.config.enums.ResultEnum;
import com.td.boss.game.comsnbapply.pojo.ComSnbApply;
import com.td.boss.game.comsnbapply.vo.ComSnbApplySimpleVo;
import com.td.boss.game.comsnbapply.vo.ComSnbApplyVo;
import com.td.boss.game.comsnbapply.service.ComSnbApplyService;
import com.td.boss.game.comusers.pojo.ComUsers;
import com.td.boss.game.comusers.service.ComUsersService;
import com.td.boss.game.comusers.vo.ComUsersVo;
import com.td.boss.util.CopyUtil;
import com.td.boss.util.DoubleUtil;
import com.td.boss.util.RedisData;
import com.td.boss.util.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/game/comSnbApply/")
public class ComSnbApplyController extends CommonController<ComSnbApplyVo, ComSnbApply, String> {
    @Autowired
    private ComSnbApplyService comSnbApplyService;

    @Autowired
    private ComUsersService comUsersService;

    @Autowired
    private RedisLock redisLock;


    @GetMapping("getPage")
    public Result<PageInfo<ComSnbApplyVo>> getPageFunction(@RequestParam(value = "userId") String userId,
                                                           @RequestParam(value = "isState") Integer isState,
                                                           @RequestParam(value = "page") Integer page,
                                                           @RequestParam(value = "limit") Integer limit) {
        ComSnbApplyVo comSnbApplyVo = new ComSnbApplyVo();
        comSnbApplyVo.setUserId(userId);
        comSnbApplyVo.setIsState(isState);
        comSnbApplyVo.setPage(page + 1);
        comSnbApplyVo.setRows(limit);
        comSnbApplyVo.setSidx("desc");
        comSnbApplyVo.setSord("createTime");
        return comSnbApplyService.page(comSnbApplyVo);
    }


    @PostMapping("applySnbToCnt")
    public Result<ComSnbApplyVo> applySnbToCntFunction(@RequestParam(value = "userId") String userId,
                                                       @RequestParam(value = "applyAmount") Integer applyAmount) {
        //加个锁
        String _redisKey = "applySnbToCnt:" + userId;
        //todo snb冻结加锁
        long time = System.currentTimeMillis() + RedisData.getUserApplyTimeout();

        try {
            // 防止重复操作
            if (!redisLock.lock(_redisKey, String.valueOf(time))) {
                return Result.of(null, false, ResultEnum.REDIS_IS_LOCK.getMessage(), ResultEnum.REDIS_IS_LOCK.getCode());
            }

            //判断输入数量，不能为负数
            if (applyAmount <= 0) {
                return Result.of(null, false, ResultEnum.APPLY_SNB_AMOUNT_ERROR.getMessage(), ResultEnum.APPLY_SNB_AMOUNT_ERROR.getCode());
            }
            // 判断当前是否累加超过当前用户的snb
            List<ComSnbApply> comSnbApplies = comSnbApplyService.findAllByUserIdAndIsState(userId, 0);
            List<ComSnbApply> comSnbApplies2 = comSnbApplyService.findAllByUserIdAndIsState(userId, 1);
            comSnbApplies2.stream().sequential().collect(Collectors.toCollection(() -> comSnbApplies));
            //记录一个当前申请的数据
            List<ComSnbApply> todayComSnbApply = new ArrayList<>();
            Date now = new Date();
            DateTime begin = DateUtil.beginOfDay(now);
            DateTime end = DateUtil.endOfDay(now);
            for (int i = 0; i < comSnbApplies.size(); i++) {
                if (applyAmount.equals(comSnbApplies.get(i).getSnb())) {
                    return Result.of(null, false, ResultEnum.APPLY_SNB_HAS_APPLY.getMessage(), ResultEnum.APPLY_SNB_HAS_APPLY.getCode());
                }
                //如果日期在指定范围内
                if (DateUtil.isIn(comSnbApplies.get(i).getCreateTime(), begin, end)) {
                    todayComSnbApply.add(comSnbApplies.get(i));
                }
            }
            Integer _applySnb = comSnbApplies.stream().mapToInt(ComSnbApply::getSnb).sum();
            //加上当前的
            _applySnb += applyAmount;

            ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
            double _allSnbDouble = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());
            if (DoubleUtil.compare(_allSnbDouble, _applySnb.doubleValue()).equals(-1)) {
                return Result.of(null, false, ResultEnum.APPLY_SNB_TOO_MUCH.getMessage(), ResultEnum.APPLY_SNB_TOO_MUCH.getCode());
            }

            ComSnbApplyVo comSnbApplyVo = new ComSnbApplyVo();
            comSnbApplyVo.setUserId(userId);
            comSnbApplyVo.setAddress(comUsersVo.getAddress());
            comSnbApplyVo.setSnb(applyAmount);
            comSnbApplyVo.setSnbDescribe("applySnbToCnt,发起兑换记录snb！");
            comSnbApplyVo.setIsState(0);
            comSnbApplyVo.setCount(todayComSnbApply.size() + 1); //当日申请的次数 + 1
            comSnbApplyVo.setCreateTime(new Date());
            comSnbApplyVo.setUpdateTime(new Date());


            //保存成功之后，刷新列表
            return comSnbApplyService.save(comSnbApplyVo);
        } catch (Exception e) {
            return Result.of(null, false, ResultEnum.REDIS_IS_LOCK_ERROR.getMessage(), ResultEnum.REDIS_IS_LOCK_ERROR.getCode());
        } finally {
            redisLock.unlock(_redisKey, String.valueOf(time));
        }


    }


    @PostMapping("checkApplySnbToCnt")
    public Result<ComSnbApplySimpleVo> checkApplySnbToCntFunction(@RequestParam(value = "userId") String userId,
                                                                  @RequestParam(value = "certificateId") String certificateId) {
        //加个锁
        String _redisKey = "checkApplySnbToCnt:" + userId;
        //todo snb冻结加锁
        long time = System.currentTimeMillis() + RedisData.getUserApplyTimeout();
        try {
            // 防止重复操作
            if (!redisLock.lock(_redisKey, String.valueOf(time))) {
                return Result.of(null, false, ResultEnum.REDIS_IS_LOCK.getMessage(), ResultEnum.REDIS_IS_LOCK.getCode());
            }

            ComSnbApplyVo comSnbApplyVo = comSnbApplyService.get(certificateId).getData();
            if (!comSnbApplyVo.getIsState().equals(1)) {
                return Result.of(null, false, ResultEnum.APPLY_SNB_STATE_ERROR.getMessage(), ResultEnum.APPLY_SNB_STATE_ERROR.getCode());
            }
            //判断申请的snb
            if (comSnbApplyVo.getSnb() <= 0) {
                comSnbApplyVo.setIsState(2);
                comSnbApplyService.save(comSnbApplyVo);
                return Result.of(null, false, ResultEnum.APPLY_SNB_AMOUNT_ERROR.getMessage(), ResultEnum.APPLY_SNB_AMOUNT_ERROR.getCode());
            }
            ComUsersVo comUsersVo = comUsersService.findByUserId(userId);
            double _allSnbDouble = DoubleUtil.add(comUsersVo.getSnb().doubleValue(), comUsersVo.getSnbPart());

            if (DoubleUtil.compare(_allSnbDouble, 0.0).equals(1) && DoubleUtil.compare(_allSnbDouble, comSnbApplyVo.getSnb().doubleValue()).equals(-1)) {
                //snb不足时候
                comSnbApplyVo.setIsState(2);
                comSnbApplyService.save(comSnbApplyVo);
                return Result.of(null, false, ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getMessage(), ResultEnum.WALLET_SNB_INSUFFICIENT_QUANTITY.getCode());
            }
            return Result.of(CopyUtil.copy(comSnbApplyVo, ComSnbApplySimpleVo.class));
        } catch (Exception e) {
            return Result.of(null, false, ResultEnum.REDIS_IS_LOCK_ERROR.getMessage(), ResultEnum.REDIS_IS_LOCK_ERROR.getCode());
        } finally {
            redisLock.unlock(_redisKey, String.valueOf(time));
        }
    }
}
