package com.adealink.weparty.commonui.widget.slide.touch

import android.animation.ValueAnimator
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import com.adealink.weparty.commonui.widget.slide.Slide
import com.adealink.weparty.commonui.widget.slide.SlideBuilder
import com.adealink.weparty.commonui.widget.slide.SlideListener
import com.adealink.weparty.commonui.widget.slide.TAG_SLIDE_TOUCH_CONSUMER
import kotlin.math.abs

class SlideDownTouchConsumer(
    builder: SlideBuilder,
    notifier: SlideListener,
    private val slideLength: Float
) : AbsTouchConsumer(builder, notifier) {

    private val touchSlop = ViewConfiguration.get(mBuilder.mSliderView.context).scaledPagingTouchSlop
    private var mGoingUp = false
    private var mGoingDown = false
    private var mDragMove = false
    override val dir: Slide.SlideDirection = Slide.SlideDirection.DOWN

    override fun onSlide(touchedView: View?, event: MotionEvent): Boolean {
        Log.d(TAG_SLIDE_TOUCH_CONSUMER, "slideDown, touchedView: " + touchedView + ", event:" + event.actionMasked)
        try {
            when (event.actionMasked) {
                MotionEvent.ACTION_DOWN -> {
                    mStartPositionX = event.rawX
                    mStartPositionY = event.rawY
                    mDragMove = false
                    mViewStartPositionY = mBuilder.mSliderView.translationY
                    Log.d(TAG_SLIDE_TOUCH_CONSUMER, "slideDown(ACTION_DOWN) -> mViewStartPositionY:$mViewStartPositionY")
                    return true
                }

                MotionEvent.ACTION_MOVE -> {
                    val difference = event.rawY - mStartPositionY
                    val moveTo = mViewStartPositionY + difference
                    val percents = (abs(moveTo) * 100f / slideLength).coerceIn(0f, 100f)
                    calculateDirection(event)

                    Log.d(TAG_SLIDE_TOUCH_CONSUMER, "slideDown(ACTION_MOVE) -> difference: $difference")
                    Log.d(TAG_SLIDE_TOUCH_CONSUMER, "                          moveTo:$moveTo, slideLength:$slideLength, percent:$percents")
                    if (moveTo > 0) {
                        mDragMove = true
                        mNotifier.notifyPercentChanged(percents, Slide.SlideDirection.DOWN)
                        mBuilder.mSliderView.translationY = moveTo
                        return true
                    } else {
                        return false
                    }
                }

                MotionEvent.ACTION_UP -> {
                    if (!mDragMove && abs(mStartPositionX - event.rawX) < touchSlop && abs(mStartPositionY - event.rawY) < touchSlop) {
                        mNotifier.performClick(event)
                        return false
                    }
                    val difference = event.rawY - mStartPositionY
                    val moveTo = mViewStartPositionY + difference
                    val percents = (abs(moveTo) * 100f / slideLength).coerceIn(0f, 100f)

                    Log.d(TAG_SLIDE_TOUCH_CONSUMER, "slideDown(ACTION_UP) -> percents: $percents, mGoingDown: $mGoingDown, slideLength:$slideLength")
                    Log.d(TAG_SLIDE_TOUCH_CONSUMER, "                        mStartPositionX: $mStartPositionX, difference: $difference, moveTo: $moveTo")

                    if (percents > mBuilder.mAutoSlideToEndPercent && mGoingDown) {
                        mAnimationProcessor.setValuesAndStart(moveTo, slideLength, true)
                    } else {
                        mAnimationProcessor.setValuesAndStart(moveTo, 0f)
                    }
                    return true
                }
            }
        } finally {
            mPrevPositionY = event.rawY
            mPrevPositionX = event.rawX
        }
        return false
    }

    private fun calculateDirection(event: MotionEvent) {
        if (abs(event.rawY - mPrevPositionY) < touchSlop) {
            return
        }
        mGoingUp = mPrevPositionY - event.rawY > 0
        mGoingDown = mPrevPositionY - event.rawY < 0
    }

    override fun onAnimationUpdate(animation: ValueAnimator) {
        val translationY = animation.animatedValue as Float
        mBuilder.mSliderView.translationY = translationY
        Log.d(TAG_SLIDE_TOUCH_CONSUMER, "SlideDown(onAnimationUpdate) ===> translationY = $translationY")

        //通知变化
        val percents = (abs(translationY) * 100f / slideLength).coerceIn(0f, 100f)
        mNotifier.notifyPercentChanged(percents, Slide.SlideDirection.DOWN)
    }
}
