package com.ruoyi.cai.service.impl;

import com.alibaba.fastjson.JSON;
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.domain.Anchor;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.domain.UserForbid;
import com.ruoyi.cai.domain.UserForbidLog;
import com.ruoyi.cai.dto.admin.vo.UserForbidAdminVo;
import com.ruoyi.cai.enums.ForbidTimeEnum;
import com.ruoyi.cai.enums.ForbidTypeEnum;
import com.ruoyi.cai.manager.ForbidCache;
import com.ruoyi.cai.mapper.UserForbidMapper;
import com.ruoyi.cai.mq.AmqpProducer;
import com.ruoyi.cai.mq.dto.CommonDelayDto;
import com.ruoyi.cai.service.AnchorService;
import com.ruoyi.cai.service.UserForbidService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.core.domain.PageQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

/**
 * 封号列表Service业务层处理
 *
 * @author 77
 * @date 2023-12-21
 */
@Service
@Slf4j
public class UserForbidServiceImpl extends ServiceImpl<UserForbidMapper, UserForbid> implements UserForbidService {

    @Autowired
    private UserService userService;
    @Autowired
    private AnchorService anchorService;
    @Autowired
    private ForbidCache forbidCache;
    @Autowired
    private AmqpProducer amqpProducer;

    @Override
    public void forbid(UserForbidLog userForbidLog, User user) {
        ForbidTimeEnum forbidTime = ForbidTimeEnum.getByCode(userForbidLog.getForbidTime());
        ForbidTypeEnum forbidType = ForbidTypeEnum.getByCode(userForbidLog.getType());
        if(forbidTime == null || forbidType == null){
            log.error("封禁入参错误 data={}", JSON.toJSONString(userForbidLog));
            return;
        }
        UserForbid one = this.getOne(Wrappers.lambdaQuery(UserForbid.class)
                .eq(UserForbid::getMember, userForbidLog.getMember())
                .eq(UserForbid::getType, forbidType.getCode()));
        if(one == null){
            one = new UserForbid();
            one.setType(userForbidLog.getType());
            one.setMember(userForbidLog.getMember());
            one.setBeginTime(LocalDateTime.now());
        } else if(one.getForbidStatus() == 2){ // 已解封
            one.setBeginTime(LocalDateTime.now());
        } else if(one.getForbidStatus() == 1 && one.getEndTime().isBefore(LocalDateTime.now())){
            one.setBeginTime(LocalDateTime.now());
        }
        LocalDateTime endTime = getEndTime(one.getBeginTime(), forbidTime);
        if(endTime == null){
            return;
        }
        one.setEndTime(endTime);
        one.setReason(userForbidLog.getReason());
        one.setForbidStatus(1);
        this.saveOrUpdate(one);
        if(user != null){
            userService.update(Wrappers.lambdaUpdate(User.class).eq(User::getId,user.getId()).set(User::getStatus,1));
            anchorService.update(Wrappers.lambdaUpdate(Anchor.class).eq(Anchor::getId,user.getId()).set(Anchor::getStatus,1));
        }
        forbidCache.addForbid(one);
        try {
            // 后者 - 前者 < 12小时
            long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), endTime);
            CommonDelayDto dto = new CommonDelayDto();
            dto.setForbidId(one.getId());
            dto.setType(2);
            amqpProducer.sendCommonDelayMq(dto,(int)between+2);
        }catch (Exception e){
            log.error("延时任务发送失败!");
        }

    }

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

    private LocalDateTime getEndTime(LocalDateTime beginTime, ForbidTimeEnum time){
        switch (time){
            case DAY_1:
                return beginTime.plusDays(1);
            case DAY_3:
                return beginTime.plusDays(3);
            case DAY_7:
                return beginTime.plusDays(7);
            case HOUSE_6:
                return beginTime.plusHours(6);
            case MONTH_1:
                return beginTime.plusMonths(1);
            case YEAR_10:
                return beginTime.plusYears(10);
            default:
                break;
        }
        return null;
    }
}
