package com.imdroid.sec_exapi.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.imdroid.common.util.GsonUtil;
import com.imdroid.common.util.NumberUtils;
import com.imdroid.sec_exapi.entity.GnssQueryResponse;
import com.imdroid.secapi.dto.GnssCalcData;
import com.imdroid.secapi.dto.GnssCalcDataMapper;
import com.imdroid.secapi.dto.GnssDevice;
import com.imdroid.secapi.dto.GnssDeviceMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;

@RestController
public class GnssDataApi {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    GnssCalcDataMapper dataMapper;
    @Autowired
    GnssDeviceMapper deviceMapper;

    final Logger logger = LoggerFactory.getLogger(GnssDataApi.class);

    @GetMapping(value = "/gnss/data")
    public String query(HttpServletRequest request, String projectName, String deviceId,
                        String beginDate, String endDate, Integer pageSize, String sortType) {
        Integer tenantId = (Integer) request.getAttribute("tenantId");
        MPJQueryWrapper queryWrapper = new MPJQueryWrapper<GnssCalcData>()
                .selectAll(GnssCalcData.class);
        queryWrapper.eq("t.tenantid",tenantId);
        if(StrUtil.isBlank(deviceId)){
            queryWrapper.leftJoin("gnssdevices d on t.deviceid=d.deviceid");
            queryWrapper.eq("d.project_id",projectName);
        }
        else {
            //queryWrapper.leftJoin("gnssdevices d on t.deviceid=d.deviceid");
            queryWrapper.eq("t.deviceid",deviceId);
        }

        queryWrapper.isNotNull("rpose");

        if(!StrUtil.isBlank(beginDate)){
            queryWrapper.ge("t.createtime",beginDate);
        }

        if(!StrUtil.isBlank(endDate)){
            queryWrapper.le("t.createtime",endDate);
        }

        boolean isAsc=true;
        if(StrUtil.isBlank(sortType) || sortType.equals("asc")){
            queryWrapper.orderByAsc("t.createtime");
        }
        else{
            queryWrapper.orderByDesc("t.createtime");
            isAsc=false;
        }

        if(pageSize!=null){
            if(pageSize > 1000) pageSize=3000;
            queryWrapper.last("limit "+pageSize*3);
        }
        else{
            queryWrapper.last("limit 300");
        }

        List<GnssCalcData> dataList = dataMapper.selectList(queryWrapper);
        GnssQueryResponse gnssResponse = new GnssQueryResponse();
        LocalDateTime lastRecordTime = null;
        gnssResponse.OK();

        HashMap<String, GnssDevice> deviceHashMap = new HashMap<>();
        HashMap<String, LocalDateTime> deviceRecordTimeMap = new HashMap<>();

        for (GnssCalcData data : dataList) {
            LocalDateTime recordTime = data.getCreatetime();
            lastRecordTime = deviceRecordTimeMap.get(data.getDeviceid());
            if(lastRecordTime == null){
                lastRecordTime = recordTime;

            }
            if(isAsc) {
                if (lastRecordTime.isBefore(recordTime) || lastRecordTime.isEqual(recordTime)) {
                    addToResponse(gnssResponse, data, deviceHashMap);
                    deviceRecordTimeMap.put(data.getDeviceid(), recordTime.plusMinutes(30));
                }
            }
            else{
                if (lastRecordTime.isAfter(recordTime) || lastRecordTime.isEqual(recordTime)) {
                    addToResponse(gnssResponse, data, deviceHashMap);
                    deviceRecordTimeMap.put(data.getDeviceid(), recordTime.minusMinutes(30));
                }
            }
        }

        String json = GsonUtil.toJson(gnssResponse);
        logger.info(json);

        deviceHashMap.clear();

        return json;
    }

    void addToResponse(GnssQueryResponse rsp, GnssCalcData data,HashMap<String, GnssDevice> deviceHashMap){
        String deviceId = data.getDeviceid();
        Double rpose = data.getRpose();
        Double rposn = data.getRposn();
        Double rposd = data.getRposd();
        GnssDevice device = deviceHashMap.get(deviceId);
        if(device==null){
            QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("deviceid", deviceId);
            device = deviceMapper.selectOne(queryWrapper);
            if(device!=null) deviceHashMap.put(deviceId, device);
        }
        if(device!=null){
            if(device.getIpose()!=null) rpose-=device.getIpose();
            if(device.getIposn()!=null) rposn-=device.getIposn();
            if(device.getIposd()!=null) rposd-=device.getIposd();
        }

        GnssQueryResponse.GnssData gnssData = new GnssQueryResponse.GnssData();
        gnssData.setDeviceId(deviceId);
        gnssData.setCreateTime(data.getCreatetime().format(formatter));
        gnssData.setRpose(NumberUtils.scale(rpose, 2));
        gnssData.setRposn(NumberUtils.scale(rposn, 2));
        gnssData.setRposu(NumberUtils.scale(rposd, 2));
        rsp.getData().add(gnssData);
    }

}


