package com.sptg.ad.biz.quartz;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.sptg.ad.api.entity.DeviceAdvertStatistics;
import com.sptg.ad.api.entity.EarlyWarning;
import com.sptg.ad.biz.service.DeviceAdvertStatisticsService;
import com.sptg.ad.biz.service.EarlyWarningService;
import com.sptg.common.core.interfaces.VoidInterface;
import com.sptg.common.core.util.DateUtil;
import com.sptg.statistics.api.dto.StatisticsAdPlayFreeTimeDto;
import com.sptg.statistics.api.dto.StatisticsAdWatchDto;
import com.sptg.statistics.api.feigns.StatisticsAdWatchFeign;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 *            
 *                
 * description: 设备广告预警定时任务
 */
@Slf4j
@Component
@AllArgsConstructor
public class EarlyWarningQuartzTask {

    private final RedisTemplate<String,String> redisTemplate;
    private final EarlyWarningService earlyWarningService;
    private final DeviceAdvertStatisticsService deviceAdvertStatisticsService;
    private final StatisticsAdWatchFeign statisticsAdWatchFeign;

    /**
     * 人脸广告预警
     * 每天1点时运行一次
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void faceAdvertEarlyWarning(){
        this.compute(1,(earlyWarning) -> {
            //  TODO 给 value 字段赋值即可
            long value = 0L;
            StatisticsAdWatchDto dto=new StatisticsAdWatchDto();
            //设备
            dto.setSerialNumber(earlyWarning.getSerialNumber());
            Calendar calendar= Calendar.getInstance();
            calendar.setTime(new Date());
            if (earlyWarning.getType() == 1){
                //  月预警-人脸广告
                //  value = 1000L;
                calendar.add(Calendar.MONTH,-1);
                //上一个月
                dto.setSelectMonth(calendar.getTime());
                value=statisticsAdWatchFeign.getAdWatchCount(dto);
            } else {
                //  周预警-人脸广告
                //  value = 1000L;
                //上一周
                int yearWeek = DateUtil.getYearWeek(new Date(), Calendar.MONTH)-1;
                dto.setYearWeek(yearWeek);
                value=statisticsAdWatchFeign.getAdWatchCount(dto);
            }
            earlyWarning.setValue(value);
        });
    }

    /**
     * 闲时广告预警
     * 每天1点时运行一次
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void leisureAdvertEarlyWarning(){
        this.compute(2,(earlyWarning) -> {
            //  TODO 给 value 字段赋值即可
            long value = 0L;
            StatisticsAdPlayFreeTimeDto dto=new StatisticsAdPlayFreeTimeDto();
            //设备
            dto.setSerialNumber(earlyWarning.getSerialNumber());
            Calendar calendar= Calendar.getInstance();
            calendar.setTime(new Date());
            if (earlyWarning.getType() == 1){
                //  月预警-闲时广告
                //  value = 1000L;
                calendar.add(Calendar.MONTH,-1);
                //上一个月
                dto.setSelectMonth(calendar.getTime());
                value=statisticsAdWatchFeign.getAdPlayCount(dto);
            } else {
                //  周预警-闲时广告
                //  value = 1000L;
                //上一周
                int yearWeek = DateUtil.getYearWeek(new Date(), Calendar.MONTH)-1;
                dto.setYearWeek(yearWeek);
                value=statisticsAdWatchFeign.getAdPlayCount(dto);
            }
            earlyWarning.setValue(value);
        });
    }

    private final static String REDIS_KEY = "advert.early_warning.";

    private void compute(Integer taskType, VoidInterface<EarlyWarning> voidInterface){
        ValueOperations<String, String> operations = this.redisTemplate.opsForValue();
        //  防止集群时定时器被运行多次
        String key  = REDIS_KEY + taskType;
        String result = operations.get(key);
        if (StringUtils.hasText(result)){
            return;
        }
        operations.set(key,"early_warning quartz runing");
        //  查询当天结束的预警记录列表
        Wrapper<EarlyWarning> wrapper = new EntityWrapper<>();
        wrapper.eq("task_type",taskType);
        wrapper.eq("end_flag",0);
        String now = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        wrapper.and("( DATE_FORMAT( end_time,'%Y-%m-%d') <= {0} )",now);
        List<EarlyWarning> list = this.earlyWarningService.selectList(wrapper);
        if (list.size() > 0) {
            //  需要修改的设备统计记录
            List<DeviceAdvertStatistics> statisticsList = new ArrayList<>(list.size());
            //  统计预警值
            list.forEach(warning -> {
                voidInterface.run(warning);
                //  标记为结束状态
                warning.setEndFlag(1);
                //  获取修改设备统计
                DeviceAdvertStatistics statistics = this.deviceAdvertStatisticsService
                        .selectCurrentMonthAdvertStatistics(warning.getDeviceId(), taskType);
                statistics.setEarlyWarningCount(statistics.getEarlyWarningCount() - 1);
                statisticsList.add(statistics);
            });
            //  批量更新预警记录
            if (this.earlyWarningService.updateBatchById(list) && statisticsList.size() > 0) {
                //  批量更新需要修改的设备统计记录
                this.deviceAdvertStatisticsService.updateBatchById(statisticsList);
            }
        }
        //  删除缓存
        this.redisTemplate.delete(key);
    }


}
