package fr.zng.xxzx.mqtt2;

import java.math.BigDecimal;

import javax.swing.JTextArea;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;

import com.alibaba.fastjson.JSONObject;

import fr.zng.xxzx.common.cacheData.ZngCacheData;
import fr.zng.xxzx.common.dao.DictDao;
import fr.zng.xxzx.common.dao.EquipWsdDao;
import fr.zng.xxzx.common.dao.TdFlowDao;
import fr.zng.xxzx.common.dao.UnoDao;
import fr.zng.xxzx.common.dao.UpdataDao;
import fr.zng.xxzx.common.dao.impl.DictDaoImpl;
import fr.zng.xxzx.common.dao.impl.EquipWsdDaoImpl;
import fr.zng.xxzx.common.dao.impl.TdFlowDaoImpl;
import fr.zng.xxzx.common.dao.impl.UnoDaoImpl;
import fr.zng.xxzx.common.dao.impl.UpdataDaoImpl;
import fr.zng.xxzx.common.entity.DictEntity;
import fr.zng.xxzx.common.entity.EquipWsdEntity;
import fr.zng.xxzx.common.entity.HeartDataEntity;
import fr.zng.xxzx.common.entity.TdEndDataEntity;
import fr.zng.xxzx.common.entity.TdEndReplyDataEntity;
import fr.zng.xxzx.common.entity.TdFlowEntity;
import fr.zng.xxzx.common.entity.TdSqDataEntity;
import fr.zng.xxzx.common.entity.TdSqReplyDataEntity;
import fr.zng.xxzx.common.entity.UnoEntity;
import fr.zng.xxzx.common.entity.UpDataEntity;
import fr.zng.xxzx.common.util.CommUtil;
import fr.zng.xxzx.common.util.StringUtil;
import fr.zng.xxzx.main.XmtApplication;

/**
 * 发布消息的回调类
 * 
 * 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
 * 每个客户机标识都需要一个回调实例。在此示例中，构造函数传递客户机标识以另存为实例数据。 在回调中，将它用来标识已经启动了该回调的哪个实例。
 * 必须在回调类中实现三个方法：
 * 
 * public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
 * 
 * public void connectionLost(Throwable cause)在断开连接时调用。
 * 
 * public void deliveryComplete(MqttDeliveryToken token)) 接收到已经发布的 QoS 1 或 QoS 2
 * 消息的传递令牌时调用。 由 MqttClient.connect 激活此回调。
 * 
 */
public class PushCallback2 implements MqttCallback {
	private JTextArea jta;
	public Server2 client;

	public PushCallback2(Server2 client,JTextArea jta) {
		this.jta = jta;
		this.client = client;
	}

	public void connectionLost(Throwable cause) {
		// 连接丢失后，一般在这里面进行重连
		System.out.println("连接断开，可以做重连");
		CommUtil.doPrint(jta, "MQTT:", "连接断开,开始尝试重新连接");
		ZngCacheData.isConnect = 0;
		XmtApplication.changeConnectState(0);

	}

	public void deliveryComplete(IMqttDeliveryToken token) {
		System.out.println("deliveryComplete---------" + token.isComplete());
		CommUtil.doPrint(jta, "MQTT:", "deliveryComplete---------" + token.isComplete());
	}

