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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.base.ErpServer;
import com.zanxiang.erp.base.rpc.ISysUserRpc;
import com.zanxiang.erp.security.util.SecurityUtil;
import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
import com.zanxiang.game.module.manage.pojo.params.GameVipAddBatchParam;
import com.zanxiang.game.module.manage.pojo.params.GameVipAddParam;
import com.zanxiang.game.module.manage.pojo.params.GameVipListParam;
import com.zanxiang.game.module.manage.pojo.vo.GameVipListVO;
import com.zanxiang.game.module.manage.service.IGameService;
import com.zanxiang.game.module.manage.service.IGameSupperService;
import com.zanxiang.game.module.manage.service.IGameVipService;
import com.zanxiang.game.module.mybatis.entity.GameSupper;
import com.zanxiang.game.module.mybatis.entity.GameVip;
import com.zanxiang.game.module.mybatis.mapper.GameVipMapper;
import com.zanxiang.module.util.exception.BaseException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author tianhua
 * @version 1.0
 * @description: 游戏档位服务实现层
 * @date 2023/11/20 14:31
 */
@Service
public class GameVipServiceImpl extends ServiceImpl<GameVipMapper, GameVip> implements IGameVipService {

    @Autowired
    private IGameService gameService;
    @Autowired
    private IGameSupperService gameSupperService;
    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private ISysUserRpc sysUserRpc;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrUpdate(GameVipAddParam param) {
        //获取当前操作者id
        Long sysUserId = SecurityUtil.getUserId();

        if (param.getRechargeMoneyMax().compareTo(param.getRechargeMoneyMin()) <= 0) {
            throw new BaseException("档位参数设置有误，请重新输入。");
        }
        //当前操作时间
        LocalDateTime now = LocalDateTime.now();

        //不传入id，说明是新增档位；传入id说明是修改档位
        long count = count(new LambdaQueryWrapper<GameVip>()
                .ne(param.getId() != null, GameVip::getId, param.getId())
                .eq(GameVip::getSuperGameId, param.getSuperGameId())
                .eq(GameVip::getParentGameId, param.getParentGameId())
                .eq(GameVip::getVipLevel, param.getVipLevel())
                .eq(GameVip::getIsDelete, 0)
        );
        if (count > 0) {
            throw new BaseException("该游戏的vip等级已经设置过，请勿重复设置");
        }

        //GameVip实体
        GameVip gameVip = GameVip.builder()
                .parentGameId(param.getParentGameId())
                .superGameId(param.getSuperGameId())
                .rechargeMoneyMin(param.getRechargeMoneyMin())
                .rechargeMoneyMax(param.getRechargeMoneyMax())
                .vipLevel(param.getVipLevel())
                .updateTime(now)
                .updateBy(sysUserId)
                .build();

        //修改档位
        if (param.getId() != null) {
            gameVip.setId(param.getId());
            return updateById(gameVip);
        }

        //新增档位
        gameVip.setCreateBy(sysUserId);
        gameVip.setCreateTime(now);
        return save(gameVip);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(List<Long> ids) {
        Long sysUserId = SecurityUtil.getUserId();
        return update(new LambdaUpdateWrapper<GameVip>()
                .set(GameVip::getIsDelete, 1)
                .set(GameVip::getUpdateBy, sysUserId)
                .set(GameVip::getUpdateTime, LocalDateTime.now())
                .in(GameVip::getId, ids)
        );
    }

    @Override
    public IPage<GameVipListVO> gameVipList(GameVipListParam param) {
        return page(param.toPage(), new LambdaQueryWrapper<GameVip>()
                .eq(null != param.getSuperGameId(), GameVip::getSuperGameId, param.getSuperGameId())
                .eq(null != param.getParentGameId(), GameVip::getParentGameId, param.getParentGameId())
                .eq(null != param.getVipLevel(), GameVip::getVipLevel, param.getVipLevel())
                .eq(GameVip::getIsDelete, 0))
                .convert(this::toVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addBatch(GameVipAddBatchParam param) {
        checkParam(param);
        Long sysUserId = SecurityUtil.getUserId();
        LocalDateTime now = LocalDateTime.now();
        //得到需要添加的vip列表的所有vip等级
        List<Integer> vipList = param.getList().stream()
                .map(GameVipAddBatchParam.GameVipParam::getVipLevel).collect(Collectors.toList());

        long count = count(new LambdaQueryWrapper<GameVip>()
                .eq(GameVip::getSuperGameId, param.getSuperGameId())
                .in(GameVip::getParentGameId, param.getParentGameId())
                .in(GameVip::getVipLevel, vipList)
                .eq(GameVip::getIsDelete, 0));
        if (count > 0) {
            throw new BaseException("已经存在需要添加的VIP等级，请勿重复设置。");
        }
        //总共需要建多少个GameVip实例
        int size = param.getParentGameId().size() * param.getList().size();
        List<GameVip> list = new ArrayList<>(size);
        for (int i = 0; i < param.getParentGameId().size(); i++) {
            //父游戏ID
            Long parentGameId = param.getParentGameId().get(i);
            for (GameVipAddBatchParam.GameVipParam gameVipParam : param.getList()) {
                list.add(GameVip.builder()
                        .parentGameId(parentGameId)
                        .superGameId(param.getSuperGameId())
                        .rechargeMoneyMin(gameVipParam.getRechargeMoneyMin())
                        .rechargeMoneyMax(gameVipParam.getRechargeMoneyMax())
                        .vipLevel(gameVipParam.getVipLevel())
                        .createBy(sysUserId)
                        .createTime(now)
                        .updateTime(now)
                        .updateBy(sysUserId)
                        .build());
            }
        }
        return saveBatch(list);
    }

    private void checkParam(GameVipAddBatchParam param) {
        if (CollectionUtils.isEmpty(param.getList())) {
            throw new BaseException("至少创建一个VIP档位。");
        }
        List<Integer> collect = param.getList().stream()
                .map(GameVipAddBatchParam.GameVipParam::getVipLevel).collect(Collectors.toList())
                .stream().distinct().collect(Collectors.toList());
        if (collect.size() != param.getList().size()) {
            throw new BaseException("不能创建重复的VIP档位。");
        }
    }

    private GameVipListVO toVO(GameVip vo) {
        GameDTO game = gameService.getById(vo.getParentGameId());
        GameSupper gameSupper = gameSupperService.getById(vo.getSuperGameId());
        return GameVipListVO.builder()
                .id(vo.getId())
                .superGameId(vo.getSuperGameId())
                .superGameName(null == gameSupper ? null : gameSupper.getName())
                .parentGameId(vo.getParentGameId())
                .parentGameName(null == game ? null : game.getName())
                .rechargeMoneyMin(vo.getRechargeMoneyMin())
                .rechargeMoneyMax(vo.getRechargeMoneyMax())
                .vipLevel(vo.getVipLevel())
                .createTime(vo.getCreateTime())
                .createBy(vo.getCreateBy())
                .createName(sysUserRpc.getById(vo.getCreateBy()).getData().getNickname())
                .updateTime(vo.getUpdateTime())
                .updateBy(vo.getUpdateBy())
                .updateName(sysUserRpc.getById(vo.getUpdateBy()).getData().getNickname())
                .build();
    }

}
