package com.cheng.blzb.manager

import android.os.Build
import android.text.TextUtils
import androidx.lifecycle.MutableLiveData
import com.cheng.blzb.bean.AreaEntity
import com.cheng.blzb.bean.BidTypeEntity
import com.cheng.blzb.bean.HotWordEntity
import com.cheng.blzb.bean.UserConfigEntity
import com.cheng.blzb.bean.UserEntity
import com.cheng.blzb.bean.WxShareEntity
import com.cheng.blzb.net.ApiFactory
import com.example.base.extensions.toast
import com.example.base.utils.MMKVUtils
import com.example.base.utils.Utils
import com.github.gzuliyujiang.oaid.DeviceID
import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.github.gzuliyujiang.oaid.IGetter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject

object UserConfigManager {
    val _userConfigLiveData = MutableLiveData<UserConfigEntity?>()

    val userConfig: UserConfigEntity? get() = _userConfigLiveData.value

    val userInfoLiveData = MutableLiveData<UserEntity?>()

    val userInfo: UserEntity? get() = userInfoLiveData.value

    //服务器时间和本地时间的偏移量
    private var timeDiff = 0L

    //真实的服务器时间
    fun serverTimeMillis(): Long {
        return System.currentTimeMillis() + timeDiff * 1000
    }

    fun getServerTime(clickFun: () -> Unit?) {
        GlobalScope.launch {
            try {
                val response = ApiFactory.apiService.getServerTime()
                if (response.status) {
                    timeDiff = response.data.toLong() - System.currentTimeMillis() / 1000
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                getUserConfig { clickFun.invoke() }
            }
        }
    }

    fun getUserConfig(clickFun: () -> Unit?) {
        if (!TextUtils.isEmpty(MMKVUtils.getString("userConfig"))) {
            val data = Gson().fromJson(MMKVUtils.getString("userConfig"), UserConfigEntity::class.java)
            _userConfigLiveData.postValue(data)

            getOaId()
            saveUserConfig(data)
            clickFun.invoke()
            return
        }
        getOaId {
            userConfig { clickFun.invoke() }
        }
    }

    fun userConfig(clickFun: () -> Unit?) {
        GlobalScope.launch {
            try {
                val oaid = MMKVUtils.getString("oaid") ?: ""
                val response = ApiFactory.apiService.getUserConfig(oaid, Build.VERSION.SDK_INT, "", DeviceIdentifier.getAndroidID(Utils.getApp()), getGTCid())
                if (response.status) {
                    timeDiff = response.data.nowtime.toLong() - System.currentTimeMillis() / 1000

                    _userConfigLiveData.postValue(response.data)
                    MMKVUtils.put("userConfig", Gson().toJson(response.data))

                    saveUserConfig(response.data)

                    withContext(Dispatchers.Main) {
                        clickFun.invoke()
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        toast(response.message, true)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun saveUserConfig(data: UserConfigEntity) {
        try {
            LoginManager.saveToken(data.token)
            saveIsTemp(data.temp)
            if (data.config != null){
                saveGuidePayEnable(data.config!!.guidePayEnable!!)
                saveGuideEnable(data.config!!.guideEnable!!)
                saveNoLoginPay(data.config!!.noLoginPayEnable!!)
                savePayAgreementEnable(data.config!!.payAgreementEnable!!)
                saveLoginType(data.config!!.loginType!!)
                saveShareEntity(data.config!!.wxShareEntity)
                saveAdSwitch(data.config!!.adSwitch)
                saveServicePhoneList(data.config!!.servicePhoneList)
                savePayType(data.config!!.payType)
                saveInvoiceIntervalTime(data.config!!.invoiceIntervalMinutes)
                saveGuideCountdownTime(data.config!!.guideCountdownTime)
            }
        } catch (e : Exception) {
            e.printStackTrace()
        }
    }

    fun saveLastUserinfo(userinfo: UserEntity?) {
        MMKVUtils.put("last_userinfo", Gson().toJson(userinfo))
    }

    fun getLastUserinfo(): UserEntity? {
        val str = MMKVUtils.getString("last_userinfo")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, UserEntity::class.java)
        }
        return null
    }

    /**
     * 是否同意隐私政策
     */
    fun saveAgree() {
        MMKVUtils.put("isAgree", true)
    }

    fun isAgree(): Boolean {
        return MMKVUtils.getBoolean("isAgree", false)
    }

    private fun saveGuidePayEnable(temp: Boolean) {
        MMKVUtils.put("guide_pay", temp)//引导页是否可以支付
    }

    fun getGuidePayEnable(): Boolean {
        return MMKVUtils.getBoolean("guide_pay", true)
    }

    private fun saveGuideEnable(temp: Boolean) {
        MMKVUtils.put("guide", temp)//是否开启引导页
    }

    fun getGuideEnable(): Boolean {
        return MMKVUtils.getBoolean("guide", true)
    }

    fun saveIsTemp(temp: Boolean) {
        MMKVUtils.put("x-role", temp)//true临时用户 ,false登录用户
    }

    fun getIsTemp(): Boolean {
        return MMKVUtils.getBoolean("x-role", true)
    }

    fun isFirstUseApp(): Boolean {
        return MMKVUtils.getBoolean("isFirstUse", true)
    }

    fun saveFirstUseApp(isFirst: Boolean) {
        MMKVUtils.put("isFirstUse", isFirst)
    }

    private fun saveNoLoginPay(noLoginPay: Boolean) {
        MMKVUtils.put("nologin_pay", noLoginPay)
    }

    fun getNoLoginPay(): Boolean {
        return MMKVUtils.getBoolean("nologin_pay", true)
    }

    private fun savePayAgreementEnable(payAgreement: Boolean) {
        MMKVUtils.put("pay_agreement", payAgreement)
    }

    fun isPayAgreementEnable(): Boolean {
        return MMKVUtils.getBoolean("pay_agreement", true)
    }

    private fun saveLoginType(list: List<String>) {
        MMKVUtils.put("login_type", Gson().toJson(list))
    }

    fun getLoginType(): List<String> {
        val s = MMKVUtils.getString("login_type")
        if (!TextUtils.isEmpty(s)) {
            return Gson().fromJson(s, object : TypeToken<List<String>>() {}.type)
        }
        return emptyList()
    }

    private fun saveShareEntity(entity: WxShareEntity?) {
        MMKVUtils.put("weixin_share", Gson().toJson(entity))
    }

    fun getShareEntity(): WxShareEntity? {
        val s = MMKVUtils.getString("weixin_share")
        if (!TextUtils.isEmpty(s)) {
            return Gson().fromJson(s, WxShareEntity::class.java)
        }
        return null
    }

    private fun saveAdSwitch(switch: Boolean) {
        MMKVUtils.put("ad_switch", switch)
    }

    fun isAdSwitch(): Boolean {
        return MMKVUtils.getBoolean("ad_switch")
    }

    private fun saveServicePhoneList(list: List<String>) {
        MMKVUtils.put("service_phone_list", Gson().toJson(list))
    }

    fun getServicePhoneList(): List<String> {
        val str = MMKVUtils.getString("service_phone_list")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, object : TypeToken<List<String>>() {}.type)
        }
        return emptyList()
    }

    /**
     * 全局支付方式
     */
    private fun savePayType(list: List<String>) {
        MMKVUtils.put("pay_type", Gson().toJson(list))
    }

    fun getPayType(): List<String> {
        val str = MMKVUtils.getString("pay_type")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, object : TypeToken<List<String>>() {}.type)
        }
        return emptyList()
    }

