package ai.panoptic.vital_sign_camera

import ai.panoptic.wvs.camera.*
import ai.panoptic.wvs.engine.Converter
import android.content.Context
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.annotation.RequiresApi
import androidx.lifecycle.Lifecycle
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView

@RequiresApi(Build.VERSION_CODES.O)
class FlutterVitalSignCamera internal constructor(
    context: Context,
    messenger: BinaryMessenger,
    id: Int,
    props: Map<String, Any>,
    lifecycle: Lifecycle
) : PlatformView, MethodChannel.MethodCallHandler, EventChannel.StreamHandler, VitalSignCameraEventHandler {

    private val camera: VitalSignCamera
    private val methodChannel: MethodChannel
    private var eventSink:  EventChannel.EventSink? = null
    private val mainThread = Handler(Looper.getMainLooper())

    override fun getView(): View {
        return camera
    }

    init {
        camera = VitalSignCamera(context, MLKitFaceDetector(), lifecycle, this)

        methodChannel = MethodChannel(messenger, "ai.panoptic/channel/flutter_vital_sign_camera_$id")
        methodChannel.setMethodCallHandler(this)

        val eventChannel = EventChannel(messenger, "ai.panoptic/channel/flutter_vital_sign_camera_processed_frame_event_$id")
        eventChannel.setStreamHandler(this)

        camera.setProps(props)
    }

    override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
        when (methodCall.method) {
            "startScanning" -> {
                camera.startStartScanning()
                        .thenAccept { result.success(null) }
                        .exceptionally {
                            result.error("-1", it.message, it.cause)
                            return@exceptionally null
                        }
            }
            "stopScanning" -> {
                camera.stopScanning()
                        .thenAccept { result.success(null) }
                        .exceptionally {
                            result.error("-2", it.message, it.cause)
                            return@exceptionally null
                        }
            }
            "configure" -> {
                val arguments = methodCall.arguments as? Map<String, Any>
                arguments?.let {
                    camera.setProps(it)
                }

            }
            else -> {
                result.notImplemented()
            }
        }
    }

    override fun dispose() {
        // camera.destroy()
    }

    override fun onVideoFrameProcessed(result: ai.panoptic.wvs.engine.ProcessFrameResult): kotlin.Unit {
        // Already handled in onEvent.
        // No need to handle here.
    }

    override fun onEvent(cameraView: VitalSignCamera, eventName: String, event: Map<String,Any>?) {
        when(eventName) {
            "videoFrameProcessed" -> {
                eventSink?.let {
                    mainThread.post {
                        it.success(event)
                    }
                }
            }
        }
    }

    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
        eventSink = events
    }

    override fun onCancel(arguments: Any?) {
        eventSink = null
    }

}
