package ai.panoptic.vital_sign_camera

import ai.panoptic.wvs.camera.availableCameraDevices
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.annotation.NonNull
import androidx.core.content.ContextCompat
import androidx.lifecycle.*
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/** VitalSignCameraPlugin */
class VitalSignCameraPlugin: FlutterPlugin, MethodCallHandler, ActivityAware,
  RequestPermissionsResultListener {

  companion object {
    const val TAG = "VitalSignCameraPlugin"

    fun parsePermissionStatus(status: Int): String {
      return when (status) {
        PackageManager.PERMISSION_DENIED -> "denied"
        PackageManager.PERMISSION_GRANTED -> "authorized"
        else -> "not-determined"
      }
    }

  }

  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel
  private lateinit var pluginBinding: FlutterPlugin.FlutterPluginBinding
  private lateinit var context: Context
  private lateinit var activity: Activity
  private lateinit var activityBinding:ActivityPluginBinding
  private val coroutineScope = CoroutineScope(Dispatchers.Main)
  private var requestCode = 1
  private var permissionRequests = HashMap<Int, Result>()

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {

    Log.d("VitalSignCameraPlugin", "onAttachedToEngine")
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "vital_sign_camera_plugin")
    channel.setMethodCallHandler(this)
    pluginBinding = flutterPluginBinding
    context = flutterPluginBinding.applicationContext

  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    Log.d(TAG, "onAttachedToActivity")

    val lifecycle: Lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding)

    pluginBinding.platformViewRegistry.registerViewFactory(
      "ai.panoptic/flutter_vital_sign_camera",
      VitalSignCameraFactory(pluginBinding.binaryMessenger, lifecycle)
    )

    activity = binding.activity
    activityBinding = binding
    activityBinding.addRequestPermissionsResultListener(this)

  }

  override fun onDetachedFromActivityForConfigChanges() {}

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}

  override fun onDetachedFromActivity() {
    activityBinding.removeRequestPermissionsResultListener(this)
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {

    when (call.method) {
      "availableCameraDevices" -> {
        coroutineScope.launch {
          val devices = availableCameraDevices(context)
          val returnValue = devices.map { it.map }
          Log.d(TAG, "$returnValue")
          result.success(returnValue)
        }
      }
      "getCameraPermissionStatus" -> {
        Log.d(TAG, "getCameraPermissionStatus")
        val status =
          parsePermissionStatus(
            ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA))
        result.success(status)
      }
      "requestCameraPermission" -> {
        Log.d(TAG, "requestCameraPermission")
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
          // API 21 and below always grants permission on app install
          result.success("authorized")
        }
        activity.requestPermissions(arrayOf(Manifest.permission.CAMERA), requestCode)
        permissionRequests[requestCode] = result
        requestCode += 1

      }


    }
  }

  override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
  ): Boolean {

    permissionRequests[requestCode]?.let {
      val permissionStatus = if (grantResults.isNotEmpty()) grantResults[0] else PackageManager.PERMISSION_DENIED
      it.success(parsePermissionStatus(permissionStatus))
      permissionRequests.remove(requestCode)
      return true
    }

    return false
  }

}
