@file:Suppress("DEPRECATION")

package com.mrousavy.camera.frameprocessor

import android.util.Log
import androidx.annotation.Keep
import androidx.annotation.UiThread
import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.uimanager.UIManagerHelper
import com.mrousavy.camera.CameraView
import com.mrousavy.camera.core.ViewNotFoundError
import java.lang.ref.WeakReference

@Suppress("KotlinJniMissingFunction") // we use fbjni.
class VisionCameraProxy(private val reactContext: ReactApplicationContext) {
  companion object {
    const val TAG = "VisionCameraProxy"
  }

  @DoNotStrip
  @Keep
  private var mHybridData: HybridData?
  private var mContext: WeakReference<ReactApplicationContext>
  private var mScheduler: VisionCameraScheduler
  val context: ReactApplicationContext
    get() = reactContext

  init {
    // TODO: Fix for React Native 0.79+ - these APIs are now framework-only
    // Since Frame Processors are disabled anyway (react-native-worklets-core not found),
    // we'll disable this functionality to allow the build to complete
    Log.w(TAG, "Frame Processor initialization disabled due to React Native 0.79+ API compatibility issues")
    mScheduler = VisionCameraScheduler()
    mContext = WeakReference(context)
    // Disable Frame Processor functionality since APIs are not compatible
    mHybridData = null
    
    // Original code that fails with RN 0.79+:
    // val jsCallInvokerHolder = context.catalystInstance.jsCallInvokerHolder as CallInvokerHolderImpl
    // val jsRuntimeHolder = context.javaScriptContextHolder?.get() ?: throw Error("JSI Runtime is null!")
    // mHybridData = initHybrid(jsRuntimeHolder, jsCallInvokerHolder, mScheduler)
  }

  @UiThread
  private fun findCameraViewById(viewId: Int): CameraView {
    Log.d(TAG, "Finding view $viewId...")
    val ctx = mContext.get()
    val view = if (ctx != null) UIManagerHelper.getUIManager(ctx, viewId)?.resolveView(viewId) as CameraView? else null
    Log.d(TAG, if (view != null) "Found view $viewId!" else "Couldn't find view $viewId!")
    return view ?: throw ViewNotFoundError(viewId)
  }

  @DoNotStrip
  @Keep
  fun setFrameProcessor(viewId: Int, frameProcessor: FrameProcessor) {
    UiThreadUtil.runOnUiThread {
      val view = findCameraViewById(viewId)
      view.frameProcessor = frameProcessor
    }
  }

  @DoNotStrip
  @Keep
  fun removeFrameProcessor(viewId: Int) {
    UiThreadUtil.runOnUiThread {
      val view = findCameraViewById(viewId)
      view.frameProcessor = null
    }
  }

  @DoNotStrip
  @Keep
  fun initFrameProcessorPlugin(name: String, options: Map<String, Any>): FrameProcessorPlugin? =
    FrameProcessorPluginRegistry.getPlugin(name, this, options)

  // private C++ funcs
  // Frame Processors are disabled - native registration is skipped via VISION_CAMERA_ENABLE_FRAME_PROCESSORS=OFF
  // This method is never called or registered, kept for reference only
  // @DoNotStrip
  // @Keep
  // private external fun initHybrid(jsContext: Long, jsCallInvokerHolder: Any, scheduler: VisionCameraScheduler): HybridData
}
