package com.remax.visualnovel.widget.ui


import android.content.Context
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable
import android.util.AttributeSet
import androidx.annotation.StringRes
import androidx.appcompat.widget.SwitchCompat
import com.remax.visualnovel.R
import com.remax.visualnovel.utils.spannablex.utils.dp
import com.remax.visualnovel.widget.uitoken.handleUIToken


/**
 * Created by HJW on 2022/9/12
 */
class SwitchView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = androidx.appcompat.R.attr.switchStyle
) :
    SwitchCompat(context, attrs, defStyleAttr) {

    companion object {
        const val LARGE = 0
        const val SMALL = 1
        const val XSMALL = 2
    }

    private var bgWid = 0
    private var bgHei = 0
    private var thumbSize = 0
    private var padding = 0
    private var strokeWidth = 0


    init {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.SwitchView)
        val type = ta.getInt(R.styleable.SwitchView_switchSize, SMALL)
        val colorStyle = ta.getInt(R.styleable.SwitchView_switchColorStyle, 0)
        ta.recycle()

        when (type) {
            LARGE -> {
                bgWid = 56.dp
                bgHei = 32.dp
                thumbSize = 24.dp
                padding = 4.dp
                strokeWidth = 4.dp
            }

            SMALL -> {
                bgWid = 40.dp
                bgHei = 24.dp
                thumbSize = 16.dp
                padding = 4.dp
                strokeWidth = 4.dp
            }

            XSMALL -> {
                bgWid = 28.dp
                bgHei = 16.dp
                thumbSize = 12.dp
                padding = 2.dp
                strokeWidth = 1.dp
            }
        }

        background = setTrackDrawable(true, colorStyle)
        //轨道背景
        trackDrawable = setTrackDrawable(false, colorStyle)
        //滑块背景
        thumbDrawable = setThumbDrawable(colorStyle)

        setPadding(padding, padding, padding, padding)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(bgWid, bgHei)
    }

    fun setPressChanged(callback: (Boolean) -> Unit) {
        setOnCheckedChangeListener { v, checked ->
            if (v.isPressed) {
                callback(checked)
            }
        }
    }

    private fun setThumbDrawable(style: Int): Drawable {
        val normal: Int
        val checked: Int
        if (style == 0) {
            normal = R.string.switch_view_normal
            checked = R.string.switch_view_checked
        } else {
            normal = R.string.color_txt_secondary_normal
            checked = R.string.color_surface_white_normal
        }
        val normalDrawable = getThumbStateDrawable(normal)
        //val pressDrawable = getThumbStateDrawable(R.string.color_surface_white_press, R.string.color_surface_element_press)
        //val disabledDrawable = getThumbStateDrawable(R.string.color_surface_white_disabled, R.string.color_surface_element_normal)
        val checkedDrawable = getThumbStateDrawable(checked)

        val resDrawable = StateListDrawable()
        //resDrawable.addState(intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled), pressDrawable)
        resDrawable.addState(intArrayOf(android.R.attr.state_checked, android.R.attr.state_enabled), checkedDrawable)
        resDrawable.addState(intArrayOf(android.R.attr.state_enabled), normalDrawable)
        //resDrawable.addState(intArrayOf(), disabledDrawable)

        return resDrawable
    }

    private fun getThumbStateDrawable(@StringRes colorToken: Int): Drawable {
        return GradientDrawable().apply {
            shape = GradientDrawable.OVAL
            setSize(thumbSize, thumbSize)
            val color = context.handleUIToken(colorToken)?.color ?: 0
            setColor(color)
        }
    }

    private fun getTrackStateDrawable(
        @StringRes colorToken: Int,
        @StringRes strokeColorToken: Int,
        isBg: Boolean
    ): Drawable {
        return GradientDrawable().apply {
            shape = GradientDrawable.RECTANGLE
            setSize(if (isBg) bgWid else bgWid - 8.dp, if (isBg) bgHei else bgHei - 8.dp)
            val radius = context.handleUIToken(R.string.radius_pill)?.size ?: 0f
            cornerRadius = radius
            val color = context.handleUIToken(colorToken)?.color ?: 0
            val strokeWidth = if (isBg) strokeWidth else 0
            val strokeColor = context.handleUIToken(strokeColorToken)?.color ?: 0
            setStroke(strokeWidth, strokeColor)
            setColor(color)
        }
    }

    private fun setTrackDrawable(isBg: Boolean, style: Int): Drawable {
        val normal: Int
        val checked: Int
        val stroke: Int
        if (style == 0) {
            if (isBg) {
                normal = R.string.switch_view_stroke
                checked = R.string.switch_view_stroke
                stroke = R.string.switch_view_stroke
            } else {
                normal = R.string.switch_view_stroke
                checked = R.string.switch_view_stroke
                stroke = R.string.switch_view_stroke
            }
        } else {
            if (isBg) {
                normal = R.string.color_surface_top_normal
                checked = R.string.color_primary_normal
                stroke = R.string.color_outline_normal
            } else {
                normal = R.string.color_surface_top_normal
                checked = R.string.color_primary_normal
                stroke = R.string.color_transparent
            }
        }
        val normalDrawable = getTrackStateDrawable(normal, stroke, isBg)
        //val pressDrawable = getTrackStateDrawable(R.string.color_surface_element_press, isBg)
        //val disabledDrawable = getTrackStateDrawable(R.string.color_surface_element_normal, isBg)
        val checkedDrawable = getTrackStateDrawable(checked, checked, isBg)

        val resDrawable = StateListDrawable()
        //resDrawable.addState(intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled), pressDrawable)
        resDrawable.addState(intArrayOf(android.R.attr.state_checked, android.R.attr.state_enabled), checkedDrawable)
        resDrawable.addState(intArrayOf(android.R.attr.state_enabled), normalDrawable)
        //resDrawable.addState(intArrayOf(), disabledDrawable)
        return resDrawable
    }

}