package com.sptg.ad.biz.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sptg.ad.api.entity.DeviceAdvertStatistics;
import com.sptg.ad.biz.mapper.DeviceAdvertStatisticsMapper;
import com.sptg.ad.biz.service.DeviceAdvertStatisticsService;
import com.sptg.common.core.beans.PageBean;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * description:
 */
@Service
@RequiredArgsConstructor
public class DeviceAdvertStatisticsServiceImpl extends ServiceImpl<DeviceAdvertStatisticsMapper,DeviceAdvertStatistics> implements DeviceAdvertStatisticsService {

    private final RedisTemplate<String,String> redisTemplate;

    private final static String KEY = "device:advert:statistics:";
    private final DeviceFeign deviceFeign;

    /**
     * parameter 1:设备Id
     * parameter 2:任务类型：{ 1：人脸广告，2：闲时广告 }
     * parameter 3:日期，如：201908，表示：2019年8月
     */
    private final static String REDIS_KEY = KEY + "%s:%s:%s";

    /**
     * parameter 1:设备Id
     */
    private final static String MATCHING_KEY = KEY + "%s";

    /**
     * 日期格式
     */
    private final static String DATE_FORMATTER = "yyyyMM";

    @Override
    public boolean updateBatchById(List<DeviceAdvertStatistics> statisticsList) {
        boolean isUpdate = super.updateBatchById(statisticsList);
        if (isUpdate){
            statisticsList.forEach(statistics -> {
                //  更新缓存
                String key = String.format(REDIS_KEY,statistics.getDeviceId(),statistics.getTaskType(),statistics.getCreateTime());
                this.redisTemplate.opsForValue().set(key,JsonUtils.objectToJson(statistics));
            });
        }
        return isUpdate;
    }

    @Override
    public boolean updateById(DeviceAdvertStatistics statistics) {
        boolean isUpdate = super.updateById(statistics);
        if (isUpdate){
            //  更新缓存
            String key = String.format(REDIS_KEY,statistics.getDeviceId(),statistics.getTaskType(),statistics.getCreateTime());
            this.redisTemplate.opsForValue().set(key,JsonUtils.objectToJson(statistics));
        }
        return isUpdate;
    }

    @Override
    public DeviceAdvertStatistics selectCurrentMonthAdvertStatistics(Long deviceId,Integer taskType){
        String month = LocalDate.now().format(DateTimeFormatter.ofPattern(DATE_FORMATTER));
        //  查询缓存
        String key = String.format(REDIS_KEY,deviceId,taskType,month);
        ValueOperations<String, String> operations = this.redisTemplate.opsForValue();
        String result = operations.get(key);
        if (StringUtils.hasText(result)){
            return JsonUtils.jsonToPojo(result,DeviceAdvertStatistics.class);
        }
        //  查询数据库
        Wrapper<DeviceAdvertStatistics> wrapper = new EntityWrapper<>();
        wrapper.eq("device_id",deviceId);
        wrapper.eq("task_type",taskType);
        wrapper.eq("create_time",month);
        DeviceAdvertStatistics statistics = this.selectOne(wrapper);
        //  判断是否需要新建当月记录
        if (null == statistics){
            statistics = this.selectLastMonthAdvertStatistics(deviceId, taskType);
            if (null == statistics){
                statistics = new DeviceAdvertStatistics();
                statistics.setTaskType(taskType);
                statistics.setPublishCount(0L);
                statistics.setAdCount(0);
                statistics.setBrowseCount(0L);
                statistics.setLastMonthBrowse(0);
                statistics.setDeviceId(deviceId);
                statistics.setEarlyWarningCount(0);
                statistics.setThisMonthBrowse(0);
            }else {
                statistics.setId(null);
            }
            statistics.setLastMonthBrowse(statistics.getThisMonthBrowse());
            statistics.setThisMonthBrowse(0);
            statistics.setWeek1Browse(0);
            statistics.setWeek2Browse(0);
            statistics.setWeek3Browse(0);
            statistics.setWeek4Browse(0);
            statistics.setCreateTime(month);
            Device device = this.deviceFeign.getEntityById(deviceId);
            statistics.setDeviceName(device.getName());
            statistics.setDeviceInstallPath(device.getInstallPath());
            this.insert(statistics);
        }
        //  删除其他缓存
        Set<String> cacheKeys = this.redisTemplate.keys(String.format(MATCHING_KEY,deviceId));
        Optional.ofNullable(cacheKeys).ifPresent(bean -> this.redisTemplate.delete(cacheKeys));
        //  加入缓存
        operations.set(key,JsonUtils.objectToJson(statistics));
        return statistics;
    }

    /**
     * 获取上月的设备广告统计
     * @param deviceId 设备Id
     * @param taskType 任务类型：{ 1：人脸广告，2：闲时广告 }
     * @return DeviceAdvertStatistics
     */
    private DeviceAdvertStatistics selectLastMonthAdvertStatistics(Long deviceId,Integer taskType){
        String month = LocalDate.now().minusMonths(1).format(DateTimeFormatter.ofPattern(DATE_FORMATTER));
        //  查询缓存
        String key = String.format(REDIS_KEY,deviceId,taskType,month);
        String result = this.redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(result)){
            return JsonUtils.jsonToPojo(result,DeviceAdvertStatistics.class);
        }
        //  查询数据库
        Wrapper<DeviceAdvertStatistics> wrapper = new EntityWrapper<>();
        wrapper.eq("device_id",deviceId);
        wrapper.eq("task_type",taskType);
        wrapper.eq("create_time",month);
        return this.selectOne(wrapper);
    }


    @Override
    public Page<DeviceAdvertStatistics> pagingQuery(PageBean<DeviceAdvertStatistics, DeviceAdvertStatistics> pageBean) {
        DeviceAdvertStatistics dto = pageBean.getDto();
        //  构建查询条件
        Wrapper<DeviceAdvertStatistics> wrapper = new EntityWrapper<>();
        //  根据任务类型查询
        if (null != dto.getTaskType()){
            wrapper.eq("task_type",dto.getTaskType());
        }
        //  查询某月的记录
        if (StringUtils.hasText(dto.getCreateTime())){
            wrapper.eq("create_time",dto.getCreateTime());
        }
        //  根据小区Id查询
        if (null != dto.getXqId()){
            wrapper.eq("xq_id",dto.getXqId());
        }
        //  根据时间查询
        if (StringUtils.hasText(dto.getCreateTime())){
            wrapper.eq("create_time",dto.getCreateTime());
        }
        //  根据设备名称模糊查询
        if (StringUtils.hasText(dto.getDeviceName())){
            wrapper.like("device_name",dto.getDeviceName(), SqlLike.RIGHT);
        }
        //  根据设备序列号模糊查询
        if (StringUtils.hasText(dto.getDeviceSerialNumber())){
            wrapper.like("device_serial_number",dto.getDeviceSerialNumber(), SqlLike.RIGHT);
        }
        //  根据省市区查询
        if (StringUtils.hasText(dto.getRegionArea())){
            String sql = "(region_province = {0} OR region_city = {0} OR region_area = {0})";
            wrapper.and(sql,dto.getRegionArea());
        }
        //  根据设备Id查询
        if (null != dto.getDeviceIdList()){
            wrapper.in("device_id",dto.getDeviceIdList());
        }
        return this.selectPage(pageBean,wrapper);
    }

}
