package com.reyun.saas.mob.user.task;


import com.reyun.saas.common.util.RedisUtils;
import com.reyun.saas.mob.user.dao.AppMapper;
import com.reyun.saas.mob.user.dao.ChannelMapper;
import com.reyun.saas.mob.user.dao.UserMapper;
import com.reyun.saas.mob.user.domain.App;
import com.reyun.saas.mob.user.domain.Channel;
import com.reyun.saas.report.realtimecommon.dao.ChannelInfoMapper;
import com.reyun.saas.report.realtimecommon.domain.ChannelInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 同步渠道管理的数据
 */
@Slf4j
@Component
public class SyncChannelTask {

    /**
     * 一天的时间
     */
    private static final Long oneDay = 1000L * 60L * 60L * 24L;

    @Resource
    private ChannelInfoMapper channelInfoMapper;

    @Resource
    private ChannelMapper channelMapper;

    @Resource
    private AppMapper appMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisUtils redisUtils;


    /**
     * 从实时数据库中渠道数据 同步数据到web的数据库中
     */
    @Async
    @Scheduled(cron = "0 0/30 * * * ?")
//    @Scheduled(cron = "0 * * * * ?")
    public void syncChannel() {
        //分布式锁
        if (!redisUtils.tryLock("syncChannelLock",10)) {
            log.info("另一台服务正在同步渠道中.......");
            return;
        }

        log.info("查询需要同步的渠道......");

        //校验同步需要同步的渠道
        List<ChannelInfo> channelInfoByDate = channelInfoMapper.findChannelInfoByDate();
        if (!CollectionUtils.isEmpty(channelInfoByDate)) {
            log.info("渠道开始同步 channel_info表中有{}未状态为未同步的数据{}", channelInfoByDate.size(),channelInfoByDate.toString());
            AtomicInteger count = new AtomicInteger();
            count.set(0);
            long start = System.currentTimeMillis();
            for (ChannelInfo channelInfo : channelInfoByDate) {
                if (channelInfo.getAppkey() == null || channelInfo.getCid() == null) {
                    continue;
                }

                try {
                    syncData(channelInfo,count);
                } catch (Exception e) {
                    log.error("app:{} 渠道:{} 同步失败! 异常信息:{}", channelInfo.getAppkey(), channelInfo.getCid(), e.getMessage());
                }
            }
            long end = System.currentTimeMillis();
            log.info("渠道同步完成! 这次同步了{}个新渠道,耗时{}毫秒", count.get() + "", (end - start) + "");
        }

    }


    /**
     * 同步渠道
     */
    private void syncData(ChannelInfo channelInfo,AtomicInteger count) {
        Example example = new Example(Channel.class);
        example.and().andEqualTo("appkey", channelInfo.getAppkey());
        example.and().andEqualTo("cid", channelInfo.getCid());
        List<Channel> channels = channelMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(channels)) {
            //同步数据

            //查询app
            Example appExample = new Example(App.class);
            appExample.and().andEqualTo("appkey",channelInfo.getAppkey());
            App app = appMapper.selectOneByExample(appExample);
            Channel channel = new Channel();
            channel.setCid(channelInfo.getCid());
            channel.setAppkey(channelInfo.getAppkey());
            channel.setSyncTime(new Date());
            channel.setModifyTime(new Date());
            channel.setActive(true);
            channel.setIsCustomAlias(false);
            //同步渠道的删除状态  如果app删除了 渠道同步后也是删除状态
            channel.setDelFlag(app.getDelFlag());
            Example channelExample = new Example(Channel.class);
            String channelName = null;

            //生成不重复的渠道名称
            while (true){
                channelName = defaultChannelName();
                channelExample.and().andEqualTo("appkey",channelInfo.getAppkey());
                channelExample.and().andEqualTo("channelAlias", channelName);
                List<Channel> channels1 = channelMapper.selectByExample(channelExample);
                if (CollectionUtils.isEmpty(channels1)) {
                    break;
                }
            }
            channel.setChannelAlias(channelName);
            channel.setIsCustomAlias(false);
            channelMapper.insertSelective(channel);
            channelInfoMapper.updateSyncStatus(channel.getAppkey(), channel.getCid());
            count.incrementAndGet();
        } else {
            //如果channel表中存在该数据  将实时的channel_info中状态改为已同步
            Channel channel = channels.get(0);
            channelInfoMapper.updateSyncStatus(channel.getAppkey(),channel.getCid());
        }


    }

    /**
     * 获取6位的随机字符串作为渠道名称
     */
    private static String defaultChannelName() {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String substring = uuid.substring(0, 6);
        return "未命名渠道-" + substring;
    }


}
