package com.gh.common.view

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import androidx.annotation.ColorRes
import com.facebook.drawee.generic.RoundingParams
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.RadiusCardView
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.entity.GameEntity
import splitties.views.dsl.core.add
import splitties.views.dsl.core.lParams
import splitties.views.dsl.core.matchParent

class GameIconView : RadiusCardView {

    private var mCornerRadius = 0
    private var mBorderColor = 0
    private var mGameIconOverlayColor = 0
    private var mBorderWidth = 1
    private var mFadeDuration = -1

    private var mGameIconIv: SimpleDraweeView? = null
    private var mGameIconDecorationIv: SimpleDraweeView? = null
    private var mBorderView: View? = null
    private var mIsRemoveCrevice = false

    constructor(context: Context) : super(context, null) {
        initView(null)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs, 0) {
        initView(attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        initView(attrs)
    }

    fun initView(attrs: AttributeSet?) {
        val gameIconUi = GameIconUi(context)

        if (attrs != null && !isInEditMode) {
            val ta = context.obtainStyledAttributes(attrs, R.styleable.GameIconView)
            mCornerRadius = ta.getDimensionPixelSize(
                R.styleable.GameIconView_gameIconCornerRadius,
                DisplayUtils.dip2px(context, 0F)
            )
            mBorderColor = ta.getColor(R.styleable.GameIconView_gameIconBorderColor, 0)
            mGameIconOverlayColor = ta.getColor(R.styleable.GameIconView_gameIconOverlayColor, 0)
            mBorderWidth = ta.getDimensionPixelSize(R.styleable.GameIconView_gameIconBorderWidth, 1)
            mFadeDuration = ta.getInt(R.styleable.GameIconView_gameIconFadeDuration, -1)
            mIsRemoveCrevice = ta.getBoolean(R.styleable.GameIconView_gameIconRemoveCrevice, false)
            ta.recycle()
        }

        add(gameIconUi.root, lParams(matchParent, matchParent) { })

        mGameIconIv = gameIconUi.gameIconIv
        mGameIconDecorationIv = gameIconUi.gameIconDecorationIv
        mBorderView = gameIconUi.borderView

        mGameIconIv?.dimOnDarkMode()
        mGameIconDecorationIv?.dimOnDarkMode()

        if (mFadeDuration != -1) {
            mGameIconIv?.hierarchy?.fadeDuration = mFadeDuration
        }
        setBackgroundColor(Color.TRANSPARENT)
    }

    fun displayGameIcon(game: GameEntity) {
        if (!TextUtils.isEmpty(game.rawIcon)) {
            displayGameIcon(game.rawIcon ?: "", game.iconSubscript)
        } else {
            displayGameIcon(game.icon ?: "", null)
        }
    }

    fun displayGameIcon(icon: String?, iconSubscript: String?) {
        displayGameIcon(icon, iconSubscript, false)
    }

    fun displayGameIcon(icon: String?, iconSubscript: String?, goneIfEmpty: Boolean = false) {
        if (getTag(ImageUtils.TAG_TARGET_WIDTH) == null) {
            setTag(ImageUtils.TAG_TARGET_WIDTH, layoutParams.width)
        }

        mGameIconIv?.display(icon)
        mGameIconDecorationIv?.display(iconSubscript, true)
        if (goneIfEmpty) {
            visibility = if (TextUtils.isEmpty(icon)) View.GONE else View.VISIBLE
        }
    }

    fun getIconIv(): SimpleDraweeView = mGameIconIv!!

    fun getIconDecoratorIv(): SimpleDraweeView = mGameIconDecorationIv!!

    override fun setTag(key: Int, tag: Any?) {
        super.setTag(key, tag)
        mGameIconIv?.setTag(key, tag)
        mGameIconDecorationIv?.setTag(key, tag)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        setBorder(w)
    }

    private fun setBorder(width: Int) {
        val cornerRadius = if (!isInEditMode) {
            getCornerRadius(width)
        } else {
            0F
        }

        setRadiusPx(cornerRadius, cornerRadius, cornerRadius, cornerRadius)
        cardElevation = 0F

        // 一些设备(没错，又是 vivo)，代码设置 CardView 的 radius 无效(xml 设置有效)
        // 被迫再设置一次 SimpleDraweeView 的 radius :(
        val roundingParams = RoundingParams.fromCornersRadius(cornerRadius)
        if (mGameIconOverlayColor != 0) {
            roundingParams.overlayColor = mGameIconOverlayColor
        }

        if (mBorderColor != 0) {
            // 当图片为动图时，设置边框无效，所以改为增加一个View，专门用来设置边框
            //roundingParams.setBorder(mBorderColor, mBorderWidth.toFloat())
            val drawable = GradientDrawable().apply {
                shape = GradientDrawable.RECTANGLE
                //骚操作~ 这里加这个操作是为了防止图片和边框有间隙
                setCornerRadius(cornerRadius - if (mIsRemoveCrevice) mBorderWidth else 0)
                setColor(R.color.transparent.toColor())
                setStroke(mBorderWidth, mBorderColor)
            }
            mBorderView?.background = drawable
        }

        //骚操作~ 这里加这个操作是为了防止图片和边框有间隙、防止右上角的静态小标签都被挡住
        if (mBorderWidth != 0) {
            val halfBorderWidth = (mBorderWidth / 2F).toInt()
            mGameIconIv?.setPadding(halfBorderWidth, halfBorderWidth, halfBorderWidth, halfBorderWidth)
            mGameIconDecorationIv?.setPadding(halfBorderWidth, halfBorderWidth, halfBorderWidth, halfBorderWidth)
        }

        mGameIconIv?.hierarchy?.roundingParams = roundingParams
        mGameIconDecorationIv?.hierarchy?.roundingParams = roundingParams
    }

    fun setCornerRadius(cornerRadius: Int) {
        mCornerRadius = cornerRadius
    }

    fun setBorderColor(@ColorRes color: Int) {
        mBorderColor = color.toColor(context)
        setBorder(measuredWidth)
    }

    private fun getCornerRadius(width: Int): Float {
        // 预设的圆角设置优先级更高
        if (mCornerRadius != 0) {
            return mCornerRadius.toFloat()
        }

        return when {
            width <= SIZE_36 -> RADIUS_8
            width >= SIZE_88 -> RADIUS_20
            width >= SIZE_80 -> RADIUS_18
            width >= SIZE_72 -> RADIUS_16
            width >= SIZE_64 -> RADIUS_14
            width >= SIZE_48 -> RADIUS_12
            width >= SIZE_40 -> RADIUS_10
            else -> RADIUS_8
        }
    }

    companion object {
        val RADIUS_8 by lazy { 8F.dip2px().toFloat() }
        val RADIUS_10 by lazy { 10F.dip2px().toFloat() }
        val RADIUS_12 by lazy { 12F.dip2px().toFloat() }
        val RADIUS_14 by lazy { 14F.dip2px().toFloat() }
        val RADIUS_16 by lazy { 16F.dip2px().toFloat() }
        val RADIUS_18 by lazy { 18F.dip2px().toFloat() }
        val RADIUS_20 by lazy { 20F.dip2px().toFloat() }

        val SIZE_36 by lazy { 36F.dip2px() }
        val SIZE_40 by lazy { 40F.dip2px() }
        val SIZE_48 by lazy { 48F.dip2px() }
        val SIZE_64 by lazy { 64F.dip2px() }
        val SIZE_72 by lazy { 72F.dip2px() }
        val SIZE_80 by lazy { 80F.dip2px() }
        val SIZE_88 by lazy { 88F.dip2px() }
    }

}
