package expo.modules.devmenu

import android.content.Context
import android.graphics.Rect
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.ViewCompat
import androidx.core.view.doOnLayout
import com.facebook.react.ReactRootView
import expo.modules.devmenu.fab.MovableFloatingActionButton

/**
 * We want to hide the FAB behind the feature flag for now.
 */
private const val enableFAB = false

class DevMenuReactRootViewContainer(context: Context) : FrameLayout(context) {
  private val updateSystemGestureExclusionRects: () -> Unit = {
    val marginLayoutParams = fab.layoutParams as MarginLayoutParams

    // Bounding box for the FAB, with margins included
    val rect = Rect(
      fab.x.toInt() - marginLayoutParams.leftMargin,
      fab.y.toInt() - marginLayoutParams.bottomMargin,
      fab.x.toInt() + fab.width + marginLayoutParams.rightMargin,
      fab.y.toInt() + fab.height + marginLayoutParams.topMargin
    )

    // For some reason, updating the system gesture exclusion rects has to be called on that view
    // instead of calling it on the fab view itself. Probably, because we want to extend the rect by view margins.
    ViewCompat.setSystemGestureExclusionRects(this, listOf(rect))
  }

  private val fab by lazy {
    MovableFloatingActionButton(context) {
      // `setSystemGestureExclusionRects` should be call after the view is laid out
      doOnLayout {
        updateSystemGestureExclusionRects()
      }
    }
  }

  override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)
    updateSystemGestureExclusionRects()
  }

  override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    DevMenuManager.onTouchEvent(ev)
    return super.dispatchTouchEvent(ev)
  }

  override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
    super.addView(child, index, params)
    if (enableFAB && child is ReactRootView) {
      addView(fab)
    }
  }
}
