package com.gh.gamecenter.feature.selector.widget

import android.content.Context
import android.graphics.RectF
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.ImageView
import com.gh.gamecenter.common.view.DragListener
import com.gh.gamecenter.common.view.IDraggable
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt

import com.gh.gamecenter.selector.R

class DraggablePreviewVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    PreviewVideoView(context, attrs), IDraggable, IDeselect {

    private var initScale: Float? = null
    private val scaledTouchSlop by lazy { ViewConfiguration.get(context).scaledTouchSlop }
    private val dismissEdge by lazy { height * 0.12 }
    private var singleTouch = true
    private var fakeDragOffset = 0F
    private var lastX = 0F
    private var lastY = 0F
    private var dragListener: DragListener? = null

    private var clickListener: OnClickListener? = null

    override fun setDragListener(listener: DragListener) {
        dragListener = listener
    }

    override fun onPageDeselected() {
        release()
    }

    override fun updateStartImage() {
        if (mStartButton is ImageView) {
            val imageView = mStartButton as ImageView
            when (mCurrentState) {
                CURRENT_STATE_PLAYING -> imageView.visibility = GONE
                else -> {
                    imageView.visibility = VISIBLE
                    imageView.setImageResource(com.gh.gamecenter.feature.R.drawable.icon_preview_video_play)
                }
            }
        }
    }

    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        when (event.actionMasked) {
            MotionEvent.ACTION_POINTER_DOWN -> {
                setSingleTouch(false)
                animate()
                    .translationX(0F).translationY(0F).scaleX(1F).scaleY(1F)
                    .setDuration(200).start()
            }
            MotionEvent.ACTION_DOWN -> if (initScale == null || initScale == 0F) initScale = 1F
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> up()
            MotionEvent.ACTION_MOVE -> {
                val rectF = RectF()
                if (singleTouch && initScale != 0F && (rectF.top == 0f || rectF.bottom == 0f)) {
                    if (lastX == 0F) lastX = event.rawX
                    if (lastY == 0F) lastY = event.rawY
                    val offsetX = event.rawX - lastX
                    val offsetY = event.rawY - lastY
                    fakeDrag(offsetX, offsetY)
                }
            }
        }
        return super.dispatchTouchEvent(event)
    }

    private fun fakeDrag(offsetX: Float, offsetY: Float) {
        if (fakeDragOffset == 0F) {
            // 大于60度才响应下拉消失
            if (abs(offsetY) / sqrt(3F) > abs(offsetX)) {
                if (offsetY > scaledTouchSlop) {
                    fakeDragOffset = scaledTouchSlop.toFloat()
                } else if (offsetY < -scaledTouchSlop) {
                    fakeDragOffset = (-scaledTouchSlop).toFloat()
                }
            }
        }
        if (fakeDragOffset != 0F) {
            val fixedOffsetY = offsetY - fakeDragOffset
            parent?.requestDisallowInterceptTouchEvent(true)
            val fraction = abs(max(-1F, min(1F, fixedOffsetY / height)))
            val fakeScale = 1 - min(0.4F, fraction)
            scaleX = fakeScale
            scaleY = fakeScale
            translationY = fixedOffsetY
            translationX = offsetX / 2
            dragListener?.onDrag(fraction)
        }
    }

    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        return false
    }

    fun setAlOnClickListener(listener: OnClickListener?) {
        clickListener = listener
    }

    override fun onClick(v: View?) {
        val i = v?.id
        if (i == R.id.start) {
            clickStartIcon()
        } else {
            if (translationY == 0F) {
                clickListener?.onClick(this)
            }
        }
    }

    private fun up() {
        parent?.requestDisallowInterceptTouchEvent(false)
        setSingleTouch(true)
        fakeDragOffset = 0F
        lastX = 0F
        lastY = 0F

        if (abs(translationY) > dismissEdge) {
            dragListener?.onRelease(scaleX)
        } else {
            val offsetY = translationY
            if (offsetY == 0F) return

            val fraction = min(1F, offsetY / height)
            dragListener?.onRestore(fraction)

            animate().translationX(0F)
                .translationY(0F)
                .scaleX(1F)
                .scaleY(1F)
                .setDuration(200).start()
        }
    }

    private fun setSingleTouch(value: Boolean) {
        singleTouch = value
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animate().cancel()
    }

}

interface IDeselect {
    fun onPageDeselected()
}