package io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.mythos

import io.novafoundation.nova.feature_staking_impl.data.StakingOption
import io.novafoundation.nova.feature_staking_impl.domain.mythos.common.MythosSharedComputation
import io.novafoundation.nova.feature_staking_impl.domain.mythos.common.model.MythosDelegatorState
import io.novafoundation.nova.feature_staking_impl.domain.mythos.main.stakeSummary.MythosDelegatorStatus
import io.novafoundation.nova.feature_staking_impl.domain.mythos.main.stakeSummary.MythosStakeSummaryInteractor
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.ComponentHostContext
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.common.mythos.loadUserStakeState
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.BaseStakeSummaryComponent
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.StakeStatusModel
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.StakeSummaryComponent
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.StakeSummaryModel
import io.novafoundation.nova.feature_staking_impl.presentation.staking.main.components.stakeSummary.StakeSummaryState
import io.novafoundation.nova.feature_wallet_api.presentation.formatters.amount.AmountFormatter
import io.novafoundation.nova.feature_wallet_api.presentation.formatters.amount.formatAmountToAmountModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.mapLatest

class MythosStakeSummaryComponentFactory(
    private val mythosSharedComputation: MythosSharedComputation,
    private val interactor: MythosStakeSummaryInteractor,
    private val amountFormatter: AmountFormatter
) {

    fun create(
        stakingOption: StakingOption,
        hostContext: ComponentHostContext,
    ): StakeSummaryComponent = MythosStakeSummaryComponent(
        mythosSharedComputation = mythosSharedComputation,
        interactor = interactor,
        stakingOption = stakingOption,
        hostContext = hostContext,
        amountFormatter = amountFormatter
    )
}

private class MythosStakeSummaryComponent(
    private val mythosSharedComputation: MythosSharedComputation,
    private val interactor: MythosStakeSummaryInteractor,

    private val stakingOption: StakingOption,
    private val hostContext: ComponentHostContext,
    private val amountFormatter: AmountFormatter
) : BaseStakeSummaryComponent(hostContext.scope) {

    override val state: Flow<StakeSummaryState?> = mythosSharedComputation.loadUserStakeState(
        hostContext = hostContext,
        stateProducer = ::userStakeSummary
    )
        .shareInBackground()

    private fun userStakeSummary(delegatorState: MythosDelegatorState.Staked): Flow<StakeSummaryModel> {
        return interactor.stakeSummaryFlow(delegatorState, stakingOption).flatMapLatest { stakeSummary ->
            val status = stakeSummary.status.toUi()

            hostContext.assetFlow.mapLatest { asset ->
                StakeSummaryModel(
                    totalStaked = amountFormatter.formatAmountToAmountModel(stakeSummary.activeStake, asset),
                    status = status
                )
            }
        }
    }

    private fun MythosDelegatorStatus.toUi(): StakeStatusModel {
        return when (this) {
            MythosDelegatorStatus.Active -> StakeStatusModel.Active
            MythosDelegatorStatus.Inactive -> StakeStatusModel.Inactive
        }
    }
}
