package com.willalp.quartz.task;

import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.willalp.canteen.domain.HsCanteenOrder;
import com.willalp.canteen.service.IHsCanteenOrderService;
import com.willalp.common.utils.DateUtils;
import com.willalp.common.utils.StringUtils;
import com.willalp.control.domain.HsControlDeviceInfo;
import com.willalp.control.domain.HsControlStat;
import com.willalp.control.domain.HsControlTiming;
import com.willalp.control.netty.model.ControlDataModel;
import com.willalp.control.service.ControlService;
import com.willalp.control.service.IHsControlDeviceInfoService;
import com.willalp.control.service.IHsControlStatService;
import com.willalp.control.service.IHsControlTimingService;
import com.willalp.push.service.IHsAppPushService;
import com.willalp.wx.domain.WxMsgTemplateAppointment;
import com.willalp.wx.enums.WxTemplateKeyEnum;
import com.willalp.wx.service.WxMsgService;
import com.willalp.wx.utils.WxUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 定时任务调度测试
 *
 * @author willalp
 */
@Component("willalpTask")
public class RyTask {
    @Resource
    private IHsControlDeviceInfoService controlDeviceInfoService;

    @Resource
    private IHsControlTimingService controlTimingService;

    @Resource
    private ControlService controlService;

    @Resource
    private IHsControlStatService statService;

    @Resource
    private ControlDataModel controlDataModel;

    @Resource
    private IHsCanteenOrderService canteenOrderService;

    @Resource
    private WxMsgService wxMsgService;

    @Resource
    private WxUtils wxUtils;

    @Resource
    private IHsAppPushService pushService;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params) {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams() {
        System.out.println("执行无参方法");
    }

    /**
     * control模块设备定时任务检索
     */
    public void controlTimingRunDeviceTask() {
        //获取所有定时任务
        List<HsControlTiming> list = controlTimingService.list();
        // 存储本周今天的定时任务
        List<HsControlTiming> nowWeekList = new ArrayList<>();
        //获取今天周几
        String week = controlDataModel.getWeek();
        for (HsControlTiming t : list) {
            if (t.getCycle().contains(week)) {
                nowWeekList.add(t);
            }
        }
        controlService.asyncTimingStartOrEnd(nowWeekList, 0);
        controlService.asyncTimingStartOrEnd(nowWeekList, 1);
    }

    /**
     * 定时更新设备运行信息
     *
     * @param msNum 分钟（每多少分钟执行）
     */
    public void controlTimingUpdateDeviceInfo(Integer msNum) {
        List<HsControlDeviceInfo> list = controlDeviceInfoService.list();
        List<HsControlDeviceInfo> listCopy = new ArrayList<>();
        long ms = 60000L * msNum;
        for (HsControlDeviceInfo deviceInfo : list) {
            Date lastOpenTime = deviceInfo.getLastOpenTime();
            Date lastCloseTime = deviceInfo.getLastCloseTime();
            if (lastOpenTime == null) {
                continue;
            }
            if (lastCloseTime != null && lastOpenTime.getTime() < lastCloseTime.getTime()) {
                deviceInfo.setRunningStatus(0);
            } else {
                deviceInfo.setRunningStatus(1);
                //累加统计毫秒数
                long statTime = 0;
                long dateCha = System.currentTimeMillis() - deviceInfo.getLastOpenTime().getTime();
                //如果实际运行不不足一小时计算本次差值赋值给统计时间
                if (dateCha < ms) {
                    statTime = dateCha + deviceInfo.getStatTime();
                } else {
                    statTime = ms + deviceInfo.getStatTime();
                }
                deviceInfo.setStatTime(statTime);
                String dosage = DateUtil.formatBetween(statTime, BetweenFormater.Level.HOUR);
                //long between = DateUtil.between(new Date(), deviceInfo.getLastOpenTime(), DateUnit.MS);
                if (dosage.contains("天")) {
                    dosage = "24";
                } else if (dosage.contains("小时")) {
                    dosage = dosage.substring(0, dosage.indexOf("小时"));
                } else {
                    dosage = "0";
                }
                //赋值到小记时长
                deviceInfo.setDosage(dosage);
                listCopy.add(deviceInfo);
            }
        }
        controlDeviceInfoService.updateBatchById(listCopy);
    }


    /**
     * control模块设备每日统计
     */
    public void controlTimingStatDayData() {
        List<HsControlDeviceInfo> updateDeviceInfo = new ArrayList<>();
        List<HsControlStat> updateStat = new ArrayList<>();
        List<HsControlStat> saveStat = new ArrayList<>();
        //今天
        String now = DateUtils.parseDateToStr("yyyy-MM-dd", new Date());
        //明天
        Date tomorrow = new Date(DateUtil.tomorrow().getTime());

        List<HsControlDeviceInfo> nowDeviceDosageInfos = controlDeviceInfoService.list();
        for (HsControlDeviceInfo nowDeviceDosageInfo : nowDeviceDosageInfos) {
            HsControlStat controlStat = statService.getOne(new QueryWrapper<HsControlStat>()
                    .eq("use_no_id", nowDeviceDosageInfo.getDeviceUseNo())
                    .like("create_time", now));
            int isNull = 0;
            if (ObjectUtil.isEmpty(controlStat)) {
                controlStat = new HsControlStat();
                controlStat.setUseNoId(nowDeviceDosageInfo.getDeviceUseNo());
                controlStat.setDosage("0");
                controlStat.setIsStat(1);
                controlStat.setCreateTime(new Date());
                isNull = 1;
            }
            //今天
            Long statTime = nowDeviceDosageInfo.getStatTime();
            if (0 == statTime) {
                controlStat.setIsStat(2);
            } else {
                controlStat.setDosage(String.valueOf(statTime));
                controlStat.setIsStat(0);
            }
            controlStat.setCreateTime(new Date());
            if (isNull == 1) {
                saveStat.add(controlStat);
            } else {
                updateStat.add(controlStat);
            }

            //明天日志入口
            HsControlStat statTomorrow = new HsControlStat();
            statTomorrow.setUseNoId(nowDeviceDosageInfo.getDeviceUseNo());
            statTomorrow.setDosage("0");
            statTomorrow.setIsStat(1);
            statTomorrow.setCreateTime(tomorrow);
            saveStat.add(statTomorrow);

            //更新设备运行信息
            nowDeviceDosageInfo.setDosage("0");
            nowDeviceDosageInfo.setStatTime((long) 0);
            if (1 == nowDeviceDosageInfo.getRunningStatus()) {
                nowDeviceDosageInfo.setLastOpenTime(new Date());
            }
            updateDeviceInfo.add(nowDeviceDosageInfo);
        }
        //持久化操作
        statService.updateBatchById(updateStat);
        statService.saveBatch(saveStat);
        controlDeviceInfoService.updateBatchById(updateDeviceInfo);
    }

    public void reserveRemind() {
        //获取今日未下单用户
        List<HsCanteenOrder> hsCanteenOrders = canteenOrderService.todayNotOrderUser();
        WxMsgTemplateAppointment w = new WxMsgTemplateAppointment();
        w.setThing3(wxUtils.getFormat("会助理提醒您，请进入小程序提前预定明日菜品"));
        w.setThing3(wxUtils.getFormat(""));
        for (HsCanteenOrder hsCanteenOrder : hsCanteenOrders) {
            wxMsgService.sendQRCodeMsg(hsCanteenOrder.getUserNumber(), w, WxTemplateKeyEnum.APPOINTMENT, true);
        }
    }
}