	public void messageArrived(String topic, MqttMessage message) throws Exception {
		// subscribe后得到的消息会执行到这里面
		System.out.println("接收消息主题 : " + topic);
		System.out.println("接收消息Qos : " + message.getQos());
		System.out.println("接收消息内容 : " + new String(message.getPayload()));
		

		String data = new String(message.getPayload());
		if ("".equals(data))
			return;

		try {
			if (Server2.SUBSCRIBETOPIC.equals(topic)) {
				CommUtil.doPrint(jta, "MQTT:", "接收消息主题 : " + topic);
				CommUtil.doPrint(jta, "MQTT:", "接收消息Qos : " + message.getQos());
				CommUtil.doPrint(jta, "MQTT:", "接收消息内容 : " + new String(message.getPayload()));
				// 上传投递信息 授权
				TdSqDataEntity updata = JSONObject.parseObject(data, TdSqDataEntity.class);
				// 是否通过
				int PayState = 2;
				String PayStateMsg = "未知失败";
				String bankno = updata.UID;
				if(updata.UID.length()>=24) {
					bankno = updata.UID.substring(0,24);
				}
				if (updata != null) {
					// 该用户是否注册
					if (checkUno(bankno)) {
						PayState = 0;
						PayStateMsg = "网络授权通过\r\n" + 
								"请在20秒内按下指定的投口按钮后，等待开门投递！";
					} else {
						PayState = 1;
						PayStateMsg = "授权失败,无此用户";
					}
				}
				CommUtil.doPrint(jta, "MQTT:", "授权状态: " + PayState + ","+PayStateMsg);
				// 发布TOPIC China-XMT/DangeraRubo/IssuePayMsg/{TID}
				// TODO
				JSONObject jsonObject = new JSONObject();
				TdSqReplyDataEntity en = new TdSqReplyDataEntity();
				en.TID = updata.TID;
				en.UID = bankno;
				en.PayNumber = updata.PayNumber;
				en.PayState = PayState;
				en.PayStateMsg = PayStateMsg;
				en.Time = updata.Time;
				en.PayOutTime = 20;
				String reply = jsonObject.toJSONString(en);
				Server2.TOPIC = "ChinaXMT/DangeraRubo/IssuePayMsg/"+updata.TID;
//				Server2.TOPIC = "XMT_Admin_0510/DangeraRubo/IssuePayMsg/"+updata.TID;
				Server2.topic();
				CommUtil.doPrint(jta, "MQTT:", "发布消息主题: " + Server2.TOPIC);
				publish(1, reply);
				CommUtil.doPrint(jta, "MQTT:", "发布消息内容: " + reply);

			} else if (Server2.SUBSCRIBETOPIC2.equals(topic)) {
				CommUtil.doPrint(jta, "MQTT:", "接收消息主题 : " + topic);
				CommUtil.doPrint(jta, "MQTT:", "接收消息Qos : " + message.getQos());
				CommUtil.doPrint(jta, "MQTT:", "接收消息内容 : " + new String(message.getPayload()));
				// 上传投递信息 结束
				TdEndDataEntity updata = JSONObject.parseObject(data, TdEndDataEntity.class);
				if (updata != null) {
					String bankno = updata.UID;
					if(updata.UID.length()>=24) {
						bankno = updata.UID.substring(0,24);
					}
					
//					String cno = updata.Type;
//					String colno = updata.Number;
					BigDecimal gar = new BigDecimal(updata.Kg).multiply(new BigDecimal("1000")).setScale(0);
					String garbage = gar+"";
					// 是否通过
					String flag = "";

					// 获取用户信息
					UnoDao dao = new UnoDaoImpl();
					// 通过银行卡号查找用户
					UnoEntity user = dao.getVillageUserCinfoByUno(bankno);
					if(user!=null) {
						TdFlowEntity en = new TdFlowEntity();
						// 投递
						en.setDel("0");
						en.setImei(updata.TID);
						// cno 根据类型找到cno  dict表
						DictEntity dictEn1 = new DictEntity();
						String type = updata.Type;
//						if(updata.Type.equals("不可回收")){
//							type = "不可回收";
//						} else if (updata.Type.equals("可回收物")){
//							type = "可回收";
//						}
						dictEn1.setDvalue(type);
						DictDao dictDao = new DictDaoImpl();
						DictEntity dictEn = dictDao.getDictByTypeValue(dictEn1);
						if(dictEn != null){
							en.setCno(dictEn.getDno());
						}
						en.setColno(updata.Number);
						en.setWeight(new BigDecimal(garbage));
						// 积分 重量为0时给1个积分 10g等于1积分
						BigDecimal bg2 = new BigDecimal(10);
//						en.setPoint(new BigDecimal(garbage).compareTo(BigDecimal.ZERO) == 0 ? new BigDecimal("1.0")
//								: new BigDecimal(garbage).divide(bg2, 1, BigDecimal.ROUND_HALF_UP));
						en.setPoint(new BigDecimal("0"));
						en.setUno(user.getUno());
						en.setVno(user.getVno());
						en.setCreater(user.getUno());
						en.setUpdater(user.getUno());
						if (!StringUtil.isEmpty(user)) {
							// 投递前总量
							en.setBweight(user.getWeight());
							// 投递后总量
							en.setAweight(user.getWeight().add(new BigDecimal(garbage)));
							// 交易前积分
							en.setBpoint(user.getPoint());
							// 交易后积分
							en.setApoint(user.getPoint().add(en.getPoint()));
							if (InsertTdFlow(en) > 0) {
								flag = "01";
							} else {
								flag = "02";
							}
						} else {
							// 投递前总量
							en.setBweight(BigDecimal.ZERO);
							// 投递后总量
							en.setAweight(new BigDecimal(garbage));
							// 交易前积分
							en.setBpoint(BigDecimal.ZERO);
							// 交易后积分
							en.setApoint(en.getPoint());
							if (InsertTdFlowErr(en) > 0) {
								flag = "01";
							} else {
								flag = "02";
							}
						}
					}
					
					
					// 回复TOPIC China-XMT/DangeraRubo/IssuePayEndMsg/{TID}
					// TODO
					JSONObject jsonObject = new JSONObject();
					TdEndReplyDataEntity en2 = new TdEndReplyDataEntity();
					en2.TID = updata.TID;
					en2.UID = bankno;
					en2.PayNumber = updata.PayNumber;
					en2.PayMode = updata.PayMode;
					if("01".equals(flag)) {
						en2.PayStep = "3";
						en2.PayStepMsg = "数据已完成上传";
					} else {
						en2.PayStep = "10";
						en2.PayStepMsg = "数据录入失败";
					}
					
					en2.Number = updata.Number;
					en2.Type = updata.Type;
					en2.Kg = updata.Kg;
					en2.Time = updata.Time;
					String reply = jsonObject.toJSONString(en2);
					Server2.TOPIC2 = "ChinaXMT/DangeraRubo/IssuePayEndMsg/"+updata.TID;
//					Server2.TOPIC2 = "XMT_Admin_0510/DangeraRubo/IssuePayEndMsg/"+updata.TID;
					
					CommUtil.doPrint(jta, "MQTT:", "发布消息主题: " + Server2.TOPIC2);
					Server2.topic2();
					publish(2, reply);
					CommUtil.doPrint(jta, "MQTT:", "发布消息内容: " + reply);
					
					
				}
			} else if (Server2.SUBSCRIBETOPIC3.equals(topic)) {
				CommUtil.doPrint(jta, "MQTT:", "接收消息主题 : " + topic);
				CommUtil.doPrint(jta, "MQTT:", "接收消息Qos : " + message.getQos());
				CommUtil.doPrint(jta, "MQTT:", "接收消息内容 : " + new String(message.getPayload()));
				// 心跳
				HeartDataEntity heartEn =  JSONObject.parseObject(data, HeartDataEntity.class);
				if(heartEn != null) {
					CommUtil.doPrint(jta, "MQTT:", "收到心跳: " + heartEn.TID);
					String equipmentCode = heartEn.TID;
					String sd = heartEn.Humidity;
					String wd = heartEn.Temp;
					//一小时插入一次温湿度
			    	if(checkWsd(equipmentCode)<=0){
				    	EquipWsdEntity en = new EquipWsdEntity();
						en.setImei(equipmentCode);
						en.setLsd(sd);
						en.setLwd(wd);
//						insertWsd(en);
						CommUtil.doPrint(jta, "MQTT:", "插入温湿度: " + sd + " "+wd);
					}
				}
			}
			
			else {
				CommUtil.doPrint(jta, "MQTT:", "未知消息主题");
			}

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("订阅消息解析失败");
			CommUtil.doPrint(jta, "MQTT:", "订阅消息解析失败");
		}

	}

