package org.springblade.third.doordevice.provider.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.springblade.common.constant.Instruct;
import org.springblade.core.tool.api.R;
import org.springblade.device.dto.UserInfoDto;
import org.springblade.device.entity.DoorDevice;
import org.springblade.third.doordevice.entity.InstructPublishLog;
import org.springblade.third.doordevice.entity.MqConf;
import org.springblade.third.doordevice.provider.IDeviceUserService;
import org.springblade.third.doordevice.provider.IOpenDoorService;
import org.springblade.third.doordevice.service.IInstructPublishLogService;
import org.springblade.third.doordevice.service.IMqConfService;
import org.springblade.third.doordevice.utils.RabbitMqConnectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lidexi
 * @date 2021/5/24 17:28
 */
@Service
public class JVTMqProvider implements IOpenDoorService<Map<String,Object>>, IDeviceUserService<Map<String,Object>> {

	@Autowired
	private IMqConfService mqConfService;
	@Autowired
	private IInstructPublishLogService instructPublishLogService;

	@Override
	public R addUser(DoorDevice doorDevice, Map<String,Object> userInfoDto) {
		R result = publishMessage(doorDevice, Instruct.add_user_face, userInfoDto);
		if(result.isSuccess()){
			return R.success("人脸新增成功");
		}else{
			return result;
		}
	}

	@Override
	public R deleteUser(DoorDevice doorDevice, Map<String,Object> userInfoDto) {
		R result = publishMessage(doorDevice, Instruct.delete_user_face, userInfoDto.get("id"));
		if(result.isSuccess()){
			return R.success("人脸删除成功");
		}else{
			return result;
		}
	}

	@Override
	public R deleteUserPermission(DoorDevice doorDevice, Map<String,Object> userInfoDto) {
		R result = publishMessage(doorDevice, Instruct.delete_user_face, userInfoDto.get("id"));
		if(result.isSuccess()){
			return R.success("人脸删除成功");
		}else{
			return result;
		}
	}

	@Override
	public R remoteOpenDoor(DoorDevice doorDevice, Map<String,Object> userInfoDto) {
		R result = publishMessage(doorDevice, Instruct.open_door, userInfoDto.get("id"));
		if(result.isSuccess()){
			return R.success("远程开门成功");
		}else{
			return result;
		}
	}

	/**
	 * 发送消息
	 * @param doorDevice
	 * @param instruct
	 * @param data
	 */
	private R publishMessage(DoorDevice doorDevice, Instruct instruct, Object data){
		MqConf mqConf = mqConfService.getById(null);
		if (null == mqConf){
			return R.fail("设备未绑定队列");
		}
		Connection connection = RabbitMqConnectionUtil.openConnection(mqConf);
		Channel channel = null;
		try {
			channel = connection.createChannel();
			long instrcutId = IdWorker.getId();
			//  构建数据
			Map<String,Object> map = new HashMap<>(3);
			map.put("id", instrcutId);
			map.put("code", instruct.getCode());
			map.put("data", data);
			map.put("serialNumber", doorDevice.getSerialNum());
			String msg = JSON.toJSONString(map, SerializerFeature.WriteNonStringValueAsString, SerializerFeature.WriteDateUseDateFormat);
			//  推送消息
			channel.basicPublish(instruct.getExchangeName(), doorDevice.getSerialNum(), null, msg.getBytes(StandardCharsets.UTF_8));
			//  保存指令推送日志
			InstructPublishLog publishLog = new InstructPublishLog(instrcutId, doorDevice, instruct, JSON.toJSONString(data, SerializerFeature.WriteNonStringValueAsString, SerializerFeature.WriteDateUseDateFormat));
			instructPublishLogService.save(publishLog);
			return R.status(true);
		}catch (Exception e){
			e.printStackTrace();
			return R.fail("下发异常");
		}finally {
			//  关闭连接,抛出异常
			RabbitMqConnectionUtil.closeConnection(connection,channel);
		}
	}
}
