package com.example.surveillanceapp;

import android.content.Intent;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class ConnectionHandler {

    public static MqttAndroidClient client;
    private Context context;

    String topicStr2 = "Motion/";
    String topicStr3 = "Detection/";
    String topicStr4 = "Photo/";
    String topicStr5 = "Info/";
    String topicStr6 = "Unknown/";

    public ConnectionHandler(Context context){
        this.context = context;
    }

    public void connectClient(final Intent intent){
        String textMQTTHost = intent.getStringExtra(MainActivity.EXTRA_SERVER);
        String textUserName = intent.getStringExtra(MainActivity.EXTRA_NAME);
        String textPassword = intent.getStringExtra(MainActivity.EXTRA_PASSWORD);

        String clientId = MqttClient.generateClientId();
        client = new MqttAndroidClient(context, "tcp://" + textMQTTHost, clientId);

        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(textUserName);
        options.setPassword(textPassword.toCharArray());

        try {
            IMqttToken token = client.connect(options);
            client.registerResources(context);
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Toast.makeText(context, "Connection was successful", Toast.LENGTH_LONG).show();
                    setSubscription();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Toast.makeText(context, "Connection was unsuccessful", Toast.LENGTH_LONG).show();
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }

        client.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                System.out.println("Message:\n" + cause.getMessage());

                connectClient(intent);
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                sendBroadcast(topic, message.getPayload());
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {

            }
        });
    }

    private void setSubscription(){
        try {
            client.subscribe(topicStr2,0);
            client.subscribe(topicStr3,0);
            client.subscribe(topicStr4,0);
            client.subscribe(topicStr5,0);
            client.subscribe(topicStr6,0);
        } catch (MqttException e){
            e.printStackTrace();
        }
    }

    public static boolean sendMessage(String topic, String message) {
        try {
            client.publish(topic, message.getBytes(), 0, false);
            return true;
        } catch (MqttException e) {
            e.printStackTrace();
        }
        return false;
    }

    private void sendBroadcast(String topic, byte[] message){

        Calendar c = Calendar.getInstance();
        System.out.println("Current time => "+c.getTime());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = df.format(c.getTime());

        String listH = formattedDate+"\n" +topic + new String(message);

        Intent intentL = new Intent("ListOfMessages").putExtra("history", listH);
        intentL.putExtra("topic", topic);
        intentL.putExtra("bytes", message);
        intentL.putExtra("message", new String(message));
        LocalBroadcastManager.getInstance(context).sendBroadcast(intentL);
    }

    public void disconnectClient(){
        try {
            IMqttToken token = client.disconnect();
            client.unregisterResources();
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    Toast.makeText(context,"Disconnected", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    Toast.makeText(context,"Disconnection failed", Toast.LENGTH_LONG).show();

                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}