package com.remax.visualnovel.widget.uitoken

import android.content.Context
import android.graphics.Color
import android.os.Build
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import com.remax.visualnovel.BuildConfig
import com.remax.visualnovel.R
import com.remax.visualnovel.extension.readJsonAsset
import com.remax.visualnovel.utils.spannablex.utils.dp
import com.remax.visualnovel.widget.uitoken.bean.UIToken
import org.json.JSONObject

/**
 * Created by HJW on 2022/8/31
 */
private var jsonObject: JSONObject? = null
private const val packageName = BuildConfig.APPLICATION_ID
private val tokenMap = mutableMapOf<String, UIToken>()

fun Context.handleUIToken(@StringRes res: Int): UIToken? {
    return if (res == 0) null else getString(res).handleUIToken(this)
}

fun String.handleUIToken(context: Context): UIToken? {
    if (this.isEmpty()) return null
    if (tokenMap.contains(this)) {
        return tokenMap[this]
    }
    //本地token 透明色
    when (this) {
        context.getString(R.string.color_transparent) -> {
            val uiToken = UIToken(UIToken.FILL_COLOR, context.getColor(R.color.transparent))
            tokenMap[this] = uiToken
            return uiToken
        }
    }
    if (jsonObject == null) {
        val jsonStr = context.readJsonAsset("uitoken/token_sys.json")
        jsonObject = JSONObject(jsonStr)
    }
    // token是正确的key
    if (jsonObject?.has(this) == true) {
        val value = jsonObject?.getString(this) ?: ""
        when {
            //文字组合  $glo.font.family.sys,$glo.font.size.48,$glo.font.weight.bold,$glo.font.lineheight.size48
            value.startsWith("\$glo.font") -> {
                val txtTokens = value.split(",")
                // [$glo.font.family.sys,$glo.font.size.48,$glo.font.weight.bold,$glo.font.lineheight.size48]
                val uiToken = UIToken(UIToken.FONT)
                val uiFont = UIToken.TextFont()
                var fontTypeFace = ""
                txtTokens.forEachIndexed { index, s ->
                    val gloToken = s.replace("$", "").replace(".", "_").trim()
                    when (index) {
                        //字体
                        0 -> {
                            val stringId = context.resources.getIdentifier(gloToken, "string", packageName)
                            fontTypeFace += "${context.getString(stringId)}-"
                        }
                        //字号
                        1 -> {
                            val dimenId = context.resources.getIdentifier(gloToken, "dimen", packageName)
                            uiFont.textFontSize = context.resources.getDimension(dimenId)
                        }
                        //字重
                        2 -> {
                            val stringId = context.resources.getIdentifier(gloToken, "string", packageName)
                            fontTypeFace += context.getString(stringId)
                        }
                        //行间距
                        3 -> {
                            val dimenId = context.resources.getIdentifier(gloToken, "dimen", packageName)
                            uiFont.textLineSpace = context.resources.getDimension(dimenId)
                        }
                    }
                }
                uiFont.typeFace = "family/$fontTypeFace.ttf"
                uiToken.textFont = uiFont
                tokenMap[this] = uiToken
                return uiToken
            }

            //颜色 $glo.color.violet.40
            value.startsWith("\$glo.color") -> {
                val uiToken = UIToken(UIToken.FILL_COLOR, value.translateColor(context))
                tokenMap[this] = uiToken
                return uiToken
            }

            // 渐变色 @GRA:$glo.deg.ltr,$glo.color.blue.40,$glo.color.violet.40
            value.startsWith("@GRA:") -> {
                // [$glo.deg.ltr,$glo.color.blue.40&$glo.transparent.t0,$glo.color.violet.40]
                val values = value.replace("@GRA:", "").split(",")
                val uiToken = UIToken(UIToken.LINEAR_GRADIENT)
                val colors = arrayListOf<Int>()
                values.forEachIndexed { index, s ->
                    val idName = s.replace("$", "").replace(".", "_").trim()
                    when (index) {
                        //下标0是方向
                        0 -> {
                            val degId = context.resources.getIdentifier(idName, "string", packageName)
                            uiToken.deg = context.resources.getString(degId)
                        }
                        //其他都是颜色
                        else -> {
                            //$glo.color.blue.40&$glo.transparent.t0
                            val color = s.replace("&", ",").translateColor(context)
                            colors.add(color)
                        }
                    }
                }
                uiToken.colors = colors.toIntArray()
                tokenMap[this] = uiToken
                return uiToken
            }

            // 引用其他颜色token
            value.startsWith("\$color") -> {
                return value.replace("$", "").handleUIToken(context)
            }

            // 大小 圆角 $glo.radius.16
            value.startsWith("\$glo.radius") -> {
                val uiToken = UIToken(UIToken.SIZE, size = value.translateDimenPixel(context))
                tokenMap[this] = uiToken
                return uiToken
            }

            // 大小 描边 $glo.border.2
            value.startsWith("\$glo.border") -> {
                val uiToken = UIToken(UIToken.SIZE, size = value.translateDimenPixel(context))
                tokenMap[this] = uiToken
                return uiToken
            }

            //阴影 @SHA:$glo.color.black,$glo.transparent.t15,0&4,4
            value.startsWith("@SHA:") -> {
                val outLine = UIToken.OutLine()
                //[$glo.color.black,$glo.transparent.t15,0&16,16]
                val valueSplit = value.replace("@SHA:", "").split(",")
                valueSplit.forEachIndexed { index, s ->
                    when (index) {
                        //阴影颜色
                        0 -> {
                            outLine.color = s.translateColor(context)
                        }
                        //阴影透明度
                        1 -> {
                            val alphaRes = s.replace("$", "").replace(".", "_")
                            val float = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                                val alphaId = context.resources.getIdentifier(alphaRes, "dimen", packageName)
                                context.resources.getFloat(alphaId)
                            } else {
                                val alphaId = context.resources.getIdentifier(alphaRes, "fraction", packageName)
                                context.resources.getFraction(alphaId, 1, 1)
                            }
                            outLine.alpha = float * 2
                        }
                        //偏移
                        2 -> {
                            val offSetSplit = s.split("&")
                            outLine.offsetX = offSetSplit[0].toInt().dp
                            outLine.offsetY = offSetSplit[1].toInt().dp
                        }
                        //elevation
                        3 -> {
                            outLine.elevation = s.toInt().dp.toFloat()
                        }
                    }
                }
                val uiToken = UIToken(UIToken.OUTLINE, outLine = outLine)
                tokenMap[this] = uiToken
                return uiToken
            }
        }
    }

    return null
}

