package com.alfredlibrary;

import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.star_zero.sse.EventHandler;
import com.star_zero.sse.EventSource;
import com.star_zero.sse.MessageEvent;

import java.util.HashMap;
import java.util.Map;

public class SseClientModule extends ReactContextBaseJavaModule implements EventHandler, LifecycleEventListener {

    private final String TAG = "SseClientModule";

    private final ReactApplicationContext reactContext;
    private EventSource eventSource = null;

    public SseClientModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
        reactContext.addLifecycleEventListener(this);
    }

    @Override
    public String getName() {
        return "SseClient";
    }

    @ReactMethod
    public void connect(String authHeader, String url) {
        Log.d(TAG, "SSE Connection requested.");
        disconnect();
        Map<String, String> header = new HashMap<>();
        header.put("Authorization", authHeader);
        eventSource = new EventSource(url, header, this);
        eventSource.connect();
    }

    @ReactMethod
    public void disconnect() {
        if (eventSource != null) {
            eventSource.close();
            eventSource = null;
        }
    }

    private void sendEvent(String type) {
        sendEvent(type, null);
    }

    private void sendEvent(String type, MessageEvent event) {
        String eventName = "SseEvent";

        WritableMap params = Arguments.createMap();
        params.putString("type", type);

        if (event != null) {
            params.putString("data", event.getData());
        }

        this.reactContext
            .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
            .emit(eventName, params);
    }

    // Start Event Handler listeners
    @Override
    public void onOpen() {
        sendEvent("sse_connection_open");
        Log.d(TAG, "SSE Connection open.");
    }

    @Override
    public void onMessage(MessageEvent event) {
        sendEvent("sse_connection_message", event);
        Log.d(TAG, "Message received: "+event.getData());
    }

    @Override
    public void onError(Exception e) {
        sendEvent("sse_connection_error");
        Log.d(TAG, "Error detected on connection.");
    }

    @Override
    public void onHostResume() {
        if (eventSource != null) {
            eventSource.connect();
            sendEvent("sse_connection_connect");
        }
    }

    @Override
    public void onHostPause() {
        if (eventSource != null) {
            eventSource.close();
            sendEvent("sse_connection_close");
        }
    }

    @Override
    public void onHostDestroy() {

    }
}
