package com.adealink.weparty.wallet.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.Rlt
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.weparty.App
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.module.wallet.viewmodel.IWalletViewModel
import com.adealink.weparty.wallet.datasource.remote.WalletHttpService
import com.adealink.weparty.wallet.manager.IWalletListener
import com.adealink.weparty.wallet.manager.walletManager
import com.adealink.weparty.wallet.recharge.data.PreConvertReq
import kotlinx.coroutines.launch

class WalletViewModel : BaseViewModel(), IWalletViewModel, IWalletListener {

    private val walletHttpService by lazy {
        App.instance.networkService.getHttpService(WalletHttpService::class.java)
    }
    override val coinLD: LiveData<Double> = MutableLiveData()
    override val diamondLD: LiveData<Double> = MutableLiveData()
    override val beanLD: LiveData<Double> = MutableLiveData()

    val availableBeanLD: LiveData<Double> = MutableLiveData()
    val unsettledBeanLD: LiveData<Double> = MutableLiveData()

    init {
        walletManager.addListener(this)
    }

    override fun onCleared() {
        super.onCleared()
        walletManager.removeListener(this)
    }

    fun getWalletData() {
        viewModelScope.launch {
            walletManager.getWalletData()
        }
    }

    override fun refreshWalletData() {
        viewModelScope.launch {
            walletManager.refreshWalletData()
        }
    }

    override fun getCoin(): Double {
        return walletManager.getBalance(Currency.COIN)
    }

    override fun getDiamond(): Double {
        return walletManager.getBalance(Currency.DIAMOND)
    }

    override fun getBean(): Double {
        return walletManager.getBalance(Currency.BEAN)
    }

    override fun onCurrencyChanged(currency: Map<Currency, Double>) {
        coinLD.send(currency[Currency.COIN] ?: 0.0)
        diamondLD.send(currency[Currency.DIAMOND] ?: 0.0)
        beanLD.send(currency[Currency.BEAN] ?: 0.0)
    }

    override fun onBeanChanged(bean: Double, availableBean: Double, unsettledBean: Double) {
        beanLD.send(bean)
        availableBeanLD.send(availableBean)
        unsettledBeanLD.send(unsettledBean)
    }

    fun loadConvertConfig(from: Currency, to: Currency): LiveData<Rlt<Double>> {
        val liveData = OnceMutableLiveData<Rlt<Double>>()
        viewModelScope.launch {
            liveData.send(walletManager.loadConvertConfig(from, to))
        }
        return liveData
    }

    fun preConvert(
        fromCurrency: Currency,
        toCurrency: Currency,
        amount: Double
    ): LiveData<Rlt<Pair<Double, Double>>> {
        val liveData = OnceMutableLiveData<Rlt<Pair<Double, Double>>>()
        viewModelScope.launch {
            val rlt = walletHttpService.preConvert(
                PreConvertReq(
                    fromCurrency.type,
                    toCurrency.type,
                    amount
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    liveData.send(rlt)
                }

                is Rlt.Success -> {
                    val toAmount = rlt.data.data?.amount
                    if (toAmount == null) {
                        liveData.send(Rlt.Failed(CommonDataNullError()))
                        return@launch
                    }
                    liveData.send(Rlt.Success(Pair(amount, toAmount)))
                }
            }
        }
        return liveData
    }

    fun convertTo(
        fromCurrency: Currency,
        toCurrency: Currency,
        amount: Double
    ): LiveData<Rlt<Any>> {
        val liveData = OnceMutableLiveData<Rlt<Any>>()
        viewModelScope.launch {
            liveData.send(
                walletManager.convertTo(fromCurrency, toCurrency, amount)
            )
        }
        return liveData
    }

}