package com.xuqm.base.extensions

import android.app.Activity
import android.content.Context
import android.view.inputmethod.InputMethodManager
import androidx.annotation.NonNull
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import com.livinglifetechway.quickpermissions_kotlin.runWithPermissions
import com.livinglifetechway.quickpermissions_kotlin.util.QuickPermissionsOptions
import com.xuqm.base.BuildConfig
import com.xuqm.base.common.LogHelper
import com.xuqm.base.common.ToolsHelper
import kotlin.experimental.and
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty


private class NotNullSingleValue<T> : ReadWriteProperty<Any?, T> {

    private var value: T? = null

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: throw IllegalStateException("not initialized")
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        if (this.value == null) {
            this.value = value
        } else {
            throw IllegalStateException("already initialized")
        }
    }

}

/**
 * 不为空且唯一
 */
fun <T> notNullSingleValue(): ReadWriteProperty<Any?, T> = NotNullSingleValue()


/**
 * 打印log
 */
//fun Any.log(message: CharSequence) {
//    KLog.d(this.javaClass.simpleName, message)
//}

fun Any.log(message: Any) {
    LogHelper.d(this.javaClass.simpleName, message)
}

fun Any.loge(message: Any) {
    LogHelper.e("=====>" + this.javaClass.simpleName, message)
}

fun Any.log() {
    LogHelper.d("=====>" + this.javaClass.simpleName, this)
}

fun Any.loge() {
    LogHelper.e("=====>" + this.javaClass.simpleName, this)
}

fun Any.showMessage(content: CharSequence) {
    ToolsHelper.showMessage(content)
}

fun Any.showMessage() {
    ToolsHelper.showMessage(this.toString())
}

fun ByteArray.toHexString(): String {
    val sb = StringBuffer()
    for (i in this.indices) {
        val hex = Integer.toHexString((this[i] and 0xFF.toByte()).toInt())
        if (hex.length < 2) {
            sb.append(0)
        }
        sb.append(hex)
    }
    return sb.toString()
}


/**
 * 弹出窗口
 * @param title 标题
 * @param message 提示信息
 * @param confirm 点击确认按钮
 * @param cancel 点击取消按钮的事件
 */
fun Activity.showDialog(title: String, message: String, confirm: () -> Unit, cancel: () -> Unit) {
    AlertDialog.Builder(this).setTitle(title)
        .setMessage(message)
        .setPositiveButton(
            "确定"
        ) { _, _ ->
            confirm()
        }
        .setNegativeButton(
            "取消"
        ) { _, _ ->
            cancel()
        }.create().show()
}

/**
 * 弹出窗口---只有一个确认按钮
 * @param title 标题
 * @param message 提示信息
 * @param confirm 点击确认按钮
 */
fun Activity.showDialog(title: String, message: String, confirm: () -> Unit) {
    AlertDialog.Builder(this).setTitle(title)
        .setMessage(message)
        .setPositiveButton(
            "确定"
        ) { _, _ ->
            confirm()
        }.create().show()
}

/**
 * 权限检测--申请
 * @param rationaleMethod 权限被拒绝时候的回调，提供重新申请，打开设置界面等方法
 * @param permanentDeniedMethod 拒绝权限并且选中了不在提示选项的回调，可以指导用户打开设置页面授予权限
 */
fun Context?.runWithPermission(
    vararg permissions: String,
    callback: () -> Unit
): Any? = this.runWithPermissions(
    *permissions
) { callback() }


fun Context?.runWithPermission(
    vararg permissions: String,
    rationaleMethod: ((com.livinglifetechway.quickpermissions_kotlin.util.QuickPermissionsRequest) -> Unit),
    permanentDeniedMethod: ((com.livinglifetechway.quickpermissions_kotlin.util.QuickPermissionsRequest) -> Unit),
    callback: () -> Unit
): Any? {

    val quickPermissionsOption = QuickPermissionsOptions(
        rationaleMethod = rationaleMethod,
        permanentDeniedMethod = permanentDeniedMethod
    )

    return this.runWithPermissions(
        *permissions, options = quickPermissionsOption
    ) { callback() }
}

/*
隐藏软键盘
 */
fun Activity.hideSoftInput() {
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(window.decorView.windowToken, 0)
}

fun Fragment.hideSoftInput() {
    activity?.hideSoftInput()
}

fun Context.putInt(key: String, value: Int) {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE) ?: return
    with(sharedPref.edit()) {
        putInt(key, value)
        apply()
    }
}

fun Context.getIntForPreferences(key: String): Int {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getInt(key, -1) ?: -1
}

fun Context.getIntForPreferences(key: String, @NonNull defValue: Int): Int {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getInt(key, defValue) ?: defValue
}

fun Context.putLong(key: String, value: Long) {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE) ?: return
    with(sharedPref.edit()) {
        putLong(key, value)
        apply()
    }
}

fun Context.getLongForPreferences(key: String): Long {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getLong(key, -1) ?: -1
}

fun Context.getLongForPreferences(key: String, @NonNull defValue: Long): Long {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getLong(key, defValue) ?: defValue
}

fun Context.putString(key: String, value: String) {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE) ?: return
    with(sharedPref.edit()) {
        putString(key, value)
        apply()
    }
}

fun Context.getStringForPreferences(key: String): String {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getString(key, "") ?: ""
}

fun Context.getStringForPreferences(key: String, @NonNull defValue: String): String {
    val sharedPref =
        getSharedPreferences(BuildConfig.APP_ID, Context.MODE_PRIVATE)
    return sharedPref?.getString(key, defValue) ?: defValue
}