	/**
	 * 温湿度插入
	 * */
	private int insertWsd(EquipWsdEntity en){
		EquipWsdDao dao = new EquipWsdDaoImpl();
		return dao.insert(en);
	}
	/**
	 * 发布消息
	 * 
	 * @param message
	 */
	private int publish(int topic, String message) {
		System.out.println("发布消息:" + message);
		int ret = 0;
		client.message = new MqttMessage();
		client.message.setQos(2);
		client.message.setRetained(false);
		client.message.setPayload(message.getBytes());
		try {
			if (topic == 1) {
				client.publish(client.topic, client.message);
			} else if (topic == 2) {
				client.publish(client.topic2, client.message);
			} 

		} catch (MqttPersistenceException e) {
			e.printStackTrace();
			ret = -1;
			CommUtil.doPrint(jta, "MQTT:", "MQTT通信异常，请检查网络连接或MQTT服务器");
		} catch (MqttException e) {
			e.printStackTrace();
			ret = -1;
			CommUtil.doPrint(jta, "MQTT:", "MQTT通信异常，请检查网络连接或MQTT服务器");
		}
		return ret;
	}
	
	
	/**
	 * 审核用户名
	 * 
	 * @param uno
	 * @return
	 */
	private Boolean checkUno(String uno) {
		UnoDao dao = new UnoDaoImpl();
		UnoEntity en = dao.getVillageUserCinfoByUno(uno);
		if (en != null) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 插入投递记录
	 * 
	 * @return
	 */
	private int InsertTdFlow(TdFlowEntity en) {
		TdFlowDao dao = new TdFlowDaoImpl();
		return dao.insert(en);
	}

	private int checkWsd(String imei) {
		EquipWsdDao dao = new EquipWsdDaoImpl();
		return dao.checkWsd(imei);
	}

	/**
	 * 插入异常投递记录
	 * 
	 * @return
	 */
	private int InsertTdFlowErr(TdFlowEntity en) {
		TdFlowDao dao = new TdFlowDaoImpl();
		return dao.insertErr(en);
	}
}