package com.example.zxweb.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.zxweb.common.constant.DevConstant;
import com.example.zxweb.dto.ZxCelueDTO;
import com.example.zxweb.entity.ZxCelue;
import com.example.zxweb.entity.ZxDevice;
import com.example.zxweb.entity.ZxDeviceMethod;
import com.example.zxweb.exception.BusinessException;
import com.example.zxweb.mapper.ZxCelueMapper;
import com.example.zxweb.service.IZxCelueService;
import com.example.zxweb.service.IZxDeviceService;
import com.example.zxweb.utils.AssertUtils;
import com.example.zxweb.utils.CronLowUtil;
import com.example.zxweb.utils.IotUtils;
import com.example.zxweb.vo.AddZxCeluePVO;
import com.example.zxweb.vo.QueryCelueVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 策略信息
 * @Author ZhouWenTao
 * @Date 2023/9/13 14:09
 */
@Service
@Slf4j
public class ZxCelueServiceImpl extends ServiceImpl<ZxCelueMapper, ZxCelue> implements IZxCelueService {
    @Value("${iot.active}")
    private boolean active;
    @Resource
    private IZxDeviceService zxDeviceService;
    @Override
    public boolean saveZxCelue(AddZxCeluePVO addZxCeluePVO) {
        Date date = new Date();
        long time = date.getTime();
        ZxCelue zxCelue=new ZxCelue();
        AssertUtils.hasSize(addZxCeluePVO.getDevidList(),"请选择[设备]");
        try {
            BeanUtils.copyProperties(addZxCeluePVO,zxCelue);
            String celueid = addZxCeluePVO.getCelueid();
            if(StringUtils.isNotBlank(celueid)){
                zxCelue.setCelueid(celueid);
            }else{
                zxCelue.setCelueid(time+"");
            }
            /*if (StringUtils.isBlank(zxCelue.getStartTime())) {
                zxCelue.setStartTime(DateFormatUtils.format(date,"yyyy-MM-dd"));
            }
            if (StringUtils.isBlank(zxCelue.getEndTime())) {
                zxCelue.setEndTime("2099-12-31");
            }*/
            if (!CollectionUtils.isEmpty(addZxCeluePVO.getDevidList())) {
                zxCelue.setDevid(String.join(",", addZxCeluePVO.getDevidList()));
            }
            String cron = CronLowUtil.getCron(addZxCeluePVO.getTimeType(), addZxCeluePVO.getExeTime(), addZxCeluePVO.getWeeklyDay(), addZxCeluePVO.getDay(), addZxCeluePVO.getStartTime(), addZxCeluePVO.getEndTime());
            zxCelue.setTriggereTime(cron);
            String type = addZxCeluePVO.getType();
            String gateway_5lqh = DevConstant.gateway.gateway_5lqh;
            //获取设备信息
            LambdaQueryWrapper<ZxDevice> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ZxDevice::getSerial,addZxCeluePVO.getDevidList());
            List<ZxDevice> deviceList = zxDeviceService.list(queryWrapper);
            StringBuilder action=new StringBuilder();
            //拼接触发动作
            for (ZxDevice zxDevice : deviceList) {
                //设备号
                String serial = zxDevice.getSerial();
                //设备型号
                String modelCode = zxDevice.getModelCode();
                List<ZxDeviceMethod> methodList = zxDeviceService.getMethodByDeviceModelCode(zxDevice.getModelCode());
                AssertUtils.hasSize(methodList,String.format("设备-[%s] 未找到可执行方法",zxDevice.getTerminalName()));
                ZxDeviceMethod zxDeviceMethod = methodList.get(0);
                //可执行方法
                String method = zxDeviceMethod.getMethod();
                //参数
                String[] parameters = zxDeviceMethod.getParameter().split(",");
                for (String parameter: parameters) {
                    if (action.length()>0) {
                        action.append("&&");
                    }
                    //设备号.设备型号.下行方法.参数.操作值
                    action.append(String.format("%s.%s.%s.%s=\"%s\"",serial,modelCode,method,parameter,type));
                }
                //String s = "s10001.switch1.controlSwitch1.ctrl_ch0_status=\"1\"&&s10002.switch1.controlSwitch1.ctrl_ch0_status=\"1\"";
            }
            String requestBodyJson="{\"serial\":\"%serial\",\"productId\":\"\",\"methodName\":\"celueSet\",\"inputData\":{\"devid\":\"%serial\",\"celueid\":\"%celueid\",\"name\":\"%name\",\"triggereTime\":\"%cron\",\"action\":\"%action\",\"startTime\":\"%startDate\",\"endTime\":\"%endDate\"}}";
            requestBodyJson=requestBodyJson.replace("%serial",gateway_5lqh);
            requestBodyJson=requestBodyJson.replace("%celueid", zxCelue.getCelueid());
            requestBodyJson=requestBodyJson.replace("%name",zxCelue.getName());
            requestBodyJson=requestBodyJson.replace("%cron",cron);
            requestBodyJson=requestBodyJson.replace("%action",action.toString().replace("\"","\\\""));
            requestBodyJson=requestBodyJson.replace("%startDate",StringUtils.isNotBlank(addZxCeluePVO.getStartTime())?addZxCeluePVO.getStartTime():"");
            requestBodyJson=requestBodyJson.replace("%endDate",StringUtils.isNotBlank(addZxCeluePVO.getEndTime())?addZxCeluePVO.getEndTime():"");
            JSONObject requestBody = JSONObject.parseObject(requestBodyJson);
            if (active) {
                IotUtils.celueSet(requestBody);
            }
            if (StringUtils.isNotBlank(celueid)) {
                updateById(zxCelue);
            }else{
                save(zxCelue);
            }
        }catch (Exception e){
            throw new BusinessException(e);
        }
        return true;
    }

    @Override
    public boolean editStatus(ZxCelue zxCelue) {
        String status="0";
        AssertUtils.notEmpty(zxCelue.getCelueid(),"当前策略id不可用");
        try {
            ZxCelue celue = getById(zxCelue.getCelueid());
            LambdaUpdateWrapper<ZxCelue> updateWrapper=new LambdaUpdateWrapper<>();
            updateWrapper.eq(ZxCelue::getCelueid,celue.getCelueid());
            if ("0".equals(celue.getStatus())) {
                status="1";
                updateWrapper.set(ZxCelue::getStatus,status);
            }else{
                updateWrapper.set(ZxCelue::getStatus,status);
            }
            update(updateWrapper);
            //请求更改策略方法
            if (active) {
                //向网关发生更改状态指令
                IotUtils.editCelueStatus(celue.getCelueid(),status);
            }
        }catch (Exception e){
            throw new BusinessException(e);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteZxCelue(String id) {
        //删除数据库中策略
        removeById(id);
        if (active) {
            //向网关发生删除指令
            IotUtils.deleteCelue(id);
        }

        return true;
    }

    @Override
    public IPage<ZxCelueDTO> pageList(QueryCelueVO queryCelueVO) {
        Integer page = queryCelueVO.getPage();
        Integer limit = queryCelueVO.getLimit();
        String name = queryCelueVO.getName();
        String status = queryCelueVO.getStatus();
        IPage<ZxCelueDTO> pageList = baseMapper.pageList(new Page<>(page, limit),queryCelueVO);
        for (ZxCelueDTO record : pageList.getRecords()) {
            if (StringUtils.isNotBlank(record.getDevid())) {
                List<String> collect = Arrays.stream(record.getDevid().split(",")).collect(Collectors.toList());
                record.setDevidList(collect);
            }
            String xunhuanzhouqi="";
            if (StringUtils.isNotBlank(record.getStartTime())) {
                if(record.getStartTime().equals(record.getEndTime())){
                    //单日
                    xunhuanzhouqi=record.getStartTime();
                }else{
                    //范围
                    xunhuanzhouqi=record.getStartTime()+"至"+record.getEndTime();
                }
            }
            String s = CronLowUtil.cronToText(record.getTriggereTime());
            xunhuanzhouqi= xunhuanzhouqi + " " + s;
            if (!xunhuanzhouqi.contains("-") && !xunhuanzhouqi.contains("周")) {
                xunhuanzhouqi="每天 "+xunhuanzhouqi;
            }
            record.setXunhuanzhouqi(xunhuanzhouqi);
        }
        return pageList;
    }

    @Override
    public ZxCelueDTO getDetail(String id) {
        ZxCelue zxCelue = getById(id);
        ZxCelueDTO zxCelueDTO = new ZxCelueDTO();
        BeanUtils.copyProperties(zxCelue,zxCelueDTO);
        //拆分 所选设备id
        String devid = zxCelue.getDevid();
        if (StringUtils.isNotBlank(devid)) {
            List<String> collect = Arrays.stream(devid.split(",")).collect(Collectors.toList());
            zxCelueDTO.setDevidList(collect);
        }
        //判断所选时间类型
        if (StringUtils.isNotBlank(zxCelue.getStartTime()) && StringUtils.isNotBlank(zxCelue.getEndTime())) {
            if(zxCelue.getStartTime().equals(zxCelue.getEndTime())){
                //单日
                zxCelueDTO.setTimeType("day");
            }else{
                //范围
                zxCelueDTO.setTimeType("date");
            }
        }else{
            if (StringUtils.isNotBlank(zxCelue.getTriggereTime())) {
                String[] split = zxCelue.getTriggereTime().split(" ");
                //最后一个符号是*，代表是每天的
                if (split[split.length-1].equals("*")) {
                    zxCelueDTO.setTimeType("everyDay");
                }else{
                    zxCelueDTO.setTimeType("weekly");
                    zxCelueDTO.setWeeklyDay(split[split.length-1]);
                }
            }
        }
        //获取执行时段
        if (StringUtils.isNotBlank(zxCelue.getTriggereTime())) {
            String[] s = zxCelue.getTriggereTime().split(" ");
            String exeTime=null;
            if (s.length>=6) {
                //有秒
                String s2 = new DecimalFormat("00").format(Integer.parseInt(s[2]));
                String s1 = new DecimalFormat("00").format(Integer.parseInt(s[1]));
                String s0 = new DecimalFormat("00").format(Integer.parseInt(s[0]));
                exeTime=s2+":"+s1/*+":"+s0*/;
            }
            zxCelueDTO.setExeTime(exeTime);
        }
        return zxCelueDTO;
    }

    public static void ss(){

    }
    public static void main(String[] args) {
        String timeType="day";
        String exeTime="08:30";
        String cron=null;
        String weeklyDay="1,2,3";//周一，周二，周三
        String day="1,31";
        String[] time = exeTime.split(":");
        Integer hour=Integer.parseInt(time[0]);//小时
        Integer minute=Integer.parseInt(time[1]);//分钟
        String startDate="2023-09-10";//开始时间
        String endDate="2023-09-30";//结束时间
        //每天
        if ("everyDay".equals(timeType)) {
            cron = String.format("0 %s %s * * ? *",minute,hour);
        } else if ("weekly".equals(timeType)) {
            //每周
            cron = String.format("0 %s %s ? * %s",minute,hour,weeklyDay);
        } else if("day".equals(timeType)){
            //单日
            cron = String.format("0 %s %s %s * ? ",minute,hour,day);
        } else if ("date".equals(timeType)){
            //日期段
            System.out.println("在"+startDate+"到"+endDate);
            cron = String.format("0 %s %s * * ? *",minute,hour);
        }
        System.out.println(cron);
    }
}
