package com.haussteuerung;

import static java.nio.charset.StandardCharsets.UTF_8;

import android.util.Log;

import androidx.annotation.NonNull;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.Objects;

import javax.net.ssl.SSLSocketFactory;

public class MqttClient {
    static org.eclipse.paho.client.mqttv3.MqttClient client = null;
    static String logContent = "";
    static String tv_Zustand1 = "", tv_Zustand2 = "", tv_Zustand3 = "", tv_Zustand4 = "", tv_Zustand5 = "", tv_Zustand6 = "";
    static String tv_Zustand7 = "", tv_Zustand8 = "", tv_Zustand9 = "", tv_Zustand10 = "", tv_Zustand11 = "", tv_Zustand12 = "";
    static String tv_Zustand13 = "", tv_Zustand14 = "", tv_Zustand15 = "", tv_Zustand16 = "", tv_Zustand17 = "", tv_Zustand18 = "";

    public static void connect() {
        try {
            client = new org.eclipse.paho.client.mqttv3.MqttClient(
                    "wss://mqtt.klebl.info:443",
                    MainActivity.ID, // ClientId
                    new MemoryPersistence());
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    Log.d("MQTT connloss", "client lost connection " + cause);
                    Log.d("MQTT connloss", Objects.requireNonNull(cause.getMessage()));
                    Log.d("MQTT connless", String.valueOf(client.getDebug()));
                    Log.d("MQTT connloss", String.valueOf(MqttClient.client.isConnected()));
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) {
                    Log.d("MQTTLOG", topic + ": " + message.toString());
                    if (topic.equals("stat/Haussteuerung/Alarm")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        if (jsonObject.get("Zustand").getAsString().equals("true")) {
                            MainActivity.alarmStatus = true;
                        } else if (jsonObject.get("Zustand").getAsString().equals("false")) {
                            MainActivity.alarmStatus = false;
                        }
                    }

                    if (topic.equals("stat/Haussteuerung/Waschmaschine/WM1")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        if (jsonObject.get("Zustand").getAsString().equals("ein")) {
                            MainActivity.wm1Status = true;
                        } else if (jsonObject.get("Zustand").getAsString().equals("aus")) {
                            MainActivity.wm1Status = false;
                        }
                    }

                    if (topic.equals("stat/Haussteuerung/Waschmaschine/WM2")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        if (jsonObject.get("Zustand").getAsString().equals("ein")) {
                            MainActivity.wm2Status = true;
                        } else if (jsonObject.get("Zustand").getAsString().equals("aus")) {
                            MainActivity.wm2Status = false;
                        }
                    }

                    if (topic.equals("stat/Haussteuerung/Log/List_Log")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        logContent = jsonObject.get("Zustand").getAsString().replace(";", "\n");
                    }

                    if (topic.equals("stat/Haussteuerung/Sky")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        activitySky.zeitSkyMqtt = jsonObject.get("Datum").getAsString();
                        activitySky.isChecked = jsonObject.get("CheckboxSky").getAsBoolean();
                    }

                    if (topic.equals("stat/Haussteuerung/Waschmaschine/Tom")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        activityLicht.nameTom = jsonObject.get("Name").getAsString();
                        activityLicht.checkedTom = jsonObject.get("Checkbox").getAsBoolean();
                    }

                    if (topic.equals("stat/Haussteuerung/Waschmaschine/Flo")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        activityLicht.nameFlo = jsonObject.get("Name").getAsString();
                        activityLicht.checkedFlo = jsonObject.get("Checkbox").getAsBoolean();
                    }

                    if (topic.equals("stat/Haussteuerung/Waschmaschine/Stefan")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        activityLicht.nameStefan = jsonObject.get("Name").getAsString();
                        activityLicht.checkedStefan = jsonObject.get("Checkbox").getAsBoolean();
                    }

                    if (topic.equals("stat/Haussteuerung/Glocke")) {
                        JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
                        activityLicht.nameGlocke = jsonObject.get("Name").getAsString();
                        activityLicht.checkedGlocke = jsonObject.get("Checkbox").getAsBoolean();
                    }

                    handleLWP(topic, message);

                    fensterZustaende(topic, message);
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.d("MQTTLOG", "delivery complete " + token);
                }
            });
        } catch (MqttException e) {
            Log.d("MQTTLOG", "Connect failed: " + e);
        }
        MqttConnectOptions mqttConnectOptions = getMqttConnectOptions();
        try {
            client.connect(mqttConnectOptions);
            subscribe("stat/Haussteuerung/#");
            // subscribe("fhem/temp/#");
            subscribe("fhem/Heizung/#");
            subscribe("tele/sonoff153/#");
            subscribe("growatt/#");
            Log.d("MQTTLOG", "client connected");
        } catch (MqttException e) {
            Log.d("MQTTLOG", "connection failed " + e.getMessage());
        }
    }

    @NonNull
    private static MqttConnectOptions getMqttConnectOptions() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName("steve");
        mqttConnectOptions.setPassword("Florian1".toCharArray());
        mqttConnectOptions.setAutomaticReconnect(true);
        mqttConnectOptions.setCleanSession(false);
        mqttConnectOptions.setKeepAliveInterval(15);
        mqttConnectOptions.setConnectionTimeout(30);
        mqttConnectOptions.setSocketFactory(SSLSocketFactory.getDefault());
        return mqttConnectOptions;
    }

    public static void subscribe(String topic) {
        try {
            client.subscribe(topic);
        } catch (MqttException e) {
            Log.d("MQTTLOG", "Subscribing failed: " + e);
        }
    }

    public static void publish(String topic, String message) {
        try {
            client.publish(topic, message.getBytes(UTF_8), 2, false);
            Log.d("MQTTLOG", "Message" + message + "published.");
        } catch (MqttException e) {
            Log.d("MQTTLOG", "Publish failed: " + e);
        }
    }

    public static void publish(String topic, String message, int qos, boolean retained) {
        try {
            client.publish(topic, message.getBytes(UTF_8), qos, retained);
            Log.d("MQTTLOG", "Message" + message + "published.");
        } catch (MqttException e) {
            Log.d("MQTTLOG", "Publish failed: " + e);
        }
    }

    public static void disconnect() {
        try {
            client.disconnect();
        } catch (MqttException e) {
            Log.d("MQTTLOG", "Disconnect failed: " + e);
        }
    }

    private static void handleLWP(String topic, MqttMessage message) {
        if (topic.equals("stat/Haussteuerung/LWP/Warmwasser")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            FragmentWW.isCheckedWW1 = jsonObject.get("CheckWW1").getAsBoolean();
            FragmentWW.isCheckedWW2 = jsonObject.get("CheckWW2").getAsBoolean();
            FragmentWW.isCheckedWW3 = jsonObject.get("CheckWW3").getAsBoolean();

            FragmentWW.switchWW1 = jsonObject.get("SilentModeWW1").getAsBoolean();
            FragmentWW.switchWW2 = jsonObject.get("SilentModeWW2").getAsBoolean();
            FragmentWW.switchWW3 = jsonObject.get("SilentModeWW3").getAsBoolean();

            FragmentWW.wwZeit1Mqtt = jsonObject.get("ZeitWW1").getAsString();
            FragmentWW.wwZeit2Mqtt = jsonObject.get("ZeitWW2").getAsString();
            FragmentWW.wwZeit3Mqtt = jsonObject.get("ZeitWW3").getAsString();
            FragmentWW.wwZeit4Mqtt = jsonObject.get("ZeitWW4").getAsString();
            FragmentWW.wwZeit5Mqtt = jsonObject.get("ZeitWW5").getAsString();
            FragmentWW.wwZeit6Mqtt = jsonObject.get("ZeitWW6").getAsString();

            FragmentWW.tempWw1 = jsonObject.get("TempWW1").getAsInt();
            FragmentWW.tempWw2 = jsonObject.get("TempWW2").getAsInt();
        }

        if (topic.equals("stat/Haussteuerung/LWP/Heizung")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            FragmentHeizung.isCheckedHZ1 = jsonObject.get("CheckHZ1").getAsBoolean();
            FragmentHeizung.isCheckedHZ2 = jsonObject.get("CheckHZ2").getAsBoolean();
            FragmentHeizung.isCheckedHZ3 = jsonObject.get("CheckHZ3").getAsBoolean();

            FragmentHeizung.hzZeit1Mqtt = jsonObject.get("ZeitHZ1").getAsString();
            FragmentHeizung.hzZeit2Mqtt = jsonObject.get("ZeitHZ2").getAsString();
            FragmentHeizung.hzZeit3Mqtt = jsonObject.get("ZeitHZ3").getAsString();
            FragmentHeizung.hzZeit4Mqtt = jsonObject.get("ZeitHZ4").getAsString();
            FragmentHeizung.hzZeit5Mqtt = jsonObject.get("ZeitHZ5").getAsString();
            FragmentHeizung.hzZeit6Mqtt = jsonObject.get("ZeitHZ6").getAsString();

            FragmentHeizung.switchHZ1 = jsonObject.get("SilentModeHZ1").getAsBoolean();
            FragmentHeizung.switchHZ2 = jsonObject.get("SilentModeHZ2").getAsBoolean();
            FragmentHeizung.switchHZ3 = jsonObject.get("SilentModeHZ3").getAsBoolean();

            FragmentHeizung.tempHz1 = jsonObject.get("TempHZ1").getAsInt();
            FragmentHeizung.tempHz2 = jsonObject.get("TempHZ2").getAsInt();
            FragmentHeizung.tempHz3 = jsonObject.get("TempHZ3").getAsInt();
        }


        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Boiler_oben")) {
            FragmentWW.tempBoilerOben = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Boiler_unten")) {
            FragmentWW.tempBoilerUnten = message.toString();
        }

        // Grossraum
        if (topic.equals("fhem/Heizung/MAX_Grossraum/Mode")) {
            FragmentHeizkoerper.modeHKGrossraum = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Grossraum/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKGrossraum = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Wohnzimmer")) {
            FragmentHeizkoerper.istTempHKGrossraum = message.toString();
        }

        // Doris
        if (topic.equals("fhem/Heizung/MAX_Doris_klein/Mode")) {
            FragmentHeizkoerper.modeHKDoris = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Doris_klein/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKDoris = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Doris")) {
            FragmentHeizkoerper.istTempHKDoris = message.toString();
        }

        // Doris Bad
        if (topic.equals("fhem/Heizung/MAX_Doris_Bad/Mode")) {
            FragmentHeizkoerper.modeHKDorisBad = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Doris_Bad/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKDorisBad = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Doris_Bad")) {
            FragmentHeizkoerper.istTempHKDorisBad = message.toString();
        }

        // Arbeitszimmer
        if (topic.equals("fhem/Heizung/MAX_Arbeitszimmer/Mode")) {
            FragmentHeizkoerper.modeHKArbeitszimmer = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Arbeitszimmer/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKArbeitszimmer = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Arbeitszimmer")) {
            FragmentHeizkoerper.istTempHKArbeitszimmer = message.toString();
        }

        // Vorraum
        if (topic.equals("fhem/Heizung/MAX_Vorraum/Mode")) {
            FragmentHeizkoerper.modeHKVorraum = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Vorraum/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKVorraum = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Vorraum/Temperatur")) {
            FragmentHeizkoerper.istTempHKVorraum = message.toString();
        }

        // WC EG
        if (topic.equals("fhem/Heizung/MAX_WC/Mode")) {
            FragmentHeizkoerper.modeHKWCEG = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_WC/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKWCEG = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_WC/Temperatur")) {
            FragmentHeizkoerper.istTempHKWCEG = message.toString();
        }

        // Bad
        if (topic.equals("fhem/Heizung/MAX_Bad/Mode")) {
            FragmentHeizkoerper.modeHKBad = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Bad/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKBad = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Bad")) {
            FragmentHeizkoerper.istTempHKBad = message.toString();
        }

        // Florian
        if (topic.equals("fhem/Heizung/MAX_Florian/Mode")) {
            FragmentHeizkoerper.modeHKFlorian = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Florian/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKFlorian = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Florian")) {
            FragmentHeizkoerper.istTempHKFlorian = message.toString();
        }

        // Stefan
        if (topic.equals("fhem/Heizung/MAX_Stefan/Mode")) {
            FragmentHeizkoerper.modeHKStefan = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Stefan/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKStefan = message.toString();
            Log.d("SollTempStefan", message.toString());
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Stefan")) {
            FragmentHeizkoerper.istTempHKStefan = message.toString();
            Log.d("IstTempStefan", message.toString());
        }

        // Dachboden
        if (topic.equals("fhem/Heizung/MAX_Dachboden/Mode")) {
            FragmentHeizkoerper.modeHKDachboden = message.toString();
        }

        if (topic.equals("fhem/Heizung/MAX_Dachboden/Solltemperatur")) {
            FragmentHeizkoerper.sollTempHKDachboden = message.toString();
        }

        if (topic.equals("stat/Haussteuerung/Temperatur/Temp_Dachboden")) {
            FragmentHeizkoerper.istTempHKDachboden = message.toString();
        }
    }

    public static void fensterZustaende(String topic, MqttMessage message) {
        if (topic.equals("stat/Haussteuerung/Fenster/Eingangstuer")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand1 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Garagetuer")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand2 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Kellertuer")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand3 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/TerrassenTuer_Doris")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand4 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/FensterLinks_Doris")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand5 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/FensterRechts_Doris")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand6 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/FensterBad_Doris")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand7 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Tom")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand8 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Wohnzimmer")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand9 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Esszimmer")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand10 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/EssplatzKueche")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand11 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Kueche")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand12 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Garderobe")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand13 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/WC")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand14 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Dachflaechenfenster")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand15 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Flo")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand16 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Stefan")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand17 = jsonObject.get("Zustand").getAsString();
        }

        if (topic.equals("stat/Haussteuerung/Fenster/Bad")) {
            JsonObject jsonObject = JsonParser.parseString(message.toString()).getAsJsonObject();
            tv_Zustand18 = jsonObject.get("Zustand").getAsString();
        }
    }
}
