/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.systemui.navigationbar.gestural

import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Point
import android.os.Handler
import android.os.SystemClock
import android.os.VibrationEffect
import android.util.Log
import android.util.MathUtils.constrain
import android.util.MathUtils.saturate
import android.view.Gravity
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
import android.view.WindowManager
import android.view.animation.DecelerateInterpolator
import android.view.animation.PathInterpolator
import android.window.BackEvent
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.NavigationEdgeBackPlugin
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.ViewController
import com.android.wm.shell.back.BackAnimation
import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sign

private const val TAG = "BackPanelController"
private const val DEBUG = false

private const val ENABLE_FAILSAFE = true

private const val FAILSAFE_DELAY_MS: Long = 350

/**
 * The time required between the arrow-appears vibration effect and the back-committed vibration
 * effect. If the arrow is flung quickly, the phone only vibrates once. However, if the arrow is
 * held on the screen for a long time, it will vibrate a second time when the back gesture is
 * committed.
 */
private const val GESTURE_DURATION_FOR_CLICK_MS = 400

/**
 * The min duration arrow remains on screen during a fling event.
 */
private const val FLING_MIN_APPEARANCE_DURATION = 235L

/**
 * The min duration arrow remains on screen during a fling event.
 */
private const val MIN_FLING_VELOCITY = 3000

/**
 * The amount of rubber banding we do for the vertical translation
 */
private const val RUBBER_BAND_AMOUNT = 15

private const val ARROW_APPEAR_STIFFNESS = 600f
private const val ARROW_APPEAR_DAMPING_RATIO = 0.4f
private const val ARROW_DISAPPEAR_STIFFNESS = 1200f
private const val ARROW_DISAPPEAR_DAMPING_RATIO = SpringForce.DAMPING_RATIO_NO_BOUNCY

/**
 * The interpolator used to rubber band
 */
private val RUBBER_BAND_INTERPOLATOR = PathInterpolator(1.0f / 5.0f, 1.0f, 1.0f, 1.0f)

private val DECELERATE_INTERPOLATOR = DecelerateInterpolator()

private val DECELERATE_INTERPOLATOR_SLOW = DecelerateInterpolator(0.7f)

