package code;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

//import scenari.Automa;
//import scenari.Scenari;

public class Subscriber implements MqttCallback {

	private Luci luci;
	private Esecutore esec;
	static Boolean runningEsec;
	public String sensM;
	Boolean giorno=false;

	public Subscriber(Luci luci, Esecutore esec, String sensm) {
		this.luci = luci;
		this.esec = esec;
		this.sensM = sensm;
		Subscriber.runningEsec = false;
	}

	@Override
	public void connectionLost(Throwable arg0) {
		Helper.print("connessione persa\t" + arg0);
		final Date d = new Date();
		Date d2 = new Date();
		long time = Math.abs(d2.getTime() - d.getTime());

		while (time < 600000) {
			try {
				Helper.print("retrying...");

				Luci.main(null);
				return;
			} catch (MqttException | JSONException | IOException e) {
				Helper.print("non sono riusciuto");
				d2 = new Date();
				time = Math.abs(d2.getTime() - d.getTime());
			}
		}
		Helper.print("fuori dal while");
		if (time >= 600000) {
			Helper.print("Tentativo di riconnessione fallito");
			System.exit(1);
		}
	}

	@Override
	public void deliveryComplete(IMqttDeliveryToken arg0) {
		Helper.print("inviato");
	}

	@Override
	public void messageArrived(String topic, MqttMessage message) throws MqttException, JSONException, IOException {

		Helper.print("new message: " + topic + "  " + message.toString());

		if (topic.equals(Luci.getMqttTree("rpc/", "luci"))) {
			Helper.print("invio la mia configurazione");
			sendFile(Luci.getMqttTree("from/", "luci"));
			return;
		}

		if (topic.equals("to/all")) {
			Helper.print("invio il mio stato");
			sendStatus(Luci.getMqttTree("from/", "luci"));
			return;
		}

		JSONObject msgJson = new JSONObject(message.toString());

		// la beaglebone risponde sutopic {"event":1} se è acceso, 0 altrimenti

		if (topic.equals(Luci.getMqttTree("to", "luci/new"))) {

			JSONObject config = new JSONObject(Helper.leggiFile(Luci.FILE_ZONA));

			String nome = msgJson.getString("nome");
			for (Luce k : Luci.luciList) {
				if (k.getNome().equalsIgnoreCase(nome)) {
					System.out.println("Nome gia' presente, inserimento annullato\n");

					return;
				}
			}
			int k = Luci.luciList.size();
			config.put("lamp" + k, msgJson);
			// System.out.println("---"+config);
			Luci.luciList.add(new Luce(msgJson));// ,"lamp"+k
			Helper.scriviFile(config, Luci.FILE_ZONA);

			luci.sendMqttMessage(Luci.getMqttTree("from", "luci/new"), msgJson.toString());

			return;
		}

		if (topic.equals(Luci.getMqttTree("to", "luci/sensore"))) {
			// salvati il sensore di movimento

			sensM = msgJson.getString("sensM");
			// devo aggiornare in file
			JSONObject config = new JSONObject(Helper.leggiFile(Luci.FILE_ZONA));
			config.put("sensM", sensM);
			Helper.scriviFile(config, Luci.FILE_ZONA);

			luci.sendMqttMessage(Luci.getMqttTree("from", "luci/sensore"), msgJson.toString());
			return;

		} // gruppo2/luci/luci/sensore

		// sensM tempo
		if (topic.equals(Luci.getMqttTree("from", "gpio/" + sensM))) {
			System.out.println(giorno);
			if(giorno)return;
			
			if (msgJson.has("event") && msgJson.getInt("event") == 1) {
				if (runningEsec) {
					Esecutore.timer.cancel();
					Esecutore.timer.purge();
				} else {
					for (Luce k : Luci.luciList) {
						if (k.getStato())
							Esecutore.j.add(k);
					}
				}
				runningEsec = true;
				esec.run(runningEsec);
//				
			}
			return;
		}

		// controllo i topic su cui mi arrivano gli on/off
		if (topic.startsWith(Luci.getMqttTree("from", "gpio/IN"))) {
			// prendo l'ultimo pezzo del topic, diventa il mio nome

			String pezzo = topic.substring(23);// seleziono solo il nome della lamp
			System.out.println("nome lamp\t" + pezzo);

			for (int i = 0; i < Luci.luciList.size(); i++) {
				if (Luci.luciList.get(i).getIN().equalsIgnoreCase(pezzo) && msgJson.has("event")
						&& msgJson.getInt("event") == 1) {// non è k.getIN()?

					String req = Luci.luciList.get(i).getStato() ? "{cmd:0}" : "{cmd:1}";
					luci.sendMqttMessage(Luci.getMqttTree("to", "gpio/" + Luci.luciList.get(i).getOUT()), req);
				}
			}
			return;
		} // gruppo2/luci/luci/sensore

		if (topic.startsWith(Luci.getMqttTree("from", "gpio/OUT"))) {
			if (msgJson.has("status"))
				return;
			String pezzo = topic.substring(23);// seleziono solo il nome della lamp
			System.out.println("nome lamp\t" + pezzo);

			for (int i = 0; i < Luci.luciList.size(); i++) {
				if (Luci.luciList.get(i).getOUT().equalsIgnoreCase(pezzo) && msgJson.has("event")) {
					// && msgJson.getInt("event")==1)

					boolean stato = msgJson.getInt("event") == 1;

					Luci.luciList.get(i).setStato(stato);// (!Luci.luciList.get(i).getStato());

					JSONObject config = new JSONObject(Helper.leggiFile(Luci.FILE_ZONA));

					JSONObject lux = new JSONObject();
					lux.put("nome", Luci.luciList.get(i).getNome());
					lux.put("stato", Luci.luciList.get(i).getStato());
					lux.put("input", Luci.luciList.get(i).getIN());
					lux.put("output", Luci.luciList.get(i).getOUT());

					config.put("lamp" + i, lux);

					Helper.scriviFile(config, Luci.FILE_ZONA);
					// mando conferma
					lux.remove("input");
					lux.remove("nome");
					luci.sendMqttMessage(Luci.getMqttTree("from", "luci/luce"), lux.toString());

				}
			}
			return;
		}
		
		if (topic.startsWith(Luci.getMqttTree("from", "arduino/AN0"))) {
			if (msgJson.has("event")){
//				
//				if(msgJson.getInt("event")<200)giorno=false;
//				else giorno=true;
				
				giorno=(msgJson.getInt("event")>=200);
			}
		return;
		}
		

		Helper.print("Impossibile");
	}

	private void sendFile(String topic) throws MqttException, JSONException, IOException {
		JSONObject j = new JSONObject(Helper.leggiFile(Luci.FILE_ZONA));

		luci.sendMqttMessage(topic, j.toString());
	}

	private void sendStatus(String topic) throws MqttException, JSONException, IOException {
		JSONObject j = new JSONObject(Helper.leggiFile(Luci.FILE_ZONA));
		j.remove("sensM");

		luci.sendMqttMessage(topic, j.toString());
	}

}