package com.ruoyi.web.controller.system;
import com.ruoyi.system.domain.SysCar;
import com.ruoyi.system.domain.SysCompany;
import com.ruoyi.system.domain.SysDevice;
import com.ruoyi.system.domain.SysDeviceControl;
import com.ruoyi.system.mapper.SysCarMapper;
import com.ruoyi.system.service.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/SysCarController")
@ApiOperation("控制器定时更新信息")
@Component
public class SysCarController {

    @Autowired
    public SysCarService sysCarService;
    @Autowired
    public SysDeviceService sysDeviceService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private SysrealtimeService sysrealtimeService;
    @Autowired
    public SysDeviceVoService sysDeviceVoService;
    @Autowired
    public SysDeviceControlService sysDeviceControlService;
    @Autowired
    public SysWorkorderService sysWorkorderService;
    @Autowired
    public SysIndicatorsService sysIndicatorsService;

    /**
     * 更新车辆的控制器信息
     * 30秒更新一次
     */
    @ResponseBody
    @Scheduled(fixedRate = 30000)
    public void updatesyscar(){
        //将所有与车辆绑定的控制器数据进行查询
        List<SysCar> sysCarList=sysCarService.selectcontrollerId();
        //查询对应控制器的
        for (int i=0;i<sysCarList.size();i++) {
            if (sysCarList.get(i).getControllerId()==null||!sysCarList.get(i).equals("")){

            }else{
                //查询控制器的数据
                SysDevice latitude = sysDeviceService.selectsysdevice(sysCarList.get(i).getControllerId(), "纬度");
                SysDevice longitude = sysDeviceService.selectsysdevice(sysCarList.get(i).getControllerId(), "经度");
                //查询控制器的redis存储的经纬度，如果redis中没有该控制器的数据话，就进行redis的存储和mysql（车辆信息）的修改（避免因为频繁查询数据库导致服务宕机）
                // 构建模糊匹配的key前缀
                String redisKeyPattern = "workorder:coordinate:" + sysCarList.get(i).getControllerId() + ":*";

                // 获取所有匹配的key
                Set<String> keys = stringRedisTemplate.keys(redisKeyPattern);

                if (keys == null || keys.isEmpty()) {
                    String redisKey = "workorder:coordinate:" + sysCarList.get(i).getControllerId();
                    //如果没有话就进行存储
                    stringRedisTemplate.opsForHash().put(redisKey, "latitude", latitude.getV());
                    stringRedisTemplate.opsForHash().put(redisKey, "longitude", longitude.getV());
                    stringRedisTemplate.persist(redisKey);

                    String position = latitude.getV() + "," + longitude.getV();
                    //修改数据库中数据
                    sysCarService.updatecarposition(position, sysCarList.get(i).getCarId());
                    String url = "https://esos-iot.com:9443/syscar/trigger?carId=" + sysCarList.get(i).getCarId();
                    restTemplate.postForObject(url, null, String.class);
                } else {
                    //查询对应的redis中存储的数据
                    for (String key : keys) {
                        // 获取单条记录的所有字段
                        Map<Object, Object> coordinateMap = stringRedisTemplate.opsForHash().entries(key);
                        //对该数据进行对比
                        if (coordinateMap.get("latitude").equals(latitude.getV()) && coordinateMap.get("longitude").equals(longitude.getV())) {
                            //这里表示两个值都相同    就不需要任何操作
                        } else {
                            //进行修改数据
                            String redisKey = "workorder:coordinate:" + sysCarList.get(i).getControllerId();
                            stringRedisTemplate.opsForHash().put(redisKey, "latitude", latitude.getV());
                            stringRedisTemplate.opsForHash().put(redisKey, "longitude", longitude.getV());
                            stringRedisTemplate.persist(redisKey);
                            String position = latitude.getV() + "," + longitude.getV();
                            //修改数据库中数据
                            sysCarService.updatecarposition(position, sysCarList.get(i).getCarId());
                            //发生变化就进行修改操作（然后进行存储到redis中）
                            String url = "https://esos-iot.com:9443/syscar/trigger?carId=" + sysCarList.get(i).getCarId();
                            restTemplate.postForObject(url, null, String.class);
                        }
                    }
                }
            }
        }
    }


    @ResponseBody
    @Scheduled(fixedRate = 30000)
    public void insertdevice(){
        Set<String> activeKeys = null;
        try {
            //将redis中的数据全部查询出来然后过滤掉不想要的字段
            activeKeys = stringRedisTemplate.opsForSet().members("DSB:active:devices");
        }catch (Exception e){
            System.out.println("redis中无数据");
        }
        try {
            if (activeKeys == null || activeKeys.isEmpty()) {
                System.out.println("redis中无数据");
                return;
            }
            for (String redisKey : activeKeys) {
                Map<Object, Object> dataMap = stringRedisTemplate.opsForHash().entries(redisKey);
                if (dataMap == null || dataMap.isEmpty()) {
                    stringRedisTemplate.opsForSet().remove("DSB:active:devices", redisKey);
                    continue;
                }
                String[] parts = redisKey.split(":", 3);
                if (parts.length != 3 || !"DSB".equals(parts[0])) {
                    System.out.println("跳过非法 key: {}" + redisKey);
                    continue;
                }
                String controllerId = parts[1];
                //查询配置表
                List<SysDeviceControl> sysDeviceControlList = sysDeviceControlService.selectdevice("device");
                //检索数据库中是否存有
                Integer count = sysDeviceVoService.selectcount(controllerId);
                if (count != null && count > 0) {
                    StringBuilder keyvalue = new StringBuilder();
                    for (int i = 0; i < sysDeviceControlList.size(); i++) {
                        for (Map.Entry<Object, Object> entry : dataMap.entrySet()) {
                            String fieldKey = entry.getKey().toString();
                            String fieldvalue = entry.getValue().toString();
                            if (sysDeviceControlList.get(i).getControllerName().equals(fieldKey)) {
                                keyvalue.append(fieldKey).append("=/'").append(fieldvalue).append("/'");
                                if (i > sysDeviceControlList.size() - 1) {
                                    keyvalue.append(",");
                                }
                            }
                        }
                    }
                    //存在就进行修改
                    sysDeviceVoService.updatesysdevice(keyvalue.toString(), controllerId);
                } else {
                    //不存在就进行添加
                    StringBuilder key = new StringBuilder();
                    StringBuilder value = new StringBuilder();
                    for (int i = 0; i < sysDeviceControlList.size(); i++) {
                        for (Map.Entry<Object, Object> entry : dataMap.entrySet()) {
                            String fieldKey = entry.getKey().toString();
                            String fieldvalue = entry.getValue().toString();
                            if (sysDeviceControlList.get(i).getControllerName().equals(fieldKey)) {
                                key.append(fieldKey);
                                value.append(fieldvalue);
                                if (i > sysDeviceControlList.size() - 1) {
                                    key.append(",");
                                    value.append(",");
                                }
                            }
                        }
                    }
                    sysDeviceVoService.insertdevice(key.toString(), value.toString());
                }
            }
         }catch (Exception e){
             System.out.println("报错："+e);
         }
        }



    /**
     * 更新数据库实时数据
     */
    @Scheduled(fixedRate = 30000)
    @ResponseBody
    public void syncRedisToMySQL() {
        Set<String> activeKeys = stringRedisTemplate.opsForSet().members("DSB:active:devices");
        if (activeKeys == null || activeKeys.isEmpty()) return;
        for (String redisKey : activeKeys) {
            try {
                Map<Object, Object> dataMap = stringRedisTemplate.opsForHash().entries(redisKey);
                if (dataMap == null || dataMap.isEmpty()) {
                    stringRedisTemplate.opsForSet().remove("DSB:active:devices", redisKey);
                    continue;
                }

                // ✅ 正确解析：key 必须是 DSB:controllerId:metricName
                String[] parts = redisKey.split(":", 3);
                if (parts.length != 3 || !"DSB".equals(parts[0])) {
                    System.out.println("跳过非法 key: {}"+ redisKey);
                    continue;
                }
                String controllerId = parts[1];
                // 注意：这里不再用 parts[2] 作为 deviceId！
                String createTime = getStringValue(dataMap, "createTime");
                String timestamp = getStringValue(dataMap, "timestamp");
                String deviceId = getStringValue(dataMap, "device_id"); //从数据中取 UUID
                if (createTime == null || timestamp == null || deviceId == null) {
                    continue;
                }

                for (Map.Entry<Object, Object> entry : dataMap.entrySet()) {
                    String fieldKey = entry.getKey().toString();
                    // 跳过系统字段
                    if ("createTime".equals(fieldKey) || "timestamp".equals(fieldKey) || "device_id".equals(fieldKey)) {
                        continue;
                    }
                    String fieldValue = getStringValue(dataMap, fieldKey);
                    if (fieldValue == null) continue;
                    Integer count = sysrealtimeService.selectkey(controllerId, fieldKey);
                    if (count != null && count > 0) {
                        sysrealtimeService.updatetables(controllerId, createTime, fieldValue, timestamp, fieldKey, deviceId);
                    } else {
                        sysrealtimeService.inserttables(controllerId, createTime, deviceId, timestamp, fieldKey, fieldValue);
                    }
                }
            } catch (Exception e) {
                System.out.println("同步设备失败: {}"+ redisKey+e);
            }
        }
    }

    private String getStringValue(Map<Object, Object> map, String key) {
        Object val = map.get(key);
        return val == null ? null : val.toString().trim();
    }

    @Autowired
    public SysCompanyService sysCompanyServicel;

    /**
     * 更新指标信息
     * 根据公司去查询
     * 一直更新，然后如果遇见跨天的情况就是更新第二天的数据了
     */
    @Scheduled(fixedRate = 30000)
    @ResponseBody
    public void insertindicators(){
        try {
            LocalDate today = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String day = today.format(formatter);
            //查询所的合伙人公司
            List<SysCompany> sysCompanyList=sysCompanyServicel.selectcompany();
//            List<SysCar> sysCarList = sysCarService.selectcarall();
            for (int i = 0; i < sysCompanyList.size(); i++) {
                //查询今日的订单量
                Integer countworkorder = sysWorkorderService.selectworkordercount(sysCompanyList.get(i).getCompanyId(), day);
                //查询订单的收益或者是费用
                Double countprofit = sysWorkorderService.selectwokroderprofit(sysCompanyList.get(i).getCompanyId(), day);
                //存储到数据库中，如果天的数据存在就该为修改
                Integer count = sysIndicatorsService.selectcarcount(sysCompanyList.get(i).getCompanyId(), day);
                if (count <= 0) {
                    sysIndicatorsService.insertindicators(countworkorder, countprofit, sysCompanyList.get(i).getCompanyId(),day);
                } else {
                    sysIndicatorsService.updateindicators(countworkorder, countprofit, sysCompanyList.get(i).getCompanyId(),day);
                }
            }
        }catch (Exception e){
            System.out.println("————————————————————————————————————————————————————————————————————————————————————————————————————————————————");
            System.out.println(e);
        }
    }


}