/**
 * 大小token返回px
 */
private fun String.translateDimenPixel(context: Context): Float {
    val idName = this.replace("$", "").replace(".", "_").trim()
    val dimenId = context.resources.getIdentifier(idName, "dimen", packageName)
    return context.resources.getDimension(dimenId)
}

/**
 * 颜色token返回16进制
 */
private fun String.translateColor(context: Context): Int {
    val values = this.replace("$", "").replace(".", "_").split(",")
    var colorInt = 0
    var alpha = 255
    values.forEachIndexed { index, s ->
        val value = s.trim()
        when (index) {
            // 0 是颜色
            0 -> {
                val colorId = context.resources.getIdentifier(value, "color", packageName)
                colorInt = ContextCompat.getColor(context, colorId)
            }
            // 1 是透明度
            1 -> {
                val float = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    val alphaId = context.resources.getIdentifier(value, "dimen", packageName)
                    context.resources.getFloat(alphaId)
                } else {
                    val alphaId = context.resources.getIdentifier(value, "fraction", packageName)
                    context.resources.getFraction(alphaId, 1, 1)
                }
                alpha = (float * alpha).toInt()
            }
        }
    }
    val red: Int = colorInt and 0x00ff0000 shr 16
    val green: Int = colorInt and 0x0000ff00 shr 8
    val blue: Int = colorInt and 0x000000ff
    return Color.argb(alpha, red, green, blue)
}


//将10进制颜色（int）值转换成16进制(String)
fun Int.intToString(): String {
    var hexString = Integer.toHexString(this)
    if (hexString.length == 1) {
        hexString = "0$hexString"
    }
    return hexString
}