#pragma once

TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;

String GetPayloadContent(char * data, size_t len) {
	String content = "";
	for(size_t i = 0; i < len; i++)
	{
		content.concat(data[i]);
	}
	return content;
}

void ConnectToMqtt() {
	LOG_INFO("Connecting to MQTT...");
	mqttClient.connect();
}

void OnMqttConnect(bool sessionPresent) {
	LOG_INFO("Connected to MQTT.");
	SuscribeMqtt();
}

void OnMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
	LOG_WARNING("Disconnected from MQTT.");

	if(WiFi.isConnected())
	{
		xTimerStart(mqttReconnectTimer, 0);
	}
}

void OnMqttSubscribe(uint16_t packetId, uint8_t qos) {
	LOG_INFO("Subscribe acknowledged. PacketID: %d / QoS: %d", packetId, qos);
}

void OnMqttUnsubscribe(uint16_t packetId) {
	LOG_INFO("Unsubscribe Acknowledged. PacketID: %d",packetId);
}

void OnMqttPublish(uint16_t packetId) {
	LOG_INFO("Publish Acknowledged. PacketID: %d", packetId);
}

void ConnectWiFi_STA(bool useStaticIP = true) {
  WiFi.mode(WIFI_STA);
  if(useStaticIP) {
    WiFi.config(ip, gateway, subnet);
    WiFi.setHostname(hostname);
  }
	//WiFi.begin(ssid, password);
	WiFi.begin();

  while (WiFi.status() != WL_CONNECTED) {
    delay(10);
  }

	if (LOG_LEVEL_ENABLED(LOG_LEVEL_INFO)){
	  Serial.println("");
	  Serial.print("NIGGA - Initiating STA:\t");
	  Serial.println(ssid);
	  Serial.print("IP address:\t");
	  Serial.println(WiFi.localIP());
	}
}

void ConnectWiFi_AP(bool useStaticIP = false) {
  Serial.println("");
  WiFi.mode(WIFI_AP);
  while(!WiFi.softAP(ssid, password)) {
    Serial.println(".");
    delay(100);
  }

  if(useStaticIP) WiFi.softAPConfig(ip, gateway, subnet);

	if (LOG_LEVEL_ENABLED(LOG_LEVEL_INFO)){
	  Serial.println("");
	  Serial.print("Iniciado AP:\t");
	  Serial.println(ssid);
	  Serial.print("IP address:\t");
	  Serial.println(WiFi.softAPIP());
	}
}

void NetworkEvent(arduino_event_id_t event, arduino_event_info_t info) {
	LOG_INFO("(NET) event: %d\n", event);
	IPAddress ip = WiFi.localIP();
	switch(event)
	{
	case ARDUINO_EVENT_WIFI_STA_GOT_IP:
		LOG_DEBUG("WiFi connected. IP Address:  %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
		//xTimerStop(wifiReconnectTimer, 0);
		ConnectToMqtt();
		break;
	case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
		LOG_WARNING("WiFi Lost Connection! :(");
		xTimerStop(mqttReconnectTimer, 0);
		xTimerStart(wifiReconnectTimer, 0);
		break;

  case ARDUINO_EVENT_ETH_START:
    LOG_DEBUG("ETH Started");
    ETH.setHostname(hostname);
    break;
  case ARDUINO_EVENT_ETH_CONNECTED:
    LOG_DEBUG("ETH Connected !");
		break;
  case ARDUINO_EVENT_ETH_GOT_IP:
    LOG_INFO("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif));
    WiFi.disconnect(true);
		ConnectToMqtt();
    break;
  case ARDUINO_EVENT_ETH_LOST_IP:
    LOG_WARNING("ETH Lost IP");
    break;
  case ARDUINO_EVENT_ETH_DISCONNECTED:
    LOG_WARNING("ETH Disconnected");
    xTimerStop(mqttReconnectTimer, 0);
		xTimerStart(wifiReconnectTimer, 0);
    break;
  case ARDUINO_EVENT_ETH_STOP:
    LOG_INFO("ETH Stopped");
    xTimerStop(mqttReconnectTimer, 0);
		xTimerStart(wifiReconnectTimer, 0);
    break;
  default:
		break;
	}
}

void InitMqtt() {
	mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(ConnectToMqtt));
	wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(5000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(ConnectWiFi_STA));

	mqttClient.onConnect(OnMqttConnect);
	mqttClient.onDisconnect(OnMqttDisconnect);

	mqttClient.onSubscribe(OnMqttSubscribe);
	mqttClient.onUnsubscribe(OnMqttUnsubscribe);

	mqttClient.onMessage(OnMqttReceived);
	mqttClient.onPublish(OnMqttPublish);

	mqttClient.setServer(MQTT_HOST, MQTT_PORT);
	mqttClient.setCredentials(MQTT_USER, MQTT_PASS);
}
