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.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.manage.pojo.params.RoleMailRecordAddParam;
import com.zanxiang.game.module.manage.pojo.params.RoleMailRecordListParam;
import com.zanxiang.game.module.manage.pojo.vo.RoleMailRecordListVO;
import com.zanxiang.game.module.manage.service.IRoleMailRecordService;
import com.zanxiang.game.module.manage.service.IRoleOperateService;
import com.zanxiang.game.module.mybatis.entity.RoleMailRecord;
import com.zanxiang.game.module.mybatis.entity.RoleOperate;
import com.zanxiang.game.module.mybatis.mapper.RoleMailRecordMapper;
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.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色邮件发送记录表 服务实现类
 * </p>
 *
 * @author auto
 * @since 2023-09-09
 */
@Service
public class RoleMailRecordServiceImpl extends ServiceImpl<RoleMailRecordMapper, RoleMailRecord> implements IRoleMailRecordService {
    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private ISysUserRpc sysUserRpc;
    @Autowired
    private IRoleOperateService roleOperateService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrUpdate(RoleMailRecordAddParam param) {
        Long sysUserId = SecurityUtil.getUserId();
        LocalDateTime now = LocalDateTime.now();
        if (CollectionUtils.isEmpty(param.getIds())) {
            List<RoleMailRecord> roleMailRecordList = param.getRoleInfoList().stream()
                    .map(item -> RoleMailRecord.builder()
                            .gameId(item.getGameId())
                            .serverId(item.getServerId())
                            .userId(item.getUserId())
                            .roleId(item.getRoleId())
                            .sendTime(param.getSendTime())
                            .createBy(sysUserId)
                            .createTime(now)
                            .updateBy(sysUserId)
                            .updateTime(now)
                            .build()).collect(Collectors.toList());
            saveBatch(roleMailRecordList);
            List<RoleOperate> roleOperateList = param.getRoleInfoList().stream()
                    .map(item -> {
                        RoleOperate roleOperate = RoleOperate.builder().build();
                        RoleOperate queryOne = roleOperateService.getOne(new LambdaQueryWrapper<RoleOperate>()
                                .eq(RoleOperate::getGameId, item.getGameId())
                                .eq(RoleOperate::getServerId, item.getServerId())
                                .eq(RoleOperate::getUserId, item.getUserId())
                                .eq(RoleOperate::getRoleId, item.getRoleId())
                                .eq(RoleOperate::getIsDelete, 0));
                        if (null == queryOne) {
                            roleOperate.setGameId(item.getGameId());
                            roleOperate.setServerId(item.getServerId());
                            roleOperate.setUserId(item.getUserId());
                            roleOperate.setRoleId(item.getRoleId());
                            roleOperate.setCreateBy(sysUserId);
                            roleOperate.setCreateTime(now);
                        } else {
                            roleOperate = queryOne;
                        }
                        roleOperate.setIsSendMail(1);
                        roleOperate.setUpdateBy(sysUserId);
                        roleOperate.setUpdateTime(now);
                        return roleOperate;
                    }).collect(Collectors.toList());
            return roleOperateService.saveOrUpdateBatch(roleOperateList);
        } else {
            return update(new LambdaUpdateWrapper<RoleMailRecord>()
                    .set(RoleMailRecord::getSendTime, param.getSendTime())
                    .set(RoleMailRecord::getUpdateBy, sysUserId)
                    .set(RoleMailRecord::getUpdateTime, now)
                    .in(RoleMailRecord::getId, param.getIds()));
        }

    }

    @Override
    public IPage<RoleMailRecordListVO> listOfPage(RoleMailRecordListParam param) {
        return page(param.toPage(), new LambdaQueryWrapper<RoleMailRecord>()
                .eq(RoleMailRecord::getGameId, param.getGameId())
                .eq(RoleMailRecord::getServerId, param.getServerId())
                .eq(RoleMailRecord::getUserId, param.getUserId())
                .eq(RoleMailRecord::getRoleId, param.getRoleId())
                .ge(null != param.getStartDateTime(), RoleMailRecord::getSendTime, param.getStartDateTime())
                .le(null != param.getEndDateTime(), RoleMailRecord::getSendTime, param.getEndDateTime())
                .eq(RoleMailRecord::getIsDelete, 0)
                .orderByDesc(RoleMailRecord::getCreateTime))
                .convert(item -> RoleMailRecordListVO.builder()
                        .id(item.getId())
                        .sendTime(item.getSendTime())
                        .createBy(item.getCreateBy())
                        .createName(sysUserRpc.getById(item.getCreateBy()).getData().getNickname())
                        .createTime(item.getCreateTime())
                        .updateBy(item.getUpdateBy())
                        .updateName(sysUserRpc.getById(item.getUpdateBy()).getData().getNickname())
                        .updateTime(item.getUpdateTime())
                        .build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(List<Long> ids) {
        Long sysUserId = SecurityUtil.getUserId();
        RoleMailRecord roleMailRecord = listByIds(ids).get(0);
        update(new LambdaUpdateWrapper<RoleMailRecord>()
                .set(RoleMailRecord::getIsDelete, 1)
                .set(RoleMailRecord::getUpdateBy, sysUserId)
                .set(RoleMailRecord::getUpdateTime, LocalDateTime.now())
                .in(RoleMailRecord::getId, ids));
        return hasMai(roleMailRecord.getGameId(), roleMailRecord.getServerId(), roleMailRecord.getUserId(), roleMailRecord.getRoleId());
    }

    private boolean hasMai(Long gameId, String serverId, Long userId, String roleId) {
        long count = count(new LambdaQueryWrapper<RoleMailRecord>()
                .eq(RoleMailRecord::getGameId, gameId)
                .eq(RoleMailRecord::getServerId, serverId)
                .eq(RoleMailRecord::getUserId, userId)
                .eq(RoleMailRecord::getRoleId, roleId)
                .eq(RoleMailRecord::getIsDelete, 0));
        return roleOperateService.update(new LambdaUpdateWrapper<RoleOperate>()
                .set(RoleOperate::getIsSendMail, count > 0 ? 1 : 0)
                .eq(RoleOperate::getGameId, gameId)
                .eq(RoleOperate::getServerId, serverId)
                .eq(RoleOperate::getUserId, userId)
                .eq(RoleOperate::getRoleId, roleId));
    }
}
