package com.reactnativecore;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.widget.Toast;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.util.Log;

import androidx.annotation.RequiresApi;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

public class RNWiredHeadsetDetectModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
   BroadcastReceiver broadcastReceiver;
   boolean Microphone_Plugged_in = false;

   private void onChange(final String deviceName) {
      // Report device name (if not empty) to the host
      WritableMap payload = Arguments.createMap();
      WritableArray deviceList = Arguments.createArray();
      if (!deviceName.isEmpty()) {
          deviceList.pushString(deviceName);
      }
      payload.putArray("devices", deviceList);
      ReactContext reactContext = getReactApplicationContext();
      if(reactContext != null && reactContext.hasActiveCatalystInstance()) {
         reactContext
         .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
         .emit("onWiredChange", payload);
      }
   }

   public RNWiredHeadsetDetectModule(ReactApplicationContext reactContext) {
      super(reactContext);
      IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
      broadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            int i;
            if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
               i = intent.getIntExtra("state", -1);
               if (i == 0) {
                  Microphone_Plugged_in = false;
                  onChange("Wired Plugged Out");
               }
               if (i == 1) {
                  Microphone_Plugged_in = true;
                  onChange("Wired Plugged Im");
               }
            }
         }
      };
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
         reactContext.registerReceiver(this.broadcastReceiver, receiverFilter, Context.RECEIVER_NOT_EXPORTED);
      } else {
         reactContext.registerReceiver(this.broadcastReceiver, receiverFilter);
      }
      reactContext.addLifecycleEventListener(this);
   }

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

   private boolean hasWiredHeadset() {
      final String TAG = "DyteRNWiredHeadsetDetect";
      final Activity activity = getCurrentActivity();
      final AudioManager audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
         return audioManager.isWiredHeadsetOn();
      } else {
          final AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
          for (AudioDeviceInfo device : devices) {
              final int type = device.getType();
              if (type == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
                  return true;
              } else if (type == AudioDeviceInfo.TYPE_USB_DEVICE) {
                  return true;
              } else if (type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES) {
                  return true;
              }
          }
          return false;
      }
  }

   @ReactMethod
   public void getIsWiredHeadsetPluggedIn(Promise promise) {
      promise.resolve(this.hasWiredHeadset());
   }

   @RequiresApi(api = Build.VERSION_CODES.M)
   @Override
   public void onHostResume() {
      final Activity activity = getCurrentActivity();
        if (activity == null) {
            return;
        }
        final AudioManager audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
        AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
        for (AudioDeviceInfo device : devices) {
            final int type = device.getType();
            if (type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES || type == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
                // Device is found
                final String deviceName = device.getProductName().toString();
                onChange(deviceName);
                return;
            }
        }
        // No devices found
        onChange("");
   }

   @Override
   public void onHostPause() {
   }

   @Override
   public void onHostDestroy() {
   }

}
