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

import com.zanxiang.game.data.serve.pojo.properties.SmsProperties;
import com.zanxiang.game.data.serve.service.IOrderCostMonitorAlarmService;
import com.zanxiang.game.data.serve.utils.RedisUtil;
import com.zanxiang.module.sms.pojo.SendResult;
import com.zanxiang.module.sms.service.impl.AliSmsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.sql.Sql;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class OrderCostMonitorAlarmBySmsServiceImpl implements IOrderCostMonitorAlarmService {

    @Resource
    private Dao dao;

    @Resource
    private RedisUtil<String> redisUtil;

    @Resource
    private AliSmsService aliSmsService;

    @Resource
    private SmsProperties smsProperties;

    private final String modelName = "game_data_serve";

    private final String HEADLINE_COST_COUNT = modelName + ":" + "headline_cost_count";

    private final String TENCENT_COST_COUNT = modelName + ":" + "tencent_cost_count";

    @Value("${phoneNumber}")
    private String phoneNumber;

    /**
     * 30分钟扫一次，每次扫当前时间-1小时
     */
    @Override
    public void monitorDataStatus() {
        //获取当前时间前半小时的时间
        LocalDateTime date = LocalDateTime.now().minusMinutes(60);
        //查询订单表
        Sql orderSql = getSql(getOrderCountSql(date));
        int count = orderSql.getInt(0);
        //如果为0直接告警
        if (count == 0) {
            String msg = "前一小时订单表数据为空,请检查";
            log.info(msg);
            if (!sendSms(msg)) {
                throw new RuntimeException("短信发送失败");
            }
        }
    }

    @Override
    public void monitorHeadCostStatus() {
        //获取当前时间前半小时的时间
        LocalDateTime date = LocalDateTime.now().minusMinutes(60);
        //查询头条广告表
        Sql headCostSql = getSql(getheadCostCountSql(date));
        int newHeadCostCount = headCostSql.getInt(0);
        //从redis中取旧的消耗值
        String oldHeadCostCount = redisUtil.getCache(HEADLINE_COST_COUNT);
        if (StringUtils.isNotBlank(oldHeadCostCount)) {
            //如果不为空，则比较
            if (newHeadCostCount - Integer.parseInt(oldHeadCostCount) == 0) {
                //如果没期间没消耗就告警
                String msg = "前半小时头条广告数据为空,请检查";
                log.info(msg);
                if (!sendSms(msg)) {
                    throw new RuntimeException("短信发送失败");
                }
            }
        }
        //将新数据存入redis  60分钟
        redisUtil.setCache(HEADLINE_COST_COUNT, Integer.toString(newHeadCostCount), 60 * 60);

    }

    @Override
    public void monitorTencentCostStatus() {
        //获取当前时间前半小时的时间
        LocalDateTime date = LocalDateTime.now().minusMinutes(60);
        //查询腾讯广告表
        Sql tencentCostSql = getSql(getTencentCostSqlSql(date));
        int newTencentCostCount = tencentCostSql.getInt(0);
        //从redis中取旧的消耗值
        String oldTencentCostCount = redisUtil.getCache(TENCENT_COST_COUNT);
        if (StringUtils.isNotBlank(oldTencentCostCount)) {
            if (newTencentCostCount - Integer.parseInt(oldTencentCostCount) == 0) {
                String msg = "前半小时腾讯广告数据为空,请检查";
                log.info(msg);
                if (!sendSms(msg)) {
                    throw new RuntimeException("短信发送失败");
                }
            }
        }
        //将新数据存入redis  60分钟
        redisUtil.setCache(TENCENT_COST_COUNT, Integer.toString(newTencentCostCount), 60 * 60);
    }


    /**
     * 发送短信
     *
     * @param content 内容
     * @return 是否发送成功
     */
    private Boolean sendSms(String content) {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, String> params = new HashMap<>();
        params.put(smsProperties.getMsgParamName(), content);
        params.put(smsProperties.getTimeParamName(), formatter.format(date));
        //存储在配置文件
        if (StringUtils.isNotEmpty(phoneNumber)) {
            Set<String> numberList = new HashSet<>(Arrays.asList(phoneNumber.split(",")));
            Map<String, SendResult> resultMap = aliSmsService.send(smsProperties.getDefaultSignName(), smsProperties.getDefaultStstemErrorTemplate(), params, numberList);
            for (SendResult next : resultMap.values()) {
                if (!next.isSuccess()) {
                    log.error("短信发送失败，失败原因：{}", next.getMsg());
                    return false;
                }
            }
        }
        return true;
    }


    public boolean testSendSms(String content) {
        System.out.println(phoneNumber);
        return false;
//        return sendSms(content);
    }


    private Sql getSql(String sqlStr) {
        Sql sql = Sqls.create(sqlStr);
        sql.setCallback(Sqls.callback.integer());
        dao.execute(sql);
        return sql;
    }

    private String getTencentCostSqlSql(LocalDateTime date) {
        Criteria cri = Cnd.cri();
        cri.where().and("day", ">=", date.toLocalDate());
        cri.where().and("hour", "=", date.getHour());
        return """
                select sum(cost) from ods_ad_tencent_data_game.t_gdt_adgroups_data_hour
                """ + cri;
    }

    private String getheadCostCountSql(LocalDateTime date) {
        Criteria cri = Cnd.cri();
        cri.where().and("day", ">=", date.toLocalDate());
        cri.where().and("hour", "=", date.getHour());
        return """
                select sum(cost) from ods_ad_byte_data_game.t_ad_data_hour
                """ + cri;
    }

    private String getOrderCountSql(LocalDateTime localDateTime) {
        Criteria criteria = Cnd.cri();
        criteria.where().and("create_time", ">=", localDateTime);
        criteria.where().and("source_system", "=", "ZX_ONE");
        return """
                  select count(*) from dm_game_order.t_game_order
                """ + criteria;
    }


}
