package com.humand.demo

import android.app.KeyguardManager
import android.app.PictureInPictureParams
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.util.Rational
import android.view.WindowManager
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.humand.demo.modules.CallService.CallManager
import com.humand.demo.modules.CallService.RNCallManager
import com.humand.demo.modules.IncomingCallMessagingService.common.CallPayload
import com.humand.demo.modules.IncomingCallMessagingService.common.Constants
import com.humand.demo.modules.IncomingCallMessagingService.rn.RNNotificationBridge
import com.orientationdirector.implementation.ConfigurationChangedBroadcastReceiver
import com.zoontek.rnbootsplash.RNBootSplash
import expo.modules.ReactActivityDelegateWrapper
import androidx.lifecycle.Lifecycle
import android.view.KeyEvent
import android.webkit.WebView
import com.humand.demo.modules.VolumeButtonListener.VolumeButtonListenerModule

class MainActivity : ReactActivity() {
  override fun onStart() {
    super.onStart()
  }

  /**
   * Returns the name of the main component registered from JavaScript. This is used to schedule
   * rendering of the component.
   */
  override fun getMainComponentName(): String = "main"

  /**
   * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
   * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
   */
  override fun createReactActivityDelegate(): ReactActivityDelegate {
    return ReactActivityDelegateWrapper(
      this,
      BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
      object : DefaultReactActivityDelegate(
        this,
        mainComponentName,
        fabricEnabled
      ){})
  }

  override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    
    // Broadcast for react-native-orientation-director
    val orientationDirectorCustomAction = 
      "${packageName}.${ConfigurationChangedBroadcastReceiver.CUSTOM_INTENT_ACTION}"
    
    val orientationIntent = 
      Intent(orientationDirectorCustomAction).apply {
        putExtra("newConfig", newConfig)
        setPackage(packageName)
      }
    
    this.sendBroadcast(orientationIntent)
  }

  /**
   * Setup BootSplash package
   * To more info @see https://github.com/zoontek/react-native-bootsplash#android-1
   */
  override fun onCreate(savedInstanceState: Bundle?) {
    RNBootSplash.init(this, R.style.BootTheme) // Initialize splash screen BEFORE super.onCreate
    super.onCreate(null) // Pass null to prevent fragment state restoration issues

    // Disable remote debugging for release builds; newer WebView versions auto-enable it when the
    // application is debuggable.
    if (!BuildConfig.DEBUG) {
      WebView.setWebContentsDebuggingEnabled(false)
    }

    // Enable showing over lock screen when launched from accepting a call
    handleLockScreenForCall(intent)

    RNNotificationBridge.handleIncomingCallEvents(getReactInstance(),intent) // Handle call payload on cold start (app just launched)
    setupCallActivityIfNeeded(intent)
  }

  override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)

    // Enable showing over lock screen when launched from accepting a call
    handleLockScreenForCall(intent)

    RNNotificationBridge.handleIncomingCallEvents(getReactInstance(),intent) // Handle call payload when new intent is received (app already running)
    setupCallActivityIfNeeded(intent)
  }

  // Allow MainActivity to be shown on lock screen if it's opened from incoming call screen
  private fun setupCallActivityIfNeeded(intent: Intent) {

    val fromFullScreenCallActivity =
        intent.getBooleanExtra(Constants.OPENED_FROM_FULL_SCREEN_CALL_ACTIVITY, false)

    if (fromFullScreenCallActivity) {
        setShowWhenLocked(true)
        setTurnScreenOn(true)
    }
  }

  private fun getReactInstance(): ReactHost? {
    val app = applicationContext as? ReactApplication ?: return null
    return app.reactHost
  }

  /**
   * Enable showing over lock screen when launched from accepting a call.
   * This allows the app to display over the lock screen and dismiss the keyguard.
   */
  private fun handleLockScreenForCall(intent: Intent?) {
    if (intent == null) return

    val payload = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
      intent.getParcelableExtra(Constants.CALL_PAYLOAD, CallPayload::class.java)
    } else {
      @Suppress("DEPRECATION")
      intent.getParcelableExtra<CallPayload>(Constants.CALL_PAYLOAD)
    }

    // Only enable lock screen features when launched from a call
    if (payload != null) {
      setShowWhenLocked(true)
      setTurnScreenOn(true)
      window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

      // Dismiss the keyguard to allow user interaction
      val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
      keyguardManager.requestDismissKeyguard(this, null)
    }
  }

  /**
  * Align the back button behavior with Android S
  * where moving root activities to background instead of finishing activities.
  * @see <a href="https://developer.android.com/reference/android/app/Activity#onBackPressed()">onBackPressed</a>
  */
  override fun invokeDefaultOnBackPressed() {
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
      if (!moveTaskToBack(false)) {
        // For non-root activities, use the default implementation to finish them.
        super.invokeDefaultOnBackPressed()
      }
      return
    }

    // Use the default back button implementation on Android S
    // because it's doing more than [Activity.moveTaskToBack] in fact.
    super.invokeDefaultOnBackPressed()
  }

    override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode)

        RNCallManager.emitPipModeChanged(isInPictureInPictureMode)

        if (isFinishing) {
            return
        }
        if (lifecycle.currentState === Lifecycle.State.CREATED) {
            // when user clicks on Close button of PIP
            finishAndRemoveTask()
        }
    }
    override fun onUserLeaveHint() {
        super.onUserLeaveHint()
        enterPipModeIfCallActive()
    }

    private fun enterPipModeIfCallActive() {
        if (!CallManager.isPipEnabled) {
            return
        }

        val callManager = CallManager.getInstanceOrNull()
        if (callManager?.hasActiveCall() != true) {
            return
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val pipParams = PictureInPictureParams.Builder()
                .setAspectRatio(Rational(9, 16))
                .build()
            enterPictureInPictureMode(pipParams)
        }
    }

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        if (VolumeButtonListenerModule.handleKeyEvent(event.keyCode, event.action)) {
            return true
        }
        return super.dispatchKeyEvent(event)
    }
}
