package com.mvc.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.constant.BaseConstant;
import com.mvc.constant.DeviceOperationProcessingStatus;
import com.mvc.constant.OperationStatus;
import com.mvc.constant.TaskStatus;
import com.mvc.dao.TDeviceOperationMapper;
import com.mvc.entity.TDeviceOperation;
import com.mvc.entity.TDeviceOperationExample;
import com.mvc.model.ResPageModel;
import com.mvc.model.TDeviceOperationModel;
import com.mvc.model.TaskRemoteCfgModel;
import com.mvc.service.taizhang.TaskRemoteCfgService;
import com.mvc.utils.DateUtil;
import com.mvc.utils.NotifyUtil;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@Transactional
public class TDeviceOperationService {
    @Resource
    private TDeviceOperationMapper deviceOperationMapper;

    @Resource
    private TaskRemoteCfgService taskRemoteCfgService;

    @Resource
    private NotifyUtil notifyUtil;

    private final String NOTIFY_EMAIL_RECIPIENTS = "870892757@qq.com";  //邮件接收人

    /**
     * 分页查询全部记录
     *
     * @param queryModel
     * @return
     */
    public ResPageModel findAllTDeviceOperation(TDeviceOperationModel queryModel) {
        TDeviceOperationExample example = new TDeviceOperationExample();
        TDeviceOperationExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(queryModel.getStationCode())) {
            criteria.andStationCodeEqualTo(queryModel.getStationCode());
        }
        if (StringUtils.isNotEmpty(queryModel.getDeviceSn())) {
            criteria.andDeviceSnEqualTo(queryModel.getDeviceSn());
        }
        if (StringUtils.isNotEmpty(queryModel.getConfigMan())) {
            criteria.andConfigManLike(StringUtil.getLikeFormat(queryModel.getConfigMan()));
        }
        if (StringUtils.isNotEmpty(queryModel.getOperationMan())) {
            criteria.andOperationManLike(StringUtil.getLikeFormat(queryModel.getOperationMan()));
        }
        if (StringUtils.isNotEmpty(queryModel.getDataType())) {
            criteria.andDataTypeEqualTo(queryModel.getDataType());
        }
        if(queryModel.getProcessingFlag()!=null){
            criteria.andProcessingFlagEqualTo(queryModel.getProcessingFlag());
        }

        if (StringUtils.isNotEmpty(queryModel.getTaskStatus())) {
            //说明:此处做了一个特殊处理,由于把配置失效也要当作投运
            if (queryModel.getTaskStatus().equals(OperationStatus.OPERATIONAL.getFlag())) {
                criteria.andTaskStatusBetween(OperationStatus.OPERATIONAL.getFlag(), OperationStatus.CONFIG_INVALID.getFlag());
            } else {
                criteria.andTaskStatusEqualTo(queryModel.getTaskStatus());
            }
        }

        if (queryModel.getQueryTimeRange() != null) {
            Date startTime = DateUtil.getZeroTimeOfDay(DateUtil.parseTimeStr(queryModel.getQueryTimeRange()[0], DateUtil.PATTERN_DATA_NORMAL));
            Date endTime = DateUtil.parseTimeStr(queryModel.getQueryTimeRange()[1], DateUtil.PATTERN_DATA_NORMAL);
            endTime = DateUtil.getZeroTimeOfDay(DateUtil.getOtherDateByCurrentDate(endTime, 1));
            criteria.andCreateTimeGreaterThanOrEqualTo(startTime);
            criteria.andCreateTimeLessThan(endTime);
        }

        example.setOrderByClause("ID desc");

        Page<Object> pageObject = PageHelper.startPage(queryModel.getPageNum(), queryModel.getPageSize());
        List<TDeviceOperationModel> resList = selectByExample(example);

        ResPageModel resPageModel = new ResPageModel(resList, pageObject);
        return resPageModel;
    }

    private List<TDeviceOperationModel> selectByExample(TDeviceOperationExample example) {
        List<TDeviceOperation> deviceOperations = deviceOperationMapper.selectByExample(example);
        List<TDeviceOperationModel> resList = new ArrayList<>();
        for (TDeviceOperation deviceOperation : deviceOperations) {
            TDeviceOperationModel model = new TDeviceOperationModel();
            BeanUtils.copyProperties(deviceOperation, model);
            if (model.getRemoteCfgId() != null) {
                TaskRemoteCfgModel remoteCfgModel = taskRemoteCfgService.findTaskRemoteCfgById(model.getRemoteCfgId());
                if (remoteCfgModel != null && StringUtils.isNotEmpty(remoteCfgModel.getFinishedFlag())) {
                    TaskStatus taskStatus = TaskStatus.fromCode(remoteCfgModel.getFinishedFlag());
                    model.setConfigTaskStatus(taskStatus.getDescription());
                }
            }
            //由于前端使用的是QueryTimeRange作为展示和搜索,所以在于处理一下
            String createTime = DateUtil.formateDate(model.getCreateTime(), DateUtil.PATTERN_DATA_NORMAL);
            model.setQueryTimeRange(new String[]{createTime});

            //投运状态的配置失效,在前端转为已投运
            if (model.getTaskStatus().equals(OperationStatus.CONFIG_INVALID.getFlag())) {
                model.setTaskStatus(OperationStatus.OPERATIONAL.getFlag());
            }
            resList.add(model);
        }
        return resList;
    }

    public TDeviceOperationModel saveTDeviceOperation(TDeviceOperationModel model) {
        model.setCreateTime(new Date());
        TDeviceOperation deviceOperation = new TDeviceOperation();
        BeanUtils.copyProperties(model, deviceOperation);
        //如果设备已经存在未投运的安装记录,则更新其状态为过时 2025-05-22 guozhao
        markDevicesObsoleted(model.getStationCode());
        int insert = deviceOperationMapper.insert(deviceOperation);
        model.setId(deviceOperation.getId());
        return model;
    }


    /**
     * 批量更新处理状态为过时
     *
     * @param stationCode
     * @return
     */
    public int markDevicesObsoleted(String stationCode) {
        TDeviceOperationExample example = new TDeviceOperationExample();
        TDeviceOperationExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(stationCode);
        criteria.andProcessingFlagEqualTo(DeviceOperationProcessingStatus.UNHANDLED.getFlag());

        TDeviceOperation record = new TDeviceOperation();
        record.setOperationTime(new Date());
        record.setProcessingFlag(DeviceOperationProcessingStatus.OBSOLETE.getFlag());
        return deviceOperationMapper.updateByExampleSelective(record, example);
    }

    public TDeviceOperationModel updateTDeviceOperation(TDeviceOperationModel model) {
        TDeviceOperation deviceOperation = deviceOperationMapper.selectByPrimaryKey(model.getId());
        if (deviceOperation == null) {
            return null;
        }

        DeviceOperationProcessingStatus curStatus = DeviceOperationProcessingStatus.findDeviceOperationProcessingStatusByflag(deviceOperation.getProcessingFlag());
        DeviceOperationProcessingStatus newStatus = DeviceOperationProcessingStatus.findDeviceOperationProcessingStatusByflag(model.getProcessingFlag());

        if (newStatus == DeviceOperationProcessingStatus.OPERATIONAL && curStatus == DeviceOperationProcessingStatus.UNHANDLED) {//从未处理变为已投运
            model.setOperationTime(new Date());
            model.setProcessingFlag(DeviceOperationProcessingStatus.OPERATIONAL.getFlag());
            createRemoteConfigTask(model);
        }else if(newStatus == DeviceOperationProcessingStatus.IGNORED && curStatus == DeviceOperationProcessingStatus.UNHANDLED){//从未处理变为已忽略
            model.setOperationTime(new Date());
        }

        OperationStatus curTaskStatus = OperationStatus.findOperationStatusByflag(deviceOperation.getTaskStatus());//当前状态
        OperationStatus newTaskStatus = OperationStatus.findOperationStatusByflag(model.getTaskStatus());//新状态

        //从其它状态变为待投运(有可能是初始状态,也可能是故障)
        if (newTaskStatus == OperationStatus.CONFIGURED) {
            createRemoteConfigTask(model);
        }

        BeanUtils.copyProperties(model, deviceOperation);
        int i = deviceOperationMapper.updateByPrimaryKey(deviceOperation);
        return model;
    }

    /**
     * 根据投运记录创建远程配置任务
     *
     * @param scModel
     * @return
     */
    private TDeviceOperationModel createRemoteConfigTask(TDeviceOperationModel scModel) {
        TaskRemoteCfgModel cfgModel = new TaskRemoteCfgModel();
        OperationStatus newTaskStatus = OperationStatus.findOperationStatusByflag(scModel.getTaskStatus());

        if(scModel.getProcessingFlag()==DeviceOperationProcessingStatus.OPERATIONAL.getFlag()){
            cfgModel.setSampleInterval(BaseConstant.DEFAULT_SAMPLE_INTERVAL);
            cfgModel.setUpInterval(BaseConstant.DEFAULT_SAMPLE_INTERVAL);
            cfgModel.setEnableAiImageProcess(BaseConstant.INVALID_FLAG);//默认关闭AI处理图像
            cfgModel.setCreateMan(scModel.getOperationMan());
        }else if (newTaskStatus == OperationStatus.CONFIGURED) {//配置完成
            cfgModel = scModel.getRemoteCfgModel();
            cfgModel.setOperationStatus(newTaskStatus.getFlag());
            cfgModel.setCreateMan(scModel.getConfigMan());
        }

        cfgModel.setDeviceSn(scModel.getDeviceSn());
        cfgModel.setOperationStatus(newTaskStatus.getFlag());

        cfgModel = taskRemoteCfgService.saveTaskRemoteCfg(cfgModel);
        if (cfgModel != null && newTaskStatus == OperationStatus.CONFIGURED) {
            scModel.setRemoteCfgId(cfgModel.getId());
            scModel.setConfigTime(new Date());
        }

        return scModel;
    }

    public int deleteTDeviceOperation(int id) {
        int i = deviceOperationMapper.deleteByPrimaryKey(id);
        return i;
    }

    /**
     * 根据ID获取Model
     *
     * @param id
     * @return
     */
    public TDeviceOperationModel findTDeviceOperationModelById(int id) {
        TDeviceOperation deviceOperation = deviceOperationMapper.selectByPrimaryKey(id);
        if (deviceOperation != null) {
            TDeviceOperationModel model = new TDeviceOperationModel();
            BeanUtils.copyProperties(deviceOperation, model);
            return model;
        }
        return null;
    }

    /**
     * 筛选近一小时记录并通过邮件通知
     */
    public void filterAndNotifyByEmail() {
        Date endDate = new Date();
        int hours = DateUtil.getHours(endDate);
        //定时任务是9-18点
        Date startData = hours == 9 ? DateUtil.getOtherDateByHour(endDate, -15) : DateUtil.getOtherDateByHour(endDate, -1);

        TDeviceOperationExample example = new TDeviceOperationExample();
        TDeviceOperationExample.Criteria criteria = example.createCriteria();
        criteria.andCreateTimeGreaterThanOrEqualTo(startData);
        criteria.andCreateTimeLessThan(endDate);
        criteria.andProcessingFlagEqualTo(DeviceOperationProcessingStatus.UNHANDLED.getFlag());
        List<TDeviceOperation> list = deviceOperationMapper.selectByExample(example);

        if (list == null || list.size() == 0) {
            return;//没有安装或故障的记录
        }

        int numSetup = 0;
        int numFault = 0;
        for (TDeviceOperation deviceOperation : list) {
            if (deviceOperation.getDataType().equals("0")) {
                numSetup++;
            } else if (deviceOperation.getDataType().equals("1")) {
                numFault++;
            }
        }

        String subject = "[边缘AI抄表器]设备状态报告";
        StringBuilder sb = new StringBuilder();

        sb.append("尊敬的负责人：<br>");
        sb.append("您好！现将近一小时设备运行情况汇总如下，请查收：<br>");
        sb.append("1. 新增设备：");
        sb.append(numSetup);
        sb.append(" 台（已完成安装调试,需要进行配置、投运）<br>");
        sb.append("2. 异常设备：");
        sb.append(numFault);
        sb.append(" 台（需技术介入）<br>");
        sb.append("处理要求：<br>");
        sb.append("请相关团队于今日下班前完成处理。<br>");
        sb.append("数据时间范围：");
        sb.append(DateUtil.formateDate(startData, DateUtil.PATTERN_DATA_NORMAL));
        sb.append("至");
        sb.append(DateUtil.formateDate(endDate, DateUtil.PATTERN_DATA_NORMAL));
        sb.append("<br>此致<br>");
        sb.append("敬礼<br>");

        notifyUtil.sendEMail(NOTIFY_EMAIL_RECIPIENTS, subject, sb.toString());
    }
}
