package com.zanxiang.game.module.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.erp.security.util.SecurityUtil;
import com.zanxiang.game.module.base.pojo.enums.BanStatusEnum;
import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
import com.zanxiang.game.module.manage.pojo.params.IpBanAddParam;
import com.zanxiang.game.module.manage.pojo.params.IpBanListParam;
import com.zanxiang.game.module.manage.pojo.params.IpBanUpdateParam;
import com.zanxiang.game.module.manage.pojo.vo.IpBanVO;
import com.zanxiang.game.module.manage.service.IGameService;
import com.zanxiang.game.module.manage.service.IIpBanService;
import com.zanxiang.game.module.mybatis.entity.IpBan;
import com.zanxiang.game.module.mybatis.mapper.IpBanMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author : lingfeng
 * @time : 2022-06-28
 * @description : ip封禁管理
 */
@Slf4j
@Service
public class IpBanServiceImpl extends ServiceImpl<IpBanMapper, IpBan> implements IIpBanService {

    @Autowired
    private IGameService gameService;

    @Override
    public IPage<IpBanVO> list(IpBanListParam param) {
        return page(param.toPage(), new QueryWrapper<IpBan>().lambda()
                .eq(Strings.isNotBlank(param.getIp()), IpBan::getIp, param.getIp())
                .eq(param.getGameId() != null, IpBan::getGameId, param.getGameId())
                .eq(param.getStatus() != null, IpBan::getStatus, param.getStatus())
                .ge(param.getBeginDate() != null, IpBan::getBanTime, param.getBeginDate() == null ? null : LocalDateTime.of(param.getBeginDate(), LocalTime.MIN))
                .le(param.getEndDate() != null, IpBan::getBanTime, param.getEndDate() == null ? null : LocalDateTime.of(param.getEndDate(), LocalTime.MAX))
                .orderByDesc(IpBan::getCreateTime))
                .convert(this::toVo);
    }

    private IpBanVO toVo(IpBan ipBan) {
        if (Objects.isNull(ipBan)) {
            return null;
        }
        IpBanVO ipBanVO = BeanUtil.copy(ipBan, IpBanVO.class);
        GameDTO gameDTO = gameService.getById(ipBanVO.getGameId());
        ipBanVO.setGameName(gameDTO == null ? null : gameDTO.getName());
        return ipBanVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addIp(IpBanAddParam param) {
        List<IpBan> list = new ArrayList<>();
        param.getIpList().forEach(ip -> {
            //先查询是否已经存在
            IpBan ipBan = super.getOne(new LambdaQueryWrapper<IpBan>()
                    .eq(IpBan::getGameId, param.getGameId()).eq(IpBan::getIp, ip));
            if (ipBan == null) {
                ipBan = IpBan.builder()
                        .ip(ip)
                        .gameId(param.getGameId())
                        .banTime(LocalDateTime.now())
                        .status(BanStatusEnum.BAN_STATUS.getStatus())
                        .operateId(SecurityUtil.getUserId())
                        .operateName(SecurityUtil.getTokenInfo().getNickname())
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build();
            } else {
                if (ipBan.getStatus() == 0) {
                    ipBan.setStatus(BanStatusEnum.BAN_STATUS.getStatus());
                    ipBan.setBanTime(LocalDateTime.now());
                    ipBan.setUpdateTime(LocalDateTime.now());
                    ipBan.setOperateId(SecurityUtil.getUserId());
                    ipBan.setOperateName(SecurityUtil.getTokenInfo().getNickname());
                }
            }
            list.add(ipBan);
        });
        return super.saveOrUpdateBatch(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean ipBanOrRemove(IpBanUpdateParam param) {
        return super.update(new LambdaUpdateWrapper<IpBan>()
                .set(IpBan::getStatus, param.getStatus())
                .set(IpBan::getBanTime, Objects.equals(param.getStatus(), BanStatusEnum.BAN_STATUS.getStatus()) ? LocalDateTime.now() : null)
                .set(IpBan::getOperateId, SecurityUtil.getUserId())
                .set(IpBan::getOperateName, SecurityUtil.getTokenInfo().getNickname())
                .set(IpBan::getUpdateTime, LocalDateTime.now())
                .eq(IpBan::getIp, param.getIp())
        );
    }
}
