package com.tangem.features.swap.v2.impl.common

import com.tangem.common.ui.alerts.TransactionErrorDialogFactory
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.DialogMessage
import com.tangem.core.ui.message.EventMessageAction
import com.tangem.domain.express.models.ExpressError
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.features.swap.v2.impl.R
import javax.inject.Inject

@ModelScoped
internal class SwapAlertFactory @Inject constructor(
    private val uiMessageSender: UiMessageSender,
    private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase,
    private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
    private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
    private val transactionErrorDialogFactory: TransactionErrorDialogFactory,
    private val analyticsEventHandler: AnalyticsEventHandler,
) {
    fun getGenericErrorState(expressError: ExpressError, onFailedTxEmailClick: () -> Unit, popBack: () -> Unit = {}) {
        uiMessageSender.send(
            DialogMessage.Companion(
                title = SwapUtils.getExpressErrorTitle(expressError),
                message = SwapUtils.getExpressErrorMessage(expressError),
                onDismissRequest = popBack,
                dismissOnFirstAction = false,
                firstActionBuilder = {
                    EventMessageAction(
                        title = resourceReference(R.string.common_support),
                        onClick = onFailedTxEmailClick,
                    )
                },
                secondActionBuilder = { cancelAction() },
            ),
        )
    }

    @Suppress("CanBeNonNullable")
    fun getSendTransactionErrorState(
        error: SendTransactionError?,
        popBack: () -> Unit,
        onFailedTxEmailClick: (String) -> Unit,
    ) {
        if (error == null) return

        val errorDialog = transactionErrorDialogFactory.create(
            error = error,
            popBackStack = popBack,
            onFailedTxEmailClick = onFailedTxEmailClick,
        ) ?: return

        uiMessageSender.send(errorDialog)
    }

    suspend fun onFailedTxEmailClick(
        userWallet: UserWallet,
        cryptoCurrency: CryptoCurrency?,
        errorMessage: String?,
        txId: String? = null,
        confirmData: ConfirmData? = null,
    ) {
        saveBlockchainErrorUseCase(
            error = BlockchainErrorInfo(
                errorMessage = errorMessage.orEmpty(),
                networkId = cryptoCurrency?.network?.id,
                destinationAddress = confirmData?.enteredDestination.orEmpty(),
                tokenSymbol = confirmData?.toCryptoCurrencyStatus?.currency?.symbol.orEmpty(),
                amount = confirmData?.enteredFromAmount?.toString().orEmpty(),
                fee = confirmData?.fee?.amount?.value?.toString()
                    .orEmpty(),
            ),
        )

        val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return

        analyticsEventHandler.send(Basic.ButtonSupport(source = AnalyticsParam.ScreensSources.Swap))
        sendFeedbackEmailUseCase(
            type = FeedbackEmailType.SwapProblem(
                walletMetaInfo = metaInfo,
                providerName = confirmData?.quote?.provider?.name.orEmpty(),
                txId = txId.orEmpty(),
            ),
        )
    }
}