package com.imdroid.beidou.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.imdroid.beidou.service.CommonExcelService;
import com.imdroid.secapi.dto.GnssStatusMsg;
import com.imdroid.secapi.dto.GnssStatusMsgMapper;
import com.imdroid.secapi.dto.OpLogManager;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * 状态消息 控制器
 *
 * @author LiGang
 * @date 2024/1/6 14:37
 */
@Controller
@RequiredArgsConstructor
public class GnssMsgStatusController extends BasicController implements CommonExcelService<GnssStatusMsg, GnssStatusMsg> {

    @Autowired
    GnssStatusMsgMapper statusMsgMapper;
    @Autowired
    OpLogManager opLogManager;
    
    // 滑动窗口大小
    private static final int WINDOW_SIZE = 5;
    
    @RequestMapping("/page/gnss_msg_status")
    public String gnssStatusMsg(Model m, HttpSession session) {
        initModel(m, session);
        return "/page/gnss_msg_status";
    }

    @RequestMapping("/gnss/msg/status/list")
    @ResponseBody
    public JSONObject listStatusMsg(HttpSession session, Integer page, Integer limit, String searchParams) {
        JSONObject obj = this.pageList(session, page, limit, searchParams);
        List<GnssStatusMsg> msgList = (List<GnssStatusMsg>) obj.get("data");
        for(GnssStatusMsg msg:msgList){
            if(msg.getChargecurrency()!=null && msg.getSolarvoltage()!=null){
                if(msg.getVoltage()>msg.getSolarvoltage()+3000){
                    msg.setChargecurrency(0);
                    msg.setChargewatt(0.0F);
                }
            }
        }
        return obj;
    }
    
    /**
     * 获取特定设备的数据，并应用滑动平均
     * 
     * @param deviceId 设备ID
     * @param limit 获取条数，默认150条
     * @return 处理后的数据
     */
    @RequestMapping("/gnss/msg/status/device_data")
    @ResponseBody
    public JSONObject getDeviceData(@RequestParam String deviceId, 
                                   @RequestParam(required = false, defaultValue = "150") Integer limit) {
        // 查询指定设备的最近数据
        QueryWrapper<GnssStatusMsg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deviceid", deviceId)
                   .orderByDesc("createtime")
                   .last("limit " + limit);
        
        List<GnssStatusMsg> dataList = statusMsgMapper.selectList(queryWrapper);
        // 反转列表，使其按时间升序排列
        Collections.reverse(dataList);
        
        // 应用滑动平均
        List<GnssStatusMsg> smoothedData = applyMovingAverage(dataList, WINDOW_SIZE);
        
        JSONObject result = new JSONObject();
        result.put("code", 0);
        result.put("msg", "");
        result.put("count", smoothedData.size());
        result.put("data", smoothedData);
        result.put("originalData", dataList);
        return result;
    }
    
    /**
     * 应用滑动平均算法
     * 
     * @param dataList 原始数据列表
     * @param windowSize 窗口大小
     * @return 处理后的数据列表
     */
    private List<GnssStatusMsg> applyMovingAverage(List<GnssStatusMsg> dataList, int windowSize) {
        if (dataList.size() <= 1) {
            return new ArrayList<>(dataList);
        }
        
        List<GnssStatusMsg> result = new ArrayList<>(dataList.size());
        
        // 初始窗口
        Deque<Float> rollWindow = new LinkedList<>();
        Deque<Float> pitchWindow = new LinkedList<>();
        Deque<Float> yawWindow = new LinkedList<>();
        
        for (int i = 0; i < dataList.size(); i++) {
            GnssStatusMsg currentMsg = dataList.get(i);
            GnssStatusMsg smoothedMsg = new GnssStatusMsg();
            
            // 复制基本属性
            smoothedMsg.setId(currentMsg.getId());
            smoothedMsg.setDeviceid(currentMsg.getDeviceid());
            smoothedMsg.setCreatetime(currentMsg.getCreatetime());
            smoothedMsg.setDevicetime(currentMsg.getDevicetime());
            smoothedMsg.setTenantid(currentMsg.getTenantid());
            smoothedMsg.setDtustate(currentMsg.getDtustate());
            smoothedMsg.setRssi(currentMsg.getRssi());
            smoothedMsg.setVoltage(currentMsg.getVoltage());
            smoothedMsg.setSolarvoltage(currentMsg.getSolarvoltage());
            smoothedMsg.setChargecurrency(currentMsg.getChargecurrency());
            smoothedMsg.setChargewatt(currentMsg.getChargewatt());
            smoothedMsg.setTemperature(currentMsg.getTemperature());
            smoothedMsg.setHumidity(currentMsg.getHumidity());
            
            // 添加当前值到窗口
            if (currentMsg.getRoll() != null) rollWindow.addLast(currentMsg.getRoll());
            if (currentMsg.getPitch() != null) pitchWindow.addLast(currentMsg.getPitch());
            if (currentMsg.getYaw() != null) yawWindow.addLast(currentMsg.getYaw());
            
            // 保持窗口大小
            if (rollWindow.size() > windowSize) rollWindow.removeFirst();
            if (pitchWindow.size() > windowSize) pitchWindow.removeFirst();
            if (yawWindow.size() > windowSize) yawWindow.removeFirst();
            
            // 计算平均值
            if (!rollWindow.isEmpty()) {
                float rollSum = 0;
                for (Float val : rollWindow) rollSum += val;
                smoothedMsg.setRoll(rollSum / rollWindow.size());
            } else {
                smoothedMsg.setRoll(currentMsg.getRoll());
            }
            
            if (!pitchWindow.isEmpty()) {
                float pitchSum = 0;
                for (Float val : pitchWindow) pitchSum += val;
                smoothedMsg.setPitch(pitchSum / pitchWindow.size());
            } else {
                smoothedMsg.setPitch(currentMsg.getPitch());
            }
            
            if (!yawWindow.isEmpty()) {
                float yawSum = 0;
                for (Float val : yawWindow) yawSum += val;
                smoothedMsg.setYaw(yawSum / yawWindow.size());
            } else {
                smoothedMsg.setYaw(currentMsg.getYaw());
            }
            
            result.add(smoothedMsg);
        }
        
        return result;
    }

    /**
     * 导出excel
     *
     * @param session      HttpSession
     * @param request HttpServletRequest
     * @param response     HttpServletResponse
     * @throws Exception
     */
    @RequestMapping("/gnss/msg/status/export")
    @ResponseBody
    public void exportData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception {
        this.export(session, request, response);
    }

    /**
     * 获取实体类的class
     *
     * @return 实体类的class
     */
    @Override
    public Class<GnssStatusMsg> getEntityClass() {
        return GnssStatusMsg.class;
    }

    /**
     * 获取实体类对应的mybatis mapper
     *
     * @return 实体类对应的mybatis mapper
     */
    @Override
    public BaseMapper<GnssStatusMsg> getMapper() {
        return statusMsgMapper;
    }
}
