package com.imdroid.beidou_fwd.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.imdroid.secapi.dto.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Forwarder {
    String name;
    String description;
    Integer tenantId;
    boolean useFwdId;

    @Autowired
    private GnssDeviceMapper deviceMapper;

    @Autowired
    private GnssCalcDataMapper gnssDataMapper;

    @Autowired
    private FwdRecordMapper fwdRecordsMapper;

    @Autowired
    GnssGroupFwdMapper fwdMapper;

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    void init(String name, String desc, Integer tenantId, boolean useFwdId){
        this.name = name;
        this.description = desc;
        this.tenantId = tenantId;
        this.useFwdId = useFwdId;
        QueryWrapper<GnssGroupFwd> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",name);
        GnssGroupFwd gnssGroupFwd = fwdMapper.selectOne(queryWrapper);
        if(gnssGroupFwd == null){
            gnssGroupFwd = new GnssGroupFwd();
            gnssGroupFwd.setName(name);
            gnssGroupFwd.setDescription(description);
            gnssGroupFwd.setDevice_num(0);
            fwdMapper.insert(gnssGroupFwd);
        }
        else{
            gnssGroupFwd.setDescription(description);
            fwdMapper.updateById(gnssGroupFwd);
        }
    }

    void forwardCurrentGnss(String fwdGroupId) {
        LocalDateTime nowTime = LocalDateTime.now();
        ConcurrentHashMap<String, List<GnssCalcData>> projects = new ConcurrentHashMap<>();

        // 转发数据
        String sendAfterTime = nowTime.minusMinutes(30).format(formatter);

        QueryWrapper<GnssDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fwd_group_id", fwdGroupId)
                .or()
                .eq("fwd_group_id2", fwdGroupId);
        List<GnssDevice> gnssDeviceList = deviceMapper.selectList(queryWrapper);
        List<GnssCalcData> recordsToSend;
        for(GnssDevice device:gnssDeviceList){
            String projectId = device.getProject_id();
            if(projectId == null) continue;

            recordsToSend = projects.get(projectId);
            if(recordsToSend == null){
                recordsToSend = new ArrayList<>();
                projects.put(projectId,recordsToSend);
            }
            QueryWrapper<GnssCalcData> gnssQueryWrapper = new QueryWrapper<>();
            gnssQueryWrapper.eq("deviceid",device.getDeviceid());
            gnssQueryWrapper.ge("createtime",sendAfterTime);
            gnssQueryWrapper.orderByDesc("createtime");
            gnssQueryWrapper.eq("enabled",true);
            gnssQueryWrapper.isNotNull("rb562e");
            gnssQueryWrapper.last("limit 1");
            GnssCalcData record = gnssDataMapper.selectOne(gnssQueryWrapper);
            if(record!=null) {
                // 替换成推送用的名字和数值
                if(device.getB562e()!=null &&
                        device.getB562n()!=null &&
                        device.getB562d()!=null){
                    record.setRb562e(record.getRb562e()-device.getB562e());
                    record.setRb562n(record.getRb562n()-device.getB562n());
                    record.setRb562d(record.getRb562d()-device.getB562d());
                }
                if(useFwdId && device.getFwddeviceid()!=null && device.getFwddeviceid().trim().length()>0) {
                    record.setDeviceid(device.getFwddeviceid());
                }
                recordsToSend.add(record);
            }
        }

        // 按项目打包推送
        int totalSendNum = 0;
        boolean fwdFailed = false;
        for (Map.Entry<String, List<GnssCalcData>> entry: projects.entrySet()){
            String projectId = entry.getKey();
            List<GnssCalcData> records = entry.getValue();
            if(records.size() == 0) continue;

            int sendNum = send(projectId, records);

            FwdRecord fwdRecord = new FwdRecord();
            fwdRecord.setProject_id(projectId);
            fwdRecord.setTenantid(tenantId);
            fwdRecord.setDevicenum((short) records.size());
            fwdRecord.setStarttime(nowTime);
            fwdRecord.setEndtime(nowTime);
            fwdRecord.setFwd_group_id(fwdGroupId);

            if(sendNum > 0) {
                totalSendNum += sendNum;
                // 记录推送
                fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
            }
            else{
                fwdRecord.setState(FwdRecord.STATE_FWD_FAILED);
                fwdFailed = true;
            }
            fwdRecordsMapper.insert(fwdRecord);
        }

        // 更新推送信息
        if(totalSendNum>0) updateFwd(totalSendNum, true);
        else if(fwdFailed) updateFwd(totalSendNum, false);

    }

    void forwardHistoryGnss(String fwdGroupId) {
        // 1.从转发记录表里检索待补传记录时间表，含设备Id，时间段
        QueryWrapper<FwdRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fwd_group_id",fwdGroupId);
        queryWrapper.eq("state",FwdRecord.STATE_UPLOAD_DONE);
        List<FwdRecord> fwdRecordsList = fwdRecordsMapper.selectList(queryWrapper);
        // 2.检索这个这个时间段的解算结果，如果有数据则单个终端转发，标志记录为已补传
        int totalSendNum = 0;
        boolean fwdFailed = false;
        for(FwdRecord fwdRecord:fwdRecordsList){
            // 查找device
            QueryWrapper<GnssDevice> deviceQueryWrapper = new QueryWrapper<>();
            deviceQueryWrapper.eq("fwd_group_id", fwdGroupId);
            deviceQueryWrapper.eq("deviceid", fwdRecord.getDeviceid());
            GnssDevice device = deviceMapper.selectOne(deviceQueryWrapper);
            if(device == null) continue;

            // 查找位置记录
            QueryWrapper<GnssCalcData> calcDataQueryWrapper = new QueryWrapper<>();
            calcDataQueryWrapper.eq("deviceid", fwdRecord.getDeviceid());
            calcDataQueryWrapper.ge("createtime", fwdRecord.getStarttime());
            calcDataQueryWrapper.le("createtime", fwdRecord.getEndtime());
            calcDataQueryWrapper.orderByAsc("createtime");
            calcDataQueryWrapper.eq("enabled",true);
            calcDataQueryWrapper.isNotNull("rb562e");
            List<GnssCalcData> calcDataList = gnssDataMapper.selectList(calcDataQueryWrapper);
            // 推送记录
            int sendNum = sendBatch(device, fwdRecord.getProject_id(), calcDataList);
            if(sendNum > 0) {
                // 记录推送结果
                fwdRecord.setState(FwdRecord.STATE_FWD_DONE);
                totalSendNum += sendNum;
            }
            else{
                fwdRecord.setState(FwdRecord.STATE_FWD_FAILED);
                fwdFailed = true;
            }
            fwdRecordsMapper.updateById(fwdRecord);
        }

        // 更新推送信息
        if(totalSendNum>0) updateFwd(totalSendNum, true);
        else if(fwdFailed) updateFwd(totalSendNum, false);
    }

    int sendBatch(GnssDevice device, String projectId, List<GnssCalcData> records){
        if(records.size() == 0) return 0;

        LocalDateTime lastTime = records.get(0).getCreatetime();

        for(GnssCalcData calcData:records){
            if(calcData.getCreatetime().isAfter(lastTime.plusMinutes(28))){
                // 推送
                lastTime = calcData.getCreatetime();
                // 替换推送名和值
                if(useFwdId && device.getFwddeviceid()!=null && device.getFwddeviceid().trim().length()>0) {
                    calcData.setDeviceid(device.getFwddeviceid());
                }
                if(device.getB562e()!=null &&
                        device.getB562n()!=null &&
                        device.getB562d()!=null){
                    calcData.setRb562e(calcData.getRb562e()-device.getB562e());
                    calcData.setRb562n(calcData.getRb562n()-device.getB562n());
                    calcData.setRb562d(calcData.getRb562d()-device.getB562d());
                }
            }
            else{
                calcData.setEnabled(false);//借用来表示不推送，不会保存到数据库
            }
        }

        return send(projectId, records);
    }

    int send(String projectId, List<GnssCalcData> records) {
        return 0;
    }

    void updateFwd(int fwd_num, boolean isFwdOK){
        QueryWrapper<GnssGroupFwd> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name",name);
        GnssGroupFwd gnssGroupFwd = fwdMapper.selectOne(queryWrapper);
        if(gnssGroupFwd != null){
            gnssGroupFwd.setFwd_device_num(fwd_num);
            gnssGroupFwd.setResult(isFwdOK);
            gnssGroupFwd.setUpdatetime(LocalDateTime.now());
            fwdMapper.updateById(gnssGroupFwd);
        }
    }
}
