package com.zanxiang.game.platform.serve.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.game.platform.serve.dao.mapper.PlatformDeYangUserMapper;
import com.zanxiang.game.platform.serve.enums.GamePlatformEnum;
import com.zanxiang.game.platform.serve.pojo.dto.PlatformDeYangUserDTO;
import com.zanxiang.game.platform.serve.pojo.entity.PlatformDeYangUser;
import com.zanxiang.game.platform.serve.service.IPlatformDeYangUserService;
import com.zanxiang.module.redis.annotation.Lock;
import com.zanxiang.module.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : lingfeng
 * @time : 2023-05-22
 * @description : 德扬用户
 */
@Slf4j
@Service
public class PlatformDeYangUserServiceImpl extends ServiceImpl<PlatformDeYangUserMapper, PlatformDeYangUser> implements IPlatformDeYangUserService {

    @Override
    public Boolean addOrUpdate(PlatformDeYangUserDTO userDTO) {
        //判断用户信息是否已经存在
        PlatformDeYangUser platformDeYangUser = super.getById(userDTO.getUid());
        //已存在的用户, ua如果有的话不更新, 游戏方每次传过来的是当前登录的ua
        if (platformDeYangUser != null && Strings.isNotBlank(platformDeYangUser.getUserAgent())) {
            userDTO.setUser_agent(null);
        }
        //更新或者保存数据
        return super.saveOrUpdate(PlatformDeYangUser.builder()
                .uid(userDTO.getUid())
                .platformKey(GamePlatformEnum.DE_YANG.getPlatformKey())
                .mpOpenId(userDTO.getWecha_id())
                .qcSign(userDTO.getN_wecha_id())
                .time(Strings.isBlank(userDTO.getTime()) ? null : DateUtil.parseLocalDateTime(userDTO.getTime()))
                .tunnelId(userDTO.getTunnel_id())
                .updateTime(Strings.isBlank(userDTO.getUpdate_time()) ? null : DateUtil.parseLocalDateTime(userDTO.getUpdate_time()))
                .allPrice(userDTO.getAll_price())
                .gamePrice(userDTO.getGame_price())
                .mobile(userDTO.getMobile())
                .trueName(userDTO.getTrue_name())
                .code(userDTO.getCode())
                .gameName(userDTO.getGame_name())
                .roleName(userDTO.getRole_name())
                .roleArea(userDTO.getRole_area())
                .ip(userDTO.getIp())
                .appId(userDTO.getAppid())
                .appName(userDTO.getAppname())
                .userAgent(userDTO.getUser_agent())
                .agentId(userDTO.getAgent_id2())
                .build());
    }

    @Lock(prefix = "platform:deYangUserService:saveOrUpdate", waitTime = 3, leaseTime = 3, timeUnit = TimeUnit.MINUTES)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(List<PlatformDeYangUser> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            return true;
        }
        Map<Long, PlatformDeYangUser> oldMap = list(new LambdaQueryWrapper<PlatformDeYangUser>()
                .in(PlatformDeYangUser::getUid, userList.stream().map(PlatformDeYangUser::getUid).collect(Collectors.toList()))
        ).stream().collect(Collectors.toMap(PlatformDeYangUser::getUid, Function.identity()));
        List<PlatformDeYangUser> addList = new ArrayList<>(userList.size());
        for (PlatformDeYangUser user : userList) {
            PlatformDeYangUser old = oldMap.remove(user.getUid());
            if (old == null) {
                addList.add(user);
            } else {
                user.setUid(old.getUid());
                if (!user.equals(old)) {
                    updateById(user);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(addList)) {
            saveBatch(addList);
        }
        return true;
    }
}
