package com.remax.visualnovel.extension

import android.os.SystemClock
import android.view.View
import androidx.lifecycle.LifecycleCoroutineScope
import com.remax.visualnovel.R
import com.remax.visualnovel.manager.login.LoginManager
import com.remax.visualnovel.utils.Routers
import com.remax.visualnovel.utils.TimeUtils
import com.dylanc.loadingstateview.viewClickHandler
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.Locale

/**
 * 批量添加点击事件，防抖500毫秒
 * */
inline fun setOnClick(vararg v: View?, crossinline block: viewClickHandler) {
    val interval = 500L
    v.forEach {
        it?.let { view ->
            view.setOnClickListener {
                val lastClickedTimestamp = view.getTag(R.id.view_last_click_timestamp)?.toString()?.toLongOrNull() ?: 0L
                val currTimestamp = SystemClock.uptimeMillis()
                if (currTimestamp - lastClickedTimestamp < interval) return@setOnClickListener
                view.setTag(R.id.view_last_click_timestamp, currTimestamp)
                view.block()
            }
        }
    }
}

/**
 * 检查是否登录，未登录直接跳转登录页面
 * */
fun checkLogin(then: (() -> Unit)? = null): Boolean {
    return if (LoginManager.isLogin) {
        then?.invoke()
        true
    } else {
        Routers.navigation(Routers.LOGIN)
        false
    }
}

//防止弹窗多次弹出
private var addGamerIdHintDialogIsShow = false

inline fun <reified T> String?.convertFromJson(): T? {
    return try {
        Gson().fromJson(this ?: "", T::class.java)
    } catch (_: Exception) {
        null
    }
}

/**
 * map 解析json
 * */
inline fun <reified T> Map<String, Any>?.convertFromJson(): T? {
    return try {
        Gson().fromJson(Gson().toJson(this ?: HashMap<String, Any>()) ?: "", T::class.java)
    } catch (_: Exception) {
        null
    }
}

inline fun <reified T> convertListFromJson(param: String?): List<T> {
    return try {
        val itemType = object : TypeToken<List<T>>() {}.type
        Gson().fromJson(param, itemType) ?: emptyList()
    } catch (e: Exception) {
        emptyList()
    }
}

val buffDecimalFormat: DecimalFormat
    get() {
        return DecimalFormat("#,###,##0.00")
    }


fun formatBuff(buff: Long?): String {
    val obj = BigDecimal(buff ?: 0L).divide(BigDecimal(100), 2, RoundingMode.DOWN)
    return buffDecimalFormat.format(obj.toDouble())
}

fun formatBuffWithIntegers(buff: Long?): String {
    val buffInt = ((buff ?: 0L) / 100)
    return formatNumber(buffInt)
}

/**
 * 价格输入框不能格式化价格
 */
fun formatPrice(buff: Long?, isIntegers: Boolean = true) = if (isIntegers)
    formatBuffWithIntegers(buff)
else
    BigDecimal(buff ?: 0L).divide(BigDecimal(100)).setScale(2).toString()

val numberDecimalFormat = DecimalFormat("#,###,###")
fun formatNumber(number: Long?): String {
    val formatNumber = number ?: 0
    if (formatNumber < 1000) return formatNumber.toString()
    return numberDecimalFormat.format(formatNumber)
}

val birthDateFormatParse by lazy { SimpleDateFormat(TimeUtils.YMD_PATTERN, Locale.getDefault()) }

/**
 * 语音录音计时器
 *
 * @param total
 * @return job
 */
fun LifecycleCoroutineScope.countDownCoroutines(total: Int, onTick: (Int) -> Unit, onFinish: () -> Unit): Job {
    return flow {
        for (i in total downTo 1) {
            emit(i)
            delay(1000)
        }
    }
        .flowOn(Dispatchers.Main)
        .onCompletion {
            onFinish.invoke()
        }
        .onEach {
            onTick.invoke(it)
        }
        .launchIn(this)
}


