package com.adealink.weparty.commonui.widget.floatview.view

import android.animation.LayoutTransition
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.content.Context
import android.util.AttributeSet
import android.util.SparseIntArray
import android.view.View
import androidx.annotation.IdRes
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.util.isEmpty
import androidx.core.view.children
import androidx.core.view.contains
import com.adealink.frame.aab.util.getCompatDimension
import com.adealink.frame.log.Log
import com.adealink.weparty.BuildConfig
import com.adealink.weparty.commonui.layout.DynamicLayerIndexNotFoundError
import com.adealink.weparty.commonui.widget.floatview.data.FloatWindowType
import com.adealink.weparty.commonui.widget.floatview.data.TAG_FLOAT_LAYOUT_VIEW
import com.adealink.weparty.R as APP_R

class FloatLinearLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayoutCompat(context, attrs, defStyleAttr),
    IFloatViewGroup<BaseLayoutFloatView> {

    private val layersDefine: IntArray = intArrayOf(
        APP_R.id.id_float_incoming_view, //1v1来电呼叫置顶
        APP_R.id.id_float_message_view
    )

    private val layerViewIndexSA = SparseIntArray()

    /**
     * 获取视图定义层级(通过映射提升检索效率)
     */
    private fun getLayerViewIndex(@IdRes id: Int): Int {
        if (layersDefine.isEmpty()) {
            return -1
        }
        if (layerViewIndexSA.isEmpty()) {
            layersDefine.forEachIndexed { index, value ->
                layerViewIndexSA.put(value, index)
            }
        }

        return layerViewIndexSA.get(id, -1)
    }

    private val transition = LayoutTransition().apply {
        setDuration(300)
        // 自定义各种动画
        setAnimator(
            LayoutTransition.APPEARING,
            ObjectAnimator.ofPropertyValuesHolder(
                this,
                PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -getCompatDimension(APP_R.dimen.top_float_view_height), 0f),
                PropertyValuesHolder.ofFloat(View.ALPHA, 0.5f, 1f)
            )
        )
        setAnimator(
            LayoutTransition.DISAPPEARING,
            ObjectAnimator.ofFloat(null, View.ALPHA, 1f, 0f)
        )
    }

    fun clearLayoutTransition() {
        layoutTransition = null
    }

    fun reApplyLayoutTransition() {
        layoutTransition = transition
    }

    private fun getViewIndex(@IdRes id: Int): Int {
        if (id == NO_ID) {
            return 0
        }
        val defineIndex = getLayerViewIndex(id)
        if (defineIndex == -1) {
            if (BuildConfig.DEBUG) {
                throw DynamicLayerIndexNotFoundError(context.resources.getResourceName(id))
            }
        }

        //往靠近自己的两头开始找
        var targetView: View? = null
        var targetIndex = -1
        var up = 1
        var down = 1
        var upBaseIndex = -1
        var downBaseIndex = -1
        while (!(defineIndex - up < 0 && defineIndex + down >= layersDefine.size)) {
            if (defineIndex - up >= 0) {
                targetView = findViewById(layersDefine[defineIndex - up])
                if (targetView != null) {
                    targetIndex = indexOfChild(targetView)
                    upBaseIndex = targetIndex
                    break
                }
                up++
            }
            if (defineIndex + down < layersDefine.size) {
                targetView = findViewById(layersDefine[defineIndex + down])
                if (targetView != null) {
                    targetIndex = indexOfChild(targetView)
                    downBaseIndex = targetIndex
                    break
                }
                down++
            }
        }

        return when {
            upBaseIndex != -1 -> {
                upBaseIndex + 1
            }

            downBaseIndex != -1 -> {
                downBaseIndex
            }

            else -> {
                0
            }
        }
    }

    override fun viewGroup(): FloatLinearLayout {
        return this
    }

    override fun onResume(layoutDirection: Int) {
        Log.d(TAG_FLOAT_LAYOUT_VIEW, "onResume")
        this.layoutDirection = layoutDirection
        reApplyLayoutTransition()
    }

    override fun onPause() {
        Log.d(TAG_FLOAT_LAYOUT_VIEW, "onPause")
        clearLayoutTransition()
    }

    override fun containsView(view: BaseLayoutFloatView): Boolean {
        return contains(view)
    }

    override fun removeFloatView(view: BaseLayoutFloatView) {
        Log.d(TAG_FLOAT_LAYOUT_VIEW, "removeFloatView, $view")
        removeView(view)
    }

    override fun onViewRemoved(child: View?) {
        Log.d(TAG_FLOAT_LAYOUT_VIEW, "onViewRemoved, $child")
    }

    override fun addFloatView(view: BaseLayoutFloatView) {
        val index = getViewIndex(view.id)
        Log.d(TAG_FLOAT_LAYOUT_VIEW, "addFloatView(index:$index) $view")
        //兼容切语言后依赖appContext的layoutDirection不更新问题
        view.layoutDirection = LAYOUT_DIRECTION_LOCALE
        addView(view, index, view.layoutParams)
    }

    override fun findFloatViewByType(type: FloatWindowType): BaseLayoutFloatView? {
        return children.find { it is BaseLayoutFloatView && it.baseFloatData.windowType() == type } as? BaseLayoutFloatView
    }
}