package com.muyu.car.gateway.service.Impl;

import com.muyu.car.gateway.domain.VehicleConnection;
import com.muyu.car.gateway.domain.VinIp;
import com.muyu.car.gateway.domain.model.MqttServerModel;
import com.muyu.car.gateway.domain.properties.MqttProperties;
import com.muyu.car.gateway.domain.req.VehicleConnectionReq;
import com.muyu.car.gateway.mapper.CarOneClickOperationMapper;
import com.muyu.car.gateway.service.CarOneClickOperationService;
import com.muyu.common.core.domain.Result;
import com.muyu.common.redis.service.RedisService;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.muyu.car.gateway.config.RabbitmqConfig.EXCHANGE_TOPICS_INFORM;
import static com.muyu.car.gateway.config.RabbitmqConfig.ROUTINGKEY_SMS;

/**
 * @author Lenovo
 * @ Tool：IntelliJ IDEA
 * @ Author：CHX
 * @ Date：2024-09-26-20:16
 * @ Version：1.0
 * @ Description：车辆一键操作业务实现层
 */
@Log4j2
@Service
public class CarOneClickOperationServiceImpl implements CarOneClickOperationService {

    @Autowired
    private CarOneClickOperationMapper carOneClickOperationMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取连接信息
     *
     * @param vehicleConnectionReq 车辆连接请求参数
     * @return
     */
    @Override
    public Result<MqttServerModel> getConnect(VehicleConnectionReq vehicleConnectionReq) {
        log.info("车辆连接请求:{}", vehicleConnectionReq.toString());

        VehicleConnection vehicleConnection = new VehicleConnection();
        //车辆vin
        vehicleConnection.setVehicleVin(vehicleConnectionReq.getVehicleVin());
        //用户名
        vehicleConnection.setUsername(vehicleConnectionReq.getUsername());
        //密码(vin+时间戳+随机数)
        vehicleConnection.setPassword(vehicleConnectionReq.getVehicleVin() + vehicleConnectionReq.getTimestamp() + vehicleConnectionReq.getNonce());
        //查询有没有这辆车的vin码
        List<String> selectVehicle = carOneClickOperationMapper.selectByVehicleVin(vehicleConnectionReq.getVehicleVin());

        if (selectVehicle.isEmpty()) {
            //添加连接信息
            carOneClickOperationMapper.addConnect(vehicleConnection);
            log.info("车辆上线成功");
        } else {
            throw new RuntimeException("车辆无法重复上线");

        }
        //先判断vin码
        if (redisService.hasKey(vehicleConnectionReq.getVehicleVin())) {
            log.error("=============车辆:{}已经绑定过了", vehicleConnectionReq.getVehicleVin());
            throw new RuntimeException("=============车辆已经绑定过了");
        }
        MqttProperties mqttProperties = new MqttProperties();
        List<VehicleConnection> vehicleVin = selectByVehicleVin(vehicleConnectionReq.getVehicleVin());
        for (VehicleConnection connection : vehicleVin) {
            mqttProperties.setClientId(connection.getVehicleVin());
            mqttProperties.setUserName(connection.getUsername());
            mqttProperties.setPassword(connection.getPassword());
        }
        mqttProperties.setTopic("vehicle");
        mqttProperties.setQos(0);
        //判断redis有没有count键
        if (redisTemplate.hasKey("oneCount")) {
            //取出count
            Integer count = Integer.valueOf(redisTemplate.opsForValue().get("oneCount"));
            if (count == 1) {
                redisTemplate.opsForValue().set("oneCount", String.valueOf(0));
            } else {
                redisTemplate.opsForValue().set("oneCount", String.valueOf(count + 1));
            }
            //根据游标count获取服务IP
//            String ip = redisTemplate.opsForList().index("ipList", count);
            Object ipList = redisService.redisTemplate.opsForList().index("oneIpList", count);

            log.info("=========================oneIpList:" + ipList);
            //关联车辆和服务
            this.addIpAddress(new VinIp(vehicleConnectionReq.getVehicleVin(), ipList.toString()));
            //响应信息
            log.info("车辆:{}", vehicleConnectionReq.getVehicleVin() + "绑定成功:{}", ipList);
            mqttProperties.setBroker("tcp://" + ipList + ":1883");
            // 使用交换机发送消息
            rabbitTemplate.convertAndSend(EXCHANGE_TOPICS_INFORM, ROUTINGKEY_SMS, mqttProperties);
            log.info("============================发送消息成功:{}", mqttProperties);
            return Result.success(new MqttServerModel("tcp://" + ipList + ":1883", "vehicle"));
        } else {
            redisTemplate.opsForValue().set("oneCount", String.valueOf(0));
            //根据游标count获取服务器Ip
            Object ipList = redisService.redisTemplate.opsForList().index("oneIpList", 0);
            //关联车辆和服务
            this.addIpAddress(new VinIp(vehicleConnectionReq.getVehicleVin(), ipList.toString()));
            //响应信息
            log.info("车辆:{}", vehicleConnectionReq.getVehicleVin(), "与:{}绑定成功", ipList);
            mqttProperties.setBroker("tcp://" + ipList + ":1883");
            // 使用交换机发送消息
            rabbitTemplate.convertAndSend(EXCHANGE_TOPICS_INFORM, ROUTINGKEY_SMS, mqttProperties);
            log.info("============================发送消息成功:{}", mqttProperties);
            return Result.success(new MqttServerModel("tcp://" + ipList + ":1883", "vehicle"));
        }
    }

    /**
     * 添加车辆绑定IP地址存入redis中
     */
    public void addIpAddress(VinIp vinIp) {
        if (vinIp == null || vinIp.getVin() == null || vinIp.getVin().isEmpty() || vinIp.getIp() == null || vinIp.getIp().isEmpty()) {
            throw new IllegalArgumentException("vin 或 ip 不能为空或无效");
        }
        redisService.setCacheObject(vinIp.getVin(), vinIp.getIp());
    }

    /**
     * 查询车辆绑定的服务器信息
     *
     * @param vehicleVin 车辆vin码集合
     * @return
     */
    public List<VehicleConnection> selectByVehicleVin(String vehicleVin) {
        return carOneClickOperationMapper.getMqttServerModel(vehicleVin);
    }
}
