package com.yidianling.home.ui.view

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Handler
import android.os.Message
import android.util.AttributeSet
import android.util.Log
import android.widget.ImageView
import android.widget.RelativeLayout
import com.blankj.utilcode.util.SizeUtils
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.home.R
import com.yidianling.home.ui.transform.CircleCropTransform
import java.lang.ref.WeakReference

const val START_AVATAR_LOOP = 111

class LoopScrollAvatar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {

    //动画播放时长
    private val animDuration = 500L

    //动画间隔播放时间
    private val animIntervalTime = 1500L

    //两边头像的缩放程度
    private val scaleFrom = 0.7F

    //头像大小
    private val avatarSize = SizeUtils.dp2px(18F)

    //从当前位置滚动到下一位置需要移动的距离
    private var scrollLength = 0F

    //下次要显示的图片角标
    private var index = 0

    private val res =
        arrayOf(
            R.mipmap.home_banner_header1,
            R.mipmap.home_banner_header2,
            R.mipmap.home_banner_header3,
            R.mipmap.home_banner_header4,
            R.mipmap.home_banner_header5
        )

    //缓存复用ImageView
    private val ivCache = mutableListOf(
        createImageView(),
        createImageView(),
        createImageView(),
        createImageView()
    )
    private val handler by lazy {
        LoopHandler(this)
    }

    init {
        //前三位的头像先addView显示出来
        //放左边
        addImageView(ALIGN_PARENT_LEFT)
        //放中间
        addImageView(CENTER_HORIZONTAL)
        //默认放右边
        addImageView()
    }

    class LoopHandler() : Handler() {
        private var lWeak: WeakReference<LoopScrollAvatar>? = null

        constructor(loopScrollAvatar: LoopScrollAvatar) : this() {
            lWeak = WeakReference(loopScrollAvatar)
        }

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)

            lWeak?.get()?.apply {
                if ((context as? Activity)?.isDestroyed == false) {
                    startAnimMove()
                    sendLoopMsg()
                }
            }
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        scrollLength = (width - avatarSize) / 2F
    }

    /**
     * 创建圆形头像ImageView
     */
    private fun createImageView(): ImageView {
        return ImageView(context)
    }

    /**
     * 摆放头像ImageView
     */
    private fun addImageView(rule: Int = ALIGN_PARENT_RIGHT) {
        //复用缓存
        val iv = if (ivCache.size > 0) {
            ivCache[0]
        } else {
            createImageView()
        }
        //当前已在屏幕显示的控件不要复用，防止params混乱
        ivCache.remove(iv)

        //图片资源全部播放完之后要从头重播
        index = (index + 1) % res.size

        //设置在RelativeLayout中的显示位置
        val lp = LayoutParams(avatarSize, avatarSize)
        lp.addRule(rule)
        iv.layoutParams = lp

        addView(iv)
        //圆角带描边
        GlideApp.with(this).load(res[index]).transform(CircleCropTransform(1f, Color.WHITE))
            .into(iv)
    }

    /**
     * 轮播滚动动效
     */
    private fun startAnimMove() {
        //添加一个即将从右边移进屏幕的ImageView
        addImageView()
        //上行代码刚添加进来的最右边头像（此时RelativeLayout的mChildrenCount=4）
        getChildAt(3)?.apply {
            //设置起始的低透明度 和 小size
            alpha = 0.6F
            scaleX = scaleFrom
            scaleY = scaleFrom
            //先设置左边部分向左移出控件，即挡住左边不显示（然后才能translationXBy移进屏幕）
            translationX = scrollLength

            //translationXBy指的是从当前位置开始移动多少距离（区别于translationX）
            //alpha是从当前透明度（即0.6F）变为设置的透明度（即1F）
            //scaleX是从当前宽度比例（即scaleFrom）变为设置的宽度比例（即1F）
            animate().translationXBy(-scrollLength).alpha(1F).scaleX(1F).scaleY(1F)
                .setDuration(animDuration).start()
        }
        //中间俩头像只需设置平移的距离即可
        getChildAt(1)?.apply {
            animate().translationXBy(-scrollLength).setDuration(animDuration).start()
        }
        //设置平移的距离
        getChildAt(2)?.apply {
            animate().translationXBy(-scrollLength).setDuration(animDuration).start()
        }
        //最左边的头像（从完整显示 到 透明度和大小都变小，并且左移出屏幕）（因为是最先add进来的View，所以index=0）
        getChildAt(0)?.let { iv ->
            iv.animate().translationXBy(0f).alpha(0F).scaleX(scaleFrom).scaleY(scaleFrom)
                .setDuration(animDuration)
                .setListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator?) {
                        super.onAnimationEnd(animation)
                        //清除ImageView已有属性，并添加进ivCache缓存
                        iv.animate().setListener(null)
                        iv.clearAnimation()
                        iv.translationX = 0F
                        iv.scaleX = 1.0F
                        iv.scaleY = 1.0F
                        iv.alpha = 1F
                        //从RelativeLayout移出
                        removeView(iv)
                        ivCache.add(0, iv as ImageView)
                        try {
                            if ((context as Activity).isFinishing) {
                                stopLoop()
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    }
                }).start()
        }
    }

    private fun sendLoopMsg() {
        handler.sendEmptyMessageDelayed(START_AVATAR_LOOP, animIntervalTime + animDuration)
    }

    private var looping = false

    /**
     * 开始轮播
     */
    fun startLoop() {
        if (looping) {
            Log.e("startLoop", "startLoop cannot be called twice")
        }
        looping = true
        sendLoopMsg()
    }

    /**
     * 停止轮播
     */
    fun stopLoop() {
        looping = false
        handler.removeCallbacksAndMessages(null)
    }
}