package com.gamedog.vididin.core.login.login

import com.ama.core.architecture.util.AndroidUtil
import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.DeviceUtil
import com.ama.core.architecture.util.SpUtil
import com.ama.core.architecture.util.eventbus.NotifyMan
import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.Account
import com.gamedog.vididin.beans.BankInfo
import com.gamedog.vididin.main.fragments.task.TaskBean
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock


object AccountManager {

    private val mutex = Mutex()

    private val mAccount: Account? by lazy {
        var account = SpUtil.instance().getObject<Account>(SpUtil.KEY_ACCOUNT)
        if (account == null) {
            val deviceUUId = DeviceUtil.generateDeviceId()
            account = Account(accountId = "user_$deviceUUId", deviceUUId=deviceUUId, createdAt = DateUtil.getCurTimeMs())
            account.let {
                SpUtil.instance().putObject(SpUtil.KEY_ACCOUNT, account)
            }
        }
        account
    }

    private fun saveAccountInfo() {
        SpUtil.instance().putObject(SpUtil.KEY_ACCOUNT, mAccount)
    }

    fun getAccount() : Account? {
        return mAccount
    }

    fun getGold(): Long {
        return mAccount?.goldCount ?: 0L
    }

    fun getCash(): Float {
        return mAccount?.cashCount ?: 0F
    }

    fun addGold(newGold: Int) {
        mAccount?.goldCount += newGold
        saveAccountInfo()
        NotifyMan.instance().sendEvent(VididinEvents.Event_Account_Gold_Changed, null)
    }

    fun addCash(newCash: Float) {
        mAccount?.cashCount += newCash
        saveAccountInfo()
        NotifyMan.instance().sendEvent(VididinEvents.Event_Account_Cash_Changed, null)
    }

    fun getBankInfo(): BankInfo? {
        return mAccount?.bankInfo
    }

    fun hasValidBankInfo(): Boolean {
        val backInfo = getBankInfo()
        return !backInfo?.bankName.isNullOrEmpty() && !backInfo.bankAccount.isNullOrEmpty()
    }

    fun saveBankAccount(bankAccount: String?) {
        if (bankAccount.isNullOrEmpty()) {
            mAccount?.bankInfo = null
        } else {
            mAccount?.bankInfo = BankInfo(bankAccount=bankAccount)
        }
        saveAccountInfo()
        NotifyMan.instance().sendEvent(
            VididinEvents.Event_Account_Bank_Info_Changed, NotifyMan.NotifyData(bankAccount))
    }



    @Synchronized
    fun convertGold2Cash(): Boolean  {
        try {
            val couldCovertCashTotal = mAccount?.goldCount?.div(VidiConst.PER_CASH_COST_GOLD_NUM) ?: 0L
            if (couldCovertCashTotal > 0) {
                val costGoldNum = couldCovertCashTotal * VidiConst.PER_CASH_COST_GOLD_NUM
                mAccount?.goldCount?.let {
                    if (it > costGoldNum) {
                        addGold(-1 * costGoldNum.toInt())
                        addCash(couldCovertCashTotal.toFloat())
                        AndroidUtil.showToast("Has convert $costGoldNum gold to $couldCovertCashTotal cash.")
                        return true
                    }
                }
            } else {
                AndroidUtil.showToast("You don't have enough gold.")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }

}

