package com.adealink.weparty.wallet.manager

import com.adealink.frame.base.IError
import com.adealink.frame.base.Rlt
import com.adealink.frame.frame.BaseFrame
import com.adealink.weparty.App
import com.adealink.weparty.commonui.ext.isSuccess
import com.adealink.weparty.config.Config
import com.adealink.weparty.config.globalConfigManager
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.wallet.datasource.remote.WalletHttpService
import com.adealink.weparty.wallet.recharge.data.ConvertCurrencyReq
import com.adealink.weparty.wallet.recharge.data.RechargeConfigData
import kotlinx.coroutines.launch


val walletManager: IWalletManager by lazy { WalletManager() }

class WalletManager : BaseFrame<IWalletListener>(), IWalletManager {

    private val walletHttpService by lazy {
        App.instance.networkService.getHttpService(WalletHttpService::class.java)
    }

    private var coin: Double = 0.0
    private var diamond: Double = 0.0
    private var bean: Double = 0.0

    override fun getWalletData() {
        launch {
            notifyCurrencyChanged()
        }
    }

    override fun refreshWalletData() {
        launch {
            suspendRefreshWalletData()
        }
    }

    private suspend fun suspendRefreshWalletData() {
        pullWalletData()
        notifyCurrencyChanged()
    }

    override fun getCurrencyCound(currency: Currency): Double {
        return when (currency) {
            Currency.COIN -> coin
            Currency.DIAMOND -> diamond
            Currency.BEAN -> bean
        }
    }

    override suspend fun pullWalletData(): Rlt<Map<Currency, Double>> {
        val rlt = walletHttpService.pullWallet()
        when (rlt) {
            is Rlt.Failed -> {
                return rlt
            }

            is Rlt.Success -> {
                this.coin = rlt.data.data?.coin ?: 0.0
                this.diamond = rlt.data.data?.diamond ?: 0.0
                this.bean = rlt.data.data?.bean ?: 0.0
                return Rlt.Success(
                    mapOf(
                        Currency.COIN to this.coin,
                        Currency.DIAMOND to this.diamond,
                        Currency.BEAN to this.bean
                    )
                )
            }
        }
    }

    override suspend fun recharge(data: RechargeConfigData): Rlt<Any> {
        return Rlt.Failed(IError(""))
    }

    override suspend fun loadConvertConfig(): Rlt<Any> {
        globalConfigManager.getAllGlobalConfig(true)
        globalConfigManager.get(Config.CoinExchange)
        return Rlt.Failed(IError(""))
    }

    override fun calcConvertResult(
        fromCurrency: Currency,
        toCurrency: Currency,
        amount: Double
    ): Double {
        return 0.0
    }

    override suspend fun convertTo(
        fromCurrency: Currency,
        toCurrency: Currency,
        amount: Double
    ): Rlt<Double> {
        val rlt = walletHttpService.convertCurrency(
            ConvertCurrencyReq(
                fromCurrency.type,
                toCurrency.type,
                amount
            )
        )
        if (rlt.isSuccess) {
            suspendRefreshWalletData()
        }
        return Rlt.Failed(IError(""))
    }

    private fun notifyCurrencyChanged() {
        dispatch {
            it.onCurrencyChanged(
                mapOf(
                    Currency.COIN to this.coin,
                    Currency.DIAMOND to this.diamond,
                    Currency.BEAN to this.bean
                )
            )
        }
    }


}