    /**
     * 加急开票间隔时间
     */
    private fun saveInvoiceIntervalTime(minutes: String?) {
        MMKVUtils.put("invoice_interval_time", minutes)
    }

    fun getInvoiceIntervalTime(): String? {
        return MMKVUtils.getString("invoice_interval_time")
    }

    /**
     * 搜索排序
     */
    private fun saveSearchSort(sort: String) {
        MMKVUtils.put("search_sort", sort)
    }

    fun getSearchSort(): String {
        return MMKVUtils.getString("search_sort") ?: ""
    }

    /**
     * 地区列表
     */
    fun saveAreaList(list: List<AreaEntity>) {
        if (list.isNotEmpty()) {
            MMKVUtils.put("area_list", Gson().toJson(list))
        }
    }

    fun getAreaList(): MutableList<AreaEntity> {
        val str = MMKVUtils.getString("area_list")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, object : TypeToken<MutableList<AreaEntity>>() {}.type)
        }
        return mutableListOf()
    }

    /**
     * 城市列表
     */
    fun getCityList(): List<AreaEntity> {
        val list = mutableListOf<AreaEntity>()
        getAreaList().forEach {
            list.addAll(it.children)
        }
        return list
    }

    /**
     * 招标类型
     */
    fun saveBidTypes(list: List<BidTypeEntity>) {
        MMKVUtils.put("bid_type", Gson().toJson(list))
    }

    fun getBidTypes(): List<BidTypeEntity> {
        val str = MMKVUtils.getString("bid_type")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, object : TypeToken<List<BidTypeEntity>>() {}.type)
        }
        return emptyList()
    }

    /**
     * 引导页热词
     */
    fun saveGuideKeywords(list: List<HotWordEntity>) {
        MMKVUtils.put("guide_keywords", Gson().toJson(list))
    }

    fun getGuideKeywords(): List<HotWordEntity> {
        val str = MMKVUtils.getString("guide_keywords")
        if (!TextUtils.isEmpty(str)) {
            return Gson().fromJson(str, object : TypeToken<List<HotWordEntity>>() {}.type)
        }
        return emptyList()
    }

    /**
     * 引导页支付倒计时
     */
    private fun saveGuideCountdownTime(time: String?) {
        MMKVUtils.put("guide_countdown_time", time)
    }

    fun getGuideCountdownTime(): String? {
        return MMKVUtils.getString("guide_countdown_time")
    }

    /**
     * 保存个推cid
     */
    fun saveGTCid(cid: String) {
        MMKVUtils.put("gt_cid", cid)
    }

    /**
     * 获取个推cid
     */
    fun getGTCid(): String {
        return MMKVUtils.getString("gt_cid") ?: ""
    }

    private fun getOaId(callback: ((String) -> Unit)? = null) {
        val oaid = DeviceIdentifier.getOAID(Utils.getApp())
        if (TextUtils.isEmpty(oaid)) {
            DeviceID.getOAID(Utils.getApp(), object : IGetter {
                override fun onOAIDGetComplete(result: String) {
                    MMKVUtils.put("oaid", result)
                    callback?.invoke(result)
                }

                override fun onOAIDGetError(error: Exception) {
                    callback?.invoke("")
                }
            })
        } else {
            MMKVUtils.put("oaid", oaid)
            callback?.invoke(oaid)
        }
    }

    /**
     * 保存百度归因bd_vid
     */
    fun saveBDVID() {
        try {
            val str = com.cheng.blzb.utils.appwalle.ChannelReader.get(Utils.getApp())
            if (!TextUtils.isEmpty(str)) {
                val jsonObj = JSONObject(str)
                jsonObj.getString("bd_vid").let {
                    MMKVUtils.put("bd_vid", it)
                }
            } else {
                MMKVUtils.put("bd_vid", "")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 获取百度归因bd_vid
     */
    fun getBDVID(): String {
        return MMKVUtils.getString("bd_vid") ?: ""
    }
}