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.UserDTO;
import com.zanxiang.game.module.manage.pojo.params.UserBanListParam;
import com.zanxiang.game.module.manage.pojo.params.UserBanUpdateParam;
import com.zanxiang.game.module.manage.pojo.vo.UserBanVO;
import com.zanxiang.game.module.manage.service.IUserBanService;
import com.zanxiang.game.module.manage.service.IUserCardService;
import com.zanxiang.game.module.manage.service.IUserService;
import com.zanxiang.game.module.mybatis.entity.User;
import com.zanxiang.game.module.mybatis.entity.UserBan;
import com.zanxiang.game.module.mybatis.entity.UserCard;
import com.zanxiang.game.module.mybatis.mapper.UserBanMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
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.Objects;

/**
 * @author : lingfeng
 * @time : 2022-06-28
 * @description : 玩家封禁管理
 */
@Slf4j
@Service
public class UserBanServiceImpl extends ServiceImpl<UserBanMapper, UserBan> implements IUserBanService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IUserCardService userCardService;

    @Override
    public IPage<UserBanVO> list(UserBanListParam param) {
        return page(param.toPage(), new QueryWrapper<UserBan>().lambda()
                .eq(Strings.isNotBlank(param.getUserId()), UserBan::getUserId, param.getUserId())
                .eq(Strings.isNotBlank(param.getUserName()), UserBan::getUserName, param.getUserName())
                .eq(Strings.isNotBlank(param.getUserNickName()), UserBan::getUserNickName, param.getUserNickName())
                .ge(param.getRegBeginTime() != null, UserBan::getRegTime, param.getRegBeginTime() == null ? null : LocalDateTime.of(param.getRegBeginTime(), LocalTime.MIN))
                .le(param.getRegEndTime() != null, UserBan::getRegTime, param.getRegEndTime() == null ? null : LocalDateTime.of(param.getRegEndTime(), LocalTime.MAX))
                .ge(param.getBeginDate() != null, UserBan::getBanTime, param.getBeginDate() == null ? null : LocalDateTime.of(param.getBeginDate(), LocalTime.MIN))
                .le(param.getEndDate() != null, UserBan::getBanTime, param.getEndDate() == null ? null : LocalDateTime.of(param.getEndDate(), LocalTime.MAX))
                .orderByDesc(UserBan::getCreateTime))
                .convert(this::toVO);
    }

    private UserBanVO toVO(UserBan userBan) {
        if (Objects.isNull(userBan)) {
            return null;
        }
        return BeanUtil.copy(userBan, UserBanVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOrUpdate(UserBanUpdateParam param) {
        //查询用户信息
        UserDTO userDTO = userService.getById(param.getUserId());
        if (userDTO == null) {
            throw new BaseException("参数错误, 玩家信息不存在");
        }
        //更新用户信息
        userService.update(new LambdaUpdateWrapper<User>()
                .set(User::getStatus, param.getStatus())
                .set(User::getUpdateTime, LocalDateTime.now())
                .eq(User::getId, param.getUserId()));
        //查询玩家封禁信息
        UserBan userBan = super.getOne(new LambdaQueryWrapper<UserBan>().eq(UserBan::getUserId, param.getUserId()));
        //已存在的玩家直接更新
        if (userBan != null) {
            return super.update(new LambdaUpdateWrapper<UserBan>()
                    .set(UserBan::getStatus, param.getStatus())
                    .set(UserBan::getBanTime, Objects.equals(param.getStatus(), BanStatusEnum.BAN_STATUS.getStatus()) ? LocalDateTime.now() : null)
                    .set(UserBan::getOperateId, SecurityUtil.getUserId())
                    .set(UserBan::getOperateName, SecurityUtil.getTokenInfo().getNickname())
                    .set(UserBan::getUpdateTime, LocalDateTime.now())
                    .eq(UserBan::getUserId, param.getUserId()));
        }
        //添加玩家封禁信息
        userBan = this.transform(userDTO, param.getStatus());
        //查询玩家实名信息
        UserCard userCard = userCardService.getOne(new LambdaQueryWrapper<UserCard>()
                .eq(UserCard::getUserId, userBan.getUserId())
                .orderByDesc(UserCard::getCreateTime)
                .last("limit 1"));
        if (userCard != null && Strings.isNotBlank(userCard.getCardId())) {
            userBan.setCardId(userCard.getCardId());
        }
        return super.save(userBan);
    }

    private UserBan transform(UserDTO userDTO, Integer status) {
        return UserBan.builder()
                .userId(userDTO.getId())
                .gameId(userDTO.getGameId())
                .userName(userDTO.getUsername())
                .userNickName(userDTO.getNickname())
                .regTime(userDTO.getCreateTime())
                .banTime(LocalDateTime.now())
                .status(status)
                .ip(Strings.isNotBlank(userDTO.getIp()) ? userDTO.getIp() : null)
                .mac(Strings.isNotBlank(userDTO.getMac()) ? userDTO.getMac() : null)
                .imei(Strings.isNotBlank(userDTO.getImei()) ? userDTO.getImei() : null)
                .oaid(Strings.isNotBlank(userDTO.getOaid()) ? userDTO.getOaid() : null)
                .androidId(Strings.isNotBlank(userDTO.getAndroidId()) ? userDTO.getAndroidId() : null)
                .idfa(Strings.isNotBlank(userDTO.getIdfa()) ? userDTO.getIdfa() : null)
                .caid(Strings.isNotBlank(userDTO.getCaid()) ? userDTO.getCaid() : null)
                .operateId(SecurityUtil.getUserId())
                .operateName(SecurityUtil.getTokenInfo().getNickname())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
    }

}
