package com.ruoyi.cai.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.constant.RedisConstant;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.domain.UserGreet;
import com.ruoyi.cai.dto.admin.vo.UserGreetAdminVo;
import com.ruoyi.cai.dto.app.query.user.UserGreetAddReq;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.manager.LockManager;
import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.mapper.UserGreetMapper;
import com.ruoyi.cai.mapper.UserMapper;
import com.ruoyi.cai.service.UserGreetService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.yunxin.Yunxin;
import com.ruoyi.yunxin.resp.YxCommonR;
import com.ruoyi.yunxin.resp.YxDataR;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 群发审核Service业务层处理
 *
 * @author 77
 * @date 2024-01-01
 */
@Service
public class UserGreetServiceImpl extends ServiceImpl<UserGreetMapper,UserGreet> implements UserGreetService {


    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SystemConfigManager systemConfigManager;
    @Autowired
    private Yunxin yunxin;
    @Resource
    private UserMapper userMapper;

    @Override
    public List<UserGreet> listByUserId(Long userId) {
        return this.list(Wrappers.lambdaQuery(UserGreet.class)
                .eq(UserGreet::getUserId,userId));
    }

    @Override
    public void addUserGreet(UserGreetAddReq req) {
        User user = userService.getById(req.getUserId());
        if(user == null || user.getIsAnchor() == 0){
            throw new ServiceException("您不是女神，无法群发消息");
        }
        // 加锁 1秒
        String lockKey = LockManager.getAddUserGreetLock(req.getUserId());
        RLock lock = redissonClient.getLock(lockKey);
        if(lock.isLocked()){
            throw new ServiceException("请求太频繁");
        }
        try {
            lock.lock(1, TimeUnit.SECONDS);
            List<UserGreet> greets = this.listByUserId(req.getUserId());
            if(greets.size() > 10){
                throw new ServiceException("每人最多10条");
            }
            Set<String> set = greets.stream().map(UserGreet::getTitle).collect(Collectors.toSet());
            if(set.contains(req.getTitle())){
                throw new ServiceException("招呼内容已存在");
            }
            UserGreet userGreet = new UserGreet();
            userGreet.setUserId(req.getUserId());
            userGreet.setTitle(req.getTitle());
            this.save(userGreet);
        }finally {
            lock.unlock();
        }

    }

    @Override
    public void batchSend(Long id, Long userId) {
        UserGreet userGreet = this.getById(id);
        if(userGreet == null || !userGreet.getUserId().equals(userId)){
            throw new ServiceException("请选择打招呼内容");
        }
        if(userGreet.getAuditStatus() != 1){
            throw new ServiceException("内容未通过审核");
        }
        String lockKey = LockManager.getSendGreetLock(userId);
        RLock lock = redissonClient.getLock(lockKey);
        if(!lock.isLocked()){
            throw new ServiceException("操作太频繁");
        }
        try {
            lock.lock(3,TimeUnit.SECONDS);
            String numKey = String.format(RedisConstant.USER_GREET_TOTAL_REDIS, DateUtil.today(), userId);
            String val = stringRedisTemplate.opsForValue().get(numKey);
            Long max = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.TODAY_GREET_MAX);
            if(val != null && Long.parseLong(val) > max){
                throw new ServiceException("您今天打招呼的次数已经用完了");
            }
            String sendGreetLock = LockManager.getSendGreetLock(userId);
            String lastTime = stringRedisTemplate.opsForValue().getAndExpire(sendGreetLock, 1, TimeUnit.DAYS);
            if(StringUtils.isNotBlank(lastTime)){
                Integer inter = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.GREET_INTERVAL_MIN);
                long jiange = Long.parseLong(lastTime) - DateUtil.currentSeconds();
                long diff = inter - jiange;
                if(diff > 0){
                    if(diff > 60){
                        throw new ServiceException("请在"+diff/60+"分钟后再打招呼吧！");
                    }else{
                        throw new ServiceException("请在"+diff+"秒后再打招呼吧！");
                    }
                }
            }
            List<Long> toUserIds = userMapper.getGreetNumId(userId);
            if(CollectionUtil.isEmpty(toUserIds)){
                return;
            }
            YxDataR<YxCommonR> r = yunxin.batchSendToTextMessage(userId, toUserIds, userGreet.getTitle());
            if(!r.isSuccess()){
                throw new ServiceException("发送失败");
            }
            stringRedisTemplate.opsForValue().set(sendGreetLock,DateUtil.currentSeconds()+"",1,TimeUnit.DAYS);
            stringRedisTemplate.opsForValue().increment(numKey);
            stringRedisTemplate.expire(numKey,1,TimeUnit.DAYS);
        }finally {
            lock.unlock();
        }


    }

    @Override
    public Page<UserGreetAdminVo> pageAdmin(PageQuery pageQuery, UserGreetAdminVo bo) {
        return baseMapper.pageAdmin(pageQuery.build(),bo);
    }


}