class BackPanelController private constructor(
    context: Context,
    private var backAnimation: BackAnimation?,
    private val windowManager: WindowManager,
    @Main private val mainHandler: Handler,
    private val vibratorHelper: VibratorHelper,
    private val configurationController: ConfigurationController,
    latencyTracker: LatencyTracker
) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin {

    /**
     * Injectable instance to create a new BackPanelController.
     *
     * Necessary because EdgeBackGestureHandler sometimes needs to create new instances of
     * BackPanelController, and we need to match EdgeBackGestureHandler's context.
     */
    class Factory @Inject constructor(
        private val windowManager: WindowManager,
        @Main private val mainHandler: Handler,
        private val vibratorHelper: VibratorHelper,
        private val configurationController: ConfigurationController,
        private val latencyTracker: LatencyTracker
    ) {
        /** Construct a [BackPanelController].  */
        fun create(context: Context, backAnimation: BackAnimation?): BackPanelController {
            val backPanelController = BackPanelController(
                context,
                backAnimation,
                windowManager,
                mainHandler,
                vibratorHelper,
                configurationController,
                latencyTracker
            )
            backPanelController.init()
            return backPanelController
        }
    }

    private var params: EdgePanelParams = EdgePanelParams(resources)
    private var currentState: GestureState = GestureState.GONE
    private var previousState: GestureState = GestureState.GONE

    // Phone should only vibrate the first time the arrow is activated
    private var hasHapticPlayed = false

    // Screen attributes
    private lateinit var layoutParams: WindowManager.LayoutParams
    private val displaySize = Point()

    private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback

    private var previousXTranslation = 0f
    private var totalTouchDelta = 0f
    private var velocityTracker: VelocityTracker? = null
        set(value) {
            if (field != value) field?.recycle()
            field = value
        }
        get() {
            if (field == null) field = VelocityTracker.obtain()
            return field
        }

    // The x,y position of the first touch event
    private var startX = 0f
    private var startY = 0f

    private var gestureStartTime = 0L

    private val failsafeRunnable = Runnable { onFailsafe() }

    private enum class GestureState {
        /* Arrow is off the screen and invisible */
        GONE,

        /* Arrow is animating in */
        ENTRY,

        /* could be entry, neutral, or stretched, releasing will commit back */
        ACTIVE,

        /* releasing will cancel back */
        INACTIVE,

        /* like committed, but animation takes longer */
        FLUNG,

        /* back action currently occurring, arrow soon to be GONE */
        COMMITTED,

        /* back action currently cancelling, arrow soon to be GONE */
        CANCELLED;

        /**
         * @return true if the current state responds to touch move events in some way (e.g. by
         * stretching the back indicator)
         */
        fun isInteractive(): Boolean {
            return when (this) {
                ENTRY, ACTIVE, INACTIVE -> true
                GONE, FLUNG, COMMITTED, CANCELLED -> false
            }
        }
    }

    /**
     * Wrapper around OnAnimationEndListener which runs the given runnable after a delay. The
     * runnable is not called if the animation is cancelled
     */
    inner class DelayedOnAnimationEndListener internal constructor(
        private val handler: Handler,
        private val runnable: Runnable,
        private val minDuration: Long
    ) : DynamicAnimation.OnAnimationEndListener {
        override fun onAnimationEnd(
            animation: DynamicAnimation<*>,
            canceled: Boolean,
            value: Float,
            velocity: Float
        ) {
            animation.removeEndListener(this)
            if (!canceled) {
                // Total elapsed time of the gesture and the animation
                val totalElapsedTime = SystemClock.uptimeMillis() - gestureStartTime
                // The delay between finishing this animation and starting the runnable
                val delay = max(0, minDuration - totalElapsedTime)
                handler.postDelayed(runnable, delay)
            }
        }

        internal fun runNow() {
            runnable.run()
        }
    }

    private val setCommittedEndListener =
        DelayedOnAnimationEndListener(
            mainHandler,
            { updateArrowState(GestureState.COMMITTED) },
            minDuration = FLING_MIN_APPEARANCE_DURATION
        )

    private val setGoneEndListener =
        DelayedOnAnimationEndListener(
            mainHandler,
            {
                cancelFailsafe()
                updateArrowState(GestureState.GONE)
            },
            minDuration = 0
        )

    // Vibration
    private var vibrationTime: Long = 0

    // Minimum of the screen's width or the predefined threshold
    private var fullyStretchedThreshold = 0f

    /**
     * Used for initialization and configuration changes
     */
    private fun updateConfiguration() {
        params.update(resources)
        updateBackAnimationSwipeThresholds()
        mView.updateArrowPaint(params.arrowThickness)
    }

    private val configurationListener = object : ConfigurationController.ConfigurationListener {
        override fun onConfigChanged(newConfig: Configuration?) {
            updateConfiguration()
        }

        override fun onLayoutDirectionChanged(isLayoutRtl: Boolean) {
            updateArrowDirection(isLayoutRtl)
        }
    }

    override fun onViewAttached() {
        updateConfiguration()
        updateArrowDirection(configurationController.isLayoutRtl)
        updateArrowState(GestureState.GONE, force = true)
        updateRestingArrowDimens(animated = false, currentState)
        configurationController.addCallback(configurationListener)
    }

    /** Update the arrow direction. The arrow should point the same way for both panels. */
    private fun updateArrowDirection(isLayoutRtl: Boolean) {
        mView.arrowsPointLeft = isLayoutRtl
    }

    override fun onViewDetached() {
        configurationController.removeCallback(configurationListener)
    }

    override fun onMotionEvent(event: MotionEvent) {
        backAnimation?.onBackMotion(
            event.x,
            event.y,
            event.actionMasked,
            if (mView.isLeftPanel) BackEvent.EDGE_LEFT else BackEvent.EDGE_RIGHT
        )

        velocityTracker!!.addMovement(event)
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                resetOnDown()
                startX = event.x
                startY = event.y
                gestureStartTime = SystemClock.uptimeMillis()

                // Reset the arrow to the side
                updateArrowState(GestureState.ENTRY)

                windowManager.updateViewLayout(mView, layoutParams)
                mView.startTrackingShowBackArrowLatency()
            }
            MotionEvent.ACTION_MOVE -> handleMoveEvent(event)
            MotionEvent.ACTION_UP -> {
                if (currentState == GestureState.ACTIVE) {
                    updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED)
                } else {
                    updateArrowState(GestureState.CANCELLED)
                }
                velocityTracker = null
            }
            MotionEvent.ACTION_CANCEL -> {
                updateArrowState(GestureState.CANCELLED)
                velocityTracker = null
            }
        }
    }

    private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
        if (!currentState.isInteractive())
            return

        when (currentState) {
            // Check if we should transition from ENTRY to ACTIVE
            GestureState.ENTRY ->
                if (xTranslation > params.swipeTriggerThreshold) {
                    updateArrowState(GestureState.ACTIVE)
                }

            // Abort if we had continuous motion toward the edge for a while, OR the direction
            // in Y is bigger than X * 2
            GestureState.ACTIVE ->
                if ((totalTouchDelta < 0 && -totalTouchDelta > params.minDeltaForSwitch) ||
                    (yTranslation > xTranslation * 2)
                ) {
                    updateArrowState(GestureState.INACTIVE)
                }

            //  Re-activate if we had continuous motion away from the edge for a while
            GestureState.INACTIVE ->
                if (totalTouchDelta > 0 && totalTouchDelta > params.minDeltaForSwitch) {
                    updateArrowState(GestureState.ACTIVE)
                }

            // By default assume the current direction is kept
            else -> {}
        }
    }

    private fun handleMoveEvent(event: MotionEvent) {
        if (!currentState.isInteractive())
            return

        val x = event.x
        val y = event.y

        val yOffset = y - startY

        // How far in the y direction we are from the original touch
        val yTranslation = abs(yOffset)

        // How far in the x direction we are from the original touch ignoring motion that
        // occurs between the screen edge and the touch start.
        val xTranslation = max(0f, if (mView.isLeftPanel) x - startX else startX - x)

        // Compared to last time, how far we moved in the x direction. If <0, we are moving closer
        // to the edge. If >0, we are moving further from the edge
        val xDelta = xTranslation - previousXTranslation
        previousXTranslation = xTranslation

        if (abs(xDelta) > 0) {
            if (sign(xDelta) == sign(totalTouchDelta)) {
                // Direction has NOT changed, so keep counting the delta
                totalTouchDelta += xDelta
            } else {
                // Direction has changed, so reset the delta
                totalTouchDelta = xDelta
            }
        }

        updateArrowStateOnMove(yTranslation, xTranslation)
        when (currentState) {
            GestureState.ACTIVE ->
                stretchActiveBackIndicator(fullScreenStretchProgress(xTranslation))
            GestureState.ENTRY ->
                stretchEntryBackIndicator(preThresholdStretchProgress(xTranslation))
            GestureState.INACTIVE ->
                mView.resetStretch()
        }

        // set y translation
        setVerticalTranslation(yOffset)
    }

    private fun setVerticalTranslation(yOffset: Float) {
        val yTranslation = abs(yOffset)
        val maxYOffset = (mView.height - params.entryIndicator.backgroundDimens.height) / 2f
        val yProgress = saturate(yTranslation / (maxYOffset * RUBBER_BAND_AMOUNT))
        mView.animateVertically(
            RUBBER_BAND_INTERPOLATOR.getInterpolation(yProgress) * maxYOffset *
                sign(yOffset)
        )
    }

    /**
     * @return the relative position of the drag from the time after the arrow is activated until
     * the arrow is fully stretched (between 0.0 - 1.0f)
     */
    private fun fullScreenStretchProgress(xTranslation: Float): Float {
        return saturate(
            (xTranslation - params.swipeTriggerThreshold) /
                (fullyStretchedThreshold - params.swipeTriggerThreshold)
        )
    }

    /**
     * Tracks the relative position of the drag from the entry until the threshold where the arrow
     * activates (between 0.0 - 1.0f)
     */
    private fun preThresholdStretchProgress(xTranslation: Float): Float {
        return saturate(xTranslation / params.swipeTriggerThreshold)
    }

    private fun stretchActiveBackIndicator(progress: Float) {
        val rubberBandIterpolation = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
        mView.setStretch(
            horizontalTranslationStretchAmount = rubberBandIterpolation,
            arrowStretchAmount = rubberBandIterpolation,
            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR_SLOW.getInterpolation(progress),
            params.fullyStretchedIndicator
        )
    }

    private fun stretchEntryBackIndicator(progress: Float) {
        mView.setStretch(
            horizontalTranslationStretchAmount = 0f,
            arrowStretchAmount = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress),
            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR.getInterpolation(progress),
            params.preThresholdIndicator
        )
    }

    fun setBackAnimation(backAnimation: BackAnimation?) {
        this.backAnimation = backAnimation
        updateBackAnimationSwipeThresholds()
    }

    private fun updateBackAnimationSwipeThresholds() {
        backAnimation?.setSwipeThresholds(
            params.swipeTriggerThreshold,
            fullyStretchedThreshold
        )
    }

    override fun onDestroy() {
        cancelFailsafe()
        windowManager.removeView(mView)
    }

    override fun setIsLeftPanel(isLeftPanel: Boolean) {
        mView.isLeftPanel = isLeftPanel
        layoutParams.gravity = if (isLeftPanel) {
            Gravity.LEFT or Gravity.TOP
        } else {
            Gravity.RIGHT or Gravity.TOP
        }
    }

    override fun setInsets(insetLeft: Int, insetRight: Int) {
    }

    override fun setBackCallback(callback: NavigationEdgeBackPlugin.BackCallback) {
        backCallback = callback
    }

    override fun setLayoutParams(layoutParams: WindowManager.LayoutParams) {
        this.layoutParams = layoutParams
        windowManager.addView(mView, layoutParams)
    }

    private fun isFlung() = velocityTracker!!.run {
        computeCurrentVelocity(1000)
        abs(xVelocity) > MIN_FLING_VELOCITY
    }

    private fun playFlingBackAnimation() {
        playAnimation(setCommittedEndListener)
    }

    private fun playCommitBackAnimation() {
        // Check if we should vibrate again
        if (previousState != GestureState.FLUNG) {
            backCallback.triggerBack()
            velocityTracker!!.computeCurrentVelocity(1000)
            val isSlow = abs(velocityTracker!!.xVelocity) < 500
            val hasNotVibratedRecently =
                SystemClock.uptimeMillis() - vibrationTime >= GESTURE_DURATION_FOR_CLICK_MS
            if (isSlow || hasNotVibratedRecently) {
                vibratorHelper.vibrate(VibrationEffect.EFFECT_CLICK)
            }
        }
        playAnimation(setGoneEndListener)
    }

    private fun playCancelBackAnimation() {
        backCallback.cancelBack()
        playAnimation(setGoneEndListener)
    }

    /**
     * @return true if the animation is running, false otherwise. Some transitions don't animate
     */
    private fun playAnimation(endListener: DelayedOnAnimationEndListener) {
        updateRestingArrowDimens(animated = true, currentState)

        if (!mView.addEndListener(endListener)) {
            scheduleFailsafe()
        }
    }

    private fun resetOnDown() {
        hasHapticPlayed = false
        totalTouchDelta = 0f
        vibrationTime = 0
        cancelFailsafe()
        backAnimation?.setTriggerBack(false)
    }

    private fun updateYPosition(touchY: Float) {
        var yPosition = touchY - params.fingerOffset
        yPosition = max(yPosition, params.minArrowYPosition.toFloat())
        yPosition -= layoutParams.height / 2.0f
        layoutParams.y = constrain(yPosition.toInt(), 0, displaySize.y)
    }

    override fun setDisplaySize(displaySize: Point) {
        this.displaySize.set(displaySize.x, displaySize.y)
        fullyStretchedThreshold = min(displaySize.x.toFloat(), params.swipeProgressThreshold)
        updateBackAnimationSwipeThresholds()
    }

    /**
     * Updates resting arrow and background size not accounting for stretch
     */
    private fun updateRestingArrowDimens(animated: Boolean, currentState: GestureState) {
        if (animated) {
            when (currentState) {
                GestureState.ENTRY, GestureState.ACTIVE, GestureState.FLUNG ->
                    mView.setArrowStiffness(ARROW_APPEAR_STIFFNESS, ARROW_APPEAR_DAMPING_RATIO)
                GestureState.CANCELLED -> mView.fadeOut()
                else ->
                    mView.setArrowStiffness(
                        ARROW_DISAPPEAR_STIFFNESS,
                        ARROW_DISAPPEAR_DAMPING_RATIO
                    )
            }
        }
        mView.setRestingDimens(
            restingParams = EdgePanelParams.BackIndicatorDimens(
                horizontalTranslation = when (currentState) {
                    GestureState.GONE -> -params.activeIndicator.backgroundDimens.width
                    // Position the committed arrow slightly further off the screen so we  do not
                    // see part of it bouncing
                    GestureState.COMMITTED ->
                        -params.activeIndicator.backgroundDimens.width * 1.5f
                    GestureState.FLUNG -> params.fullyStretchedIndicator.horizontalTranslation
                    GestureState.ACTIVE -> params.activeIndicator.horizontalTranslation
                    GestureState.ENTRY, GestureState.INACTIVE, GestureState.CANCELLED ->
                        params.entryIndicator.horizontalTranslation
                },
                arrowDimens = when (currentState) {
                    GestureState.ACTIVE, GestureState.INACTIVE,
                    GestureState.COMMITTED, GestureState.FLUNG -> params.activeIndicator.arrowDimens
                    GestureState.CANCELLED -> params.cancelledArrowDimens
                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.arrowDimens
                },
                backgroundDimens = when (currentState) {
                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.backgroundDimens
                    else ->
                        params.activeIndicator.backgroundDimens.copy(
                            edgeCornerRadius =
                            if (currentState == GestureState.INACTIVE ||
                                currentState == GestureState.CANCELLED
                            )
                                params.entryIndicator.backgroundDimens.edgeCornerRadius
                            else
                                params.activeIndicator.backgroundDimens.edgeCornerRadius
                        )
                }
            ),
            animate = animated
        )
    }

    /**
     * Update arrow state. If state has not changed, this is a no-op.
     *
     * Transitioning to active/inactive will indicate whether or not releasing touch will trigger
     * the back action.
     */
    private fun updateArrowState(newState: GestureState, force: Boolean = false) {
        if (!force && currentState == newState) return

        if (DEBUG) Log.d(TAG, "updateArrowState $currentState -> $newState")
        previousState = currentState
        currentState = newState
        if (currentState == GestureState.GONE) {
            mView.cancelAlphaAnimations()
            mView.visibility = View.GONE
        } else {
            mView.visibility = View.VISIBLE
        }

        when (currentState) {
            // Transitioning to GONE never animates since the arrow is (presumably) already off the
            // screen
            GestureState.GONE -> updateRestingArrowDimens(animated = false, currentState)
            GestureState.ENTRY -> {
                updateYPosition(startY)
                updateRestingArrowDimens(animated = true, currentState)
            }
            GestureState.ACTIVE -> {
                backAnimation?.setTriggerBack(true)
                updateRestingArrowDimens(animated = true, currentState)
                // Vibrate the first time we transition to ACTIVE
                if (!hasHapticPlayed) {
                    hasHapticPlayed = true
                    vibrationTime = SystemClock.uptimeMillis()
                    vibratorHelper.vibrate(VibrationEffect.EFFECT_TICK)
                }
            }
            GestureState.INACTIVE -> {
                backAnimation?.setTriggerBack(false)
                updateRestingArrowDimens(animated = true, currentState)
            }
            GestureState.FLUNG -> playFlingBackAnimation()
            GestureState.COMMITTED -> playCommitBackAnimation()
            GestureState.CANCELLED -> playCancelBackAnimation()
        }
    }

    private fun scheduleFailsafe() {
        if (!ENABLE_FAILSAFE) return
        cancelFailsafe()
        if (DEBUG) Log.d(TAG, "scheduleFailsafe")
        mainHandler.postDelayed(failsafeRunnable, FAILSAFE_DELAY_MS)
    }

    private fun cancelFailsafe() {
        if (DEBUG) Log.d(TAG, "cancelFailsafe")
        mainHandler.removeCallbacks(failsafeRunnable)
    }

    private fun onFailsafe() {
        if (DEBUG) Log.d(TAG, "onFailsafe")
        updateArrowState(GestureState.GONE, force = true)
    }

    override fun dump(pw: PrintWriter) {
        pw.println("$TAG:")
        pw.println("  currentState=$currentState")
        pw.println("  isLeftPanel=$mView.isLeftPanel")
    }

    init {
        if (DEBUG) mView.drawDebugInfo = { canvas ->
            val debugStrings = listOf(
                "$currentState",
                "startX=$startX",
                "startY=$startY",
                "xDelta=${"%.1f".format(totalTouchDelta)}",
                "xTranslation=${"%.1f".format(previousXTranslation)}",
                "pre=${"%.0f".format(preThresholdStretchProgress(previousXTranslation) * 100)}%",
                "post=${"%.0f".format(fullScreenStretchProgress(previousXTranslation) * 100)}%"
            )
            val debugPaint = Paint().apply {
                color = Color.WHITE
            }
            val debugInfoBottom = debugStrings.size * 32f + 4f
            canvas.drawRect(
                4f,
                4f,
                canvas.width.toFloat(),
                debugStrings.size * 32f + 4f,
                debugPaint
            )
            debugPaint.apply {
                color = Color.BLACK
                textSize = 32f
            }
            var offset = 32f
            for (debugText in debugStrings) {
                canvas.drawText(debugText, 10f, offset, debugPaint)
                offset += 32f
            }
            debugPaint.apply {
                color = Color.RED
                style = Paint.Style.STROKE
                strokeWidth = 4f
            }
            val canvasWidth = canvas.width.toFloat()
            val canvasHeight = canvas.height.toFloat()
            canvas.drawRect(0f, 0f, canvasWidth, canvasHeight, debugPaint)

            fun drawVerticalLine(x: Float, color: Int) {
                debugPaint.color = color
                val x = if (mView.isLeftPanel) x else canvasWidth - x
                canvas.drawLine(x, debugInfoBottom, x, canvas.height.toFloat(), debugPaint)
            }

            drawVerticalLine(x = params.swipeTriggerThreshold, color = Color.BLUE)
            drawVerticalLine(x = startX, color = Color.GREEN)
            drawVerticalLine(x = previousXTranslation, color = Color.DKGRAY)
        }
    }
}
