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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.game.back.serve.dao.mapper.GameTencentAppCallbackMapper;
import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppCallbackDTO;
import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppCallback;
import com.zanxiang.game.back.serve.service.IGameTencentAppCallbackService;
import com.zanxiang.game.module.base.ServerInfo;
import com.zanxiang.game.module.base.pojo.vo.AgentRpcVO;
import com.zanxiang.game.module.base.rpc.IAgentRpc;
import com.zanxiang.module.util.DateUtil;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.encryption.Md5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Slf4j
@Service
public class GameTencentAppCallbackServiceImpl extends ServiceImpl<GameTencentAppCallbackMapper, GameTencentAppCallback>
implements IGameTencentAppCallbackService {

    @Value("${spring.kafka.tencentAppCallbackTopic}")
    private String tencentAppCallbackTopic;
    @Autowired
    private KafkaProducer<String, String> kafkaProducer;
    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
    private IAgentRpc agentRpc;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean callback(GameTencentAppCallbackDTO dto) {
        AgentRpcVO agent = agentRpc.getByTencentAccountId(dto.getAccountId()).getData();
        if (agent == null) {
            log.error("腾讯检测链接数据找不到渠道：{}", JsonUtil.toString(dto));
        }
        GameTencentAppCallback appCallback = BeanUtil.copy(dto, GameTencentAppCallback.class);
        if (agent != null) {
            appCallback.setAgentKey(agent.getAgentKey());
            appCallback.setGameId(agent.getGameId());
        } else {
            appCallback.setAgentKey("-");
            appCallback.setGameId(-1L);
        }
        appCallback.setDay(dto.getClickTime() == null || dto.getClickTime() < 1000 ? LocalDate.now() : DateUtil.secondToLocalDate(dto.getClickTime()));
        save(appCallback);
        try {
            kafkaProducer.send(new ProducerRecord<>(tencentAppCallbackTopic, dto.getAccountId().toString(), JsonUtil.toString(appCallback)));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return true;
    }

    @Override
    public GameTencentAppCallback getUserCallback(Long gameId, String imei, String oaid, String android, String idfa, String caid, String ip, LocalDateTime regTime) {
        LambdaQueryWrapper<GameTencentAppCallback> qw = new LambdaQueryWrapper<GameTencentAppCallback>()
                .lt(GameTencentAppCallback::getClickTime, DateUtil.localDateTimeToSecond(regTime))
                .eq(GameTencentAppCallback::getGameId, gameId)
                .orderByDesc(GameTencentAppCallback::getClickTime)
                .last("limit 1");
        qw.and(and -> {
            if(StringUtils.isNoneBlank(imei)) {
                and.or().eq(GameTencentAppCallback::getMuid, Md5Util.encrypt32(imei.toLowerCase()).toLowerCase());
            }
            if(StringUtils.isNoneBlank(android)) {
                and.or().eq(GameTencentAppCallback::getHashAndroidId, Md5Util.encrypt32(android).toLowerCase());
            }
            if(StringUtils.isNoneBlank(oaid)) {
                and.or().eq(GameTencentAppCallback::getHashOaid, Md5Util.encrypt32(oaid).toLowerCase());
            }
            if(StringUtils.isNoneBlank(idfa)) {
                and.or().eq(GameTencentAppCallback::getMuid, Md5Util.encrypt32(idfa.toUpperCase()).toLowerCase());
            }
            and.or(StringUtils.isNoneBlank(ip), tmp -> {
                tmp.ge(GameTencentAppCallback::getClickTime, DateUtil.localDateTimeToSecond(regTime.plusDays(2)))
                        .eq(GameTencentAppCallback::getIp, ip);
            });
        });
        return getOne(qw);
    }
}
