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.core.toolkit.CollectionUtils;
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.base.pojo.enums.DeleteEnum;
import com.zanxiang.game.module.manage.pojo.params.GameAuthRoleGroupAddParam;
import com.zanxiang.game.module.manage.pojo.params.GameAuthRoleGroupListParam;
import com.zanxiang.game.module.manage.pojo.vo.GameAuthRoleGroupVO;
import com.zanxiang.game.module.manage.service.IGameAuthRoleGroupService;
import com.zanxiang.game.module.mybatis.entity.GameAuthRoleGroup;
import com.zanxiang.game.module.mybatis.mapper.GameAuthRoleGroupMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
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.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2024-05-20
 * @description : 游戏授权角色分组
 */
@Slf4j
@Service
public class GameAuthRoleGroupServiceImpl extends ServiceImpl<GameAuthRoleGroupMapper, GameAuthRoleGroup> implements IGameAuthRoleGroupService {

    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private ISysUserRpc sysUserRpc;

    @Override
    public IPage<GameAuthRoleGroupVO> listOfPage(GameAuthRoleGroupListParam param) {
        IPage<GameAuthRoleGroupVO> gameAuthRoleGroupPage = page(param.toPage(), new QueryWrapper<GameAuthRoleGroup>().lambda()
                .eq(GameAuthRoleGroup::getGroupId, param.getGroupId())
                .eq(param.getUserId() != null, GameAuthRoleGroup::getUserId, param.getUserId())
                .eq(param.getIsLeader() != null, GameAuthRoleGroup::getIsLeader, param.getIsLeader())
                .orderByDesc(GameAuthRoleGroup::getCreateTime)
        ).convert(this::toVo);
        List<GameAuthRoleGroupVO> records = gameAuthRoleGroupPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return gameAuthRoleGroupPage;
        }
        List<Long> userIdList = records.stream().map(GameAuthRoleGroupVO::getUserId)
                .distinct().collect(Collectors.toList());
        Map<Long, String> userNameMap = sysUserRpc.getUserNameByIds(userIdList).getData();
        records.forEach(r -> r.setUserName(userNameMap.get(r.getUserId())));
        return gameAuthRoleGroupPage;
    }

    private GameAuthRoleGroupVO toVo(GameAuthRoleGroup gameAuthRoleGroup) {
        if (Objects.isNull(gameAuthRoleGroup)) {
            return null;
        }
        return BeanUtil.copy(gameAuthRoleGroup, GameAuthRoleGroupVO.class);
    }

    @Override
    public boolean leaderUpdate(Long groupId, Long userId, boolean isLeader) {
        return super.update(new LambdaUpdateWrapper<GameAuthRoleGroup>()
                .set(GameAuthRoleGroup::getIsLeader, isLeader)
                .set(GameAuthRoleGroup::getUpdateBy, SecurityUtil.getUserId())
                .set(GameAuthRoleGroup::getUpdateTime, LocalDateTime.now())
                .eq(GameAuthRoleGroup::getGroupId, groupId)
                .eq(GameAuthRoleGroup::getUserId, userId)
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean groupAddUser(GameAuthRoleGroupAddParam param) {
        List<GameAuthRoleGroup> addList = new ArrayList<>();
        param.getUserIdList().forEach(userId -> {
            if (super.count(new LambdaQueryWrapper<GameAuthRoleGroup>()
                    .eq(GameAuthRoleGroup::getGroupId, param.getGroupId())
                    .eq(GameAuthRoleGroup::getUserId, userId)
            ) > 0) {
                return;
            }
            addList.add(this.transform(param.getGroupId(), userId));
        });
        return super.saveBatch(addList);
    }

    private GameAuthRoleGroup transform(Long groupId, Long userId) {
        return GameAuthRoleGroup.builder()
                .userId(userId)
                .groupId(groupId)
                .isLeader(Boolean.FALSE)
                .isDelete(DeleteEnum.NO.getCode())
                .createBy(SecurityUtil.getUserId())
                .createTime(LocalDateTime.now())
                .build();
    }

    @Override
    public boolean deleteById(Long id) {
        return super.removeById(id);
    }
}
