package com.sqx.modules.redisService.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import com.sqx.modules.redisService.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

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

import java.util.Map;

@Service
public class RedisServiceImpl implements RedisService {
    @Lazy
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private DiscSpinningAmountService amountService;

    @Override
    public void setDiscSpinningAmounts(String key) {
        List<DiscSpinningAmount> amounts = amountService.list(new QueryWrapper<DiscSpinningAmount>().eq("status", 1).orderByAsc("max_amount"));
        Map<Integer, List<DiscSpinningAmount>> map =
                amounts.stream().collect(Collectors.groupingBy(
                        disc -> disc.getNum() == null ? 0 : disc.getNum()
                ));
        redisUtils.set(key, map);
    }

    @Override
    public void setFreeWatchTime(Long userId, Integer second, boolean isPermanently) {
        Date now = DateUtil.date();
        Date tomorrow = DateUtil.beginOfDay(DateUtil.offsetDay(now, 1));
        String freeWatchKey = RedisKeys.getFreeWatchKey(userId, isPermanently);
        if (isPermanently) {
            String data = redisUtils.get(freeWatchKey);
            if (StrUtil.isBlank(data)) {
                redisUtils.set(freeWatchKey, second, -1);
            }else {
                Long expire = redisUtils.getExpire(freeWatchKey);
                if (expire == null) {
                    expire = -1L;
                }else {
                    expire += Long.valueOf(second);
                }
                redisUtils.set(freeWatchKey, second + Long.parseLong(data), expire);

            }
        }else {
            long expire = DateUtil.between(now, tomorrow, DateUnit.SECOND);
//            redisUtils.setIfAbsent(freeWatchKey, DateUtil.offsetSecond(now, second).getTime(), seconds);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("expireTime", -1);
            jsonObject.put("second", second);
            redisUtils.setIfAbsent(freeWatchKey, jsonObject.toJSONString(), expire);
        }
    }


    @Override
    public Boolean getFreeWatchTimeIsExpire(Long userId) {
        String freeWatchKey = RedisKeys.getFreeWatchKey(userId, true);
        String permanentlyFreeWatch = redisUtils.get(freeWatchKey);

        String watchKey = RedisKeys.getFreeWatchKey(userId, false);
        String payFreeWatchInfo = redisUtils.get(watchKey);
        Long expireTime = -1L;
        JSONObject jsonObject = null;
        if (StrUtil.isNotBlank(payFreeWatchInfo)) {
            jsonObject = JSONObject.parseObject(payFreeWatchInfo);
            expireTime = jsonObject.getLong("expireTime");
        }

        if ((StrUtil.isNotBlank(permanentlyFreeWatch) && redisUtils.isExpiredSet(freeWatchKey)) || (StrUtil.isNotBlank(permanentlyFreeWatch) && DateUtil.current() >= expireTime)) {
            if (StrUtil.isBlank(permanentlyFreeWatch)) {
                return null;
            }

            if (!redisUtils.isExpiredSet(freeWatchKey)) {
                redisUtils.expire(freeWatchKey, Long.parseLong(permanentlyFreeWatch));
            }
            return false;
        }else {
            if (StrUtil.isBlank(payFreeWatchInfo)) {
                return null;
            }

            Integer second = jsonObject.getInteger("second");
            if (expireTime == -1) {
                DateTime now = DateUtil.date();
                jsonObject.put("expireTime",  DateUtil.offsetSecond(now, second).getTime());
                Date tomorrow = DateUtil.beginOfDay(DateUtil.offsetDay(now, 1));
                long expire = DateUtil.between(now, tomorrow, DateUnit.SECOND);

                redisUtils.set(watchKey, jsonObject.toJSONString(), expire);
                return false;
            }else {
                return DateUtil.current() > expireTime;
            }
        }
    }

    @Override
    public Long getFreeWatchRemainTime(Long userId, boolean isPermanently) {
        String key = RedisKeys.getFreeWatchKey(userId, isPermanently);
        if (isPermanently) {
            String permanentlyFreeInfo = redisUtils.get(key);
            if (StrUtil.isBlank(permanentlyFreeInfo)) {
                return 0L;
            }

            Long expire = redisUtils.getExpire(key);
            return expire == null ? Long.valueOf(permanentlyFreeInfo) : expire;
        }


        String payFreeInfo = redisUtils.get(RedisKeys.getFreeWatchKey(userId, false));
        if (StrUtil.isBlank(payFreeInfo)) {
            return 0L;
        }

        JSONObject jsonObject = JSONObject.parseObject(payFreeInfo);
        Integer expireTime = jsonObject.getInteger("expireTime");
        Long second = jsonObject.getLong("second");

        return expireTime == -1 ? second : expireTime > DateUtil.current() ? expireTime - DateUtil.current() : 0L;
    }
}
