package com.tangem.features.walletconnect.transaction.ui.send

import android.content.res.Configuration
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.domain.blockaid.models.transaction.ValidationResult
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.send.api.subcomponents.feeSelector.FeeSelectorBlockComponent
import com.tangem.features.send.api.subcomponents.feeSelector.entity.FeeSelectorUM
import com.tangem.features.walletconnect.connections.entity.VerifiedDAppState
import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.components.PreviewFeeSelectorBlockComponent
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.BlockAidNotificationUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangesUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionFeeState
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionItemUM
import com.tangem.features.walletconnect.transaction.ui.blockaid.TransactionCheckResultsItem
import com.tangem.features.walletconnect.transaction.ui.common.WcSendTransactionItems
import com.tangem.features.walletconnect.transaction.ui.common.WcSmallTitleItem
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestButtons
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestItem
import com.tangem.features.walletconnect.transaction.ui.sign.accountPortfolioName
import com.tangem.features.walletconnect.transaction.ui.sign.walletPortfolioName
import kotlinx.collections.immutable.persistentListOf
import java.math.BigDecimal

@Suppress("LongParameterList", "LongMethod")
@Composable
internal fun WcSendTransactionModalBottomSheet(
    state: WcSendTransactionItemUM,
    feeSelectorBlockComponent: FeeSelectorBlockComponent?,
    feeSelectorUM: FeeSelectorUM,
    onClickTransactionRequest: () -> Unit,
    onBack: () -> Unit,
    onDismiss: () -> Unit,
    onClickAllowToSpend: () -> Unit,
) {
    TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
        config = TangemBottomSheetConfig(
            isShown = true,
            onDismissRequest = onDismiss,
            content = TangemBottomSheetConfigContent.Empty,
        ),
        onBack = onBack,
        containerColor = TangemTheme.colors.background.tertiary,
        title = { config ->
            TangemModalBottomSheetTitle(
                title = resourceReference(R.string.wc_transaction_flow_title),
                endIconRes = R.drawable.ic_close_24,
                onEndClick = onDismiss,
            )
        },
        content = {
            Column(
                modifier = Modifier
                    .padding(horizontal = 16.dp),
            ) {
                Column(
                    modifier = Modifier
                        .clip(RoundedCornerShape(14.dp))
                        .background(color = TangemTheme.colors.background.action)
                        .fillMaxWidth()
                        .animateContentSize(),
                ) {
                    WcSmallTitleItem(R.string.wc_request_from)
                    WcAppInfoItem(
                        iconUrl = state.appInfo.appIcon,
                        title = state.appInfo.appName,
                        subtitle = state.appInfo.appSubtitle,
                        verifiedDAppState = state.appInfo.verifiedState,
                    )
                    DividerWithPadding(start = 0.dp, end = 0.dp)
                    WcTransactionRequestItem(
                        iconRes = R.drawable.ic_doc_new_24,
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable { onClickTransactionRequest() }
                            .padding(12.dp),
                    )
                }
                Column(modifier = Modifier.padding(top = 16.dp)) {
                    if (state.estimatedWalletChanges != null) {
                        TransactionCheckResultsItem(state.estimatedWalletChanges, onClickAllowToSpend)
                    }
                    WcSendTransactionItems(
                        modifier = Modifier.padding(top = 16.dp),
                        portfolioName = state.portfolioName,
                        networkInfo = state.networkInfo,
                        feeState = state.feeState,
                        feeSelectorBlockComponent = feeSelectorBlockComponent,
                        feeSelectorUM = feeSelectorUM,
                        address = state.address,
                    )
                    if (state.feeErrorNotification != null) {
                        Notification(
                            modifier = Modifier.padding(top = 14.dp),
                            config = state.feeErrorNotification.config,
                            iconTint = TangemTheme.colors.icon.warning,
                            containerColor = TangemTheme.colors.background.action,
                        )
                    }
                }
            }
        },
        footer = {
            WcTransactionRequestButtons(
                modifier = Modifier.padding(horizontal = 16.dp, vertical = 16.dp),
                onDismiss = state.onDismiss,
                onClickActiveButton = state.onSend,
                activeButtonText = resourceReference(R.string.common_send),
                isLoading = state.isLoading,
                enabled = state.sendEnabled,
                walletInteractionIcon = state.walletInteractionIcon,
                validationResult = state.transactionValidationResult,
                isHoldToConfirmEnabled = state.isHoldToConfirmEnabled,
            )
        },
    )
}

@Composable
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun WcSendTransactionBottomSheetPreview(
    @PreviewParameter(WcSendTransactionStateProvider::class) state: WcSendTransactionItemUM,
) {
    TangemThemePreview {
        TangemModalBottomSheet<WcSendTransactionItemUM>(
            config = TangemBottomSheetConfig(
                isShown = true,
                onDismissRequest = {},
                content = state,
            ),
            containerColor = TangemTheme.colors.background.tertiary,
            title = {
                TangemModalBottomSheetTitle(
                    title = resourceReference(R.string.wallet_connect_title),
                    endIconRes = R.drawable.ic_close_24,
                    onEndClick = {},
                    startIconRes = null,
                    onStartClick = {},
                )
            },
            content = {
                WcSendTransactionModalBottomSheet(
                    state = state,
                    feeSelectorBlockComponent = PreviewFeeSelectorBlockComponent(),
                    onClickTransactionRequest = {},
                    onBack = {},
                    onDismiss = {},
                    onClickAllowToSpend = {},
                    feeSelectorUM = FeeSelectorUM.Loading,
                )
            },
        )
    }
}

private class WcSendTransactionStateProvider : CollectionPreviewParameterProvider<WcSendTransactionItemUM>(
    listOf(
        WcSendTransactionItemUM(
            onDismiss = {},
            onSend = {},
            appInfo = WcTransactionAppInfoContentUM(
                appName = "React App React App ReactApp ReactApp ReactApp",
                appIcon = "",
                verifiedState = VerifiedDAppState.Unknown,
                appSubtitle = "react-app.walletconnect.com",
            ),
            estimatedWalletChanges = WcSendReceiveTransactionCheckResultsUM(
                notification = BlockAidNotificationUM(
                    type = BlockAidNotificationUM.Type.ERROR,
                    title = TextReference.Res(R.string.wc_malicious_transaction),
                    text = TextReference.Str("The transaction approves erc20 tokens to a known malicious address"),
                ),
                estimatedWalletChanges = WcEstimatedWalletChangesUM(
                    items = persistentListOf(
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_send_new_24,
                            title = resourceReference(R.string.common_send),
                            description = "- 42 USDT",
                            tokenIconUrl = "https://tangem.com",
                        ),
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_receive_new_24,
                            title = resourceReference(R.string.common_receive),
                            description = "+ 1,131.46 MATIC",
                            tokenIconUrl = "https://tangem.com",
                        ),
                    ),
                ),
                isLoading = false,
            ),
            portfolioName = accountPortfolioName,
            networkInfo = WcNetworkInfoUM(name = "Optimistic Ethereum Network", iconRes = R.drawable.img_eth_22),
            feeState = WcTransactionFeeState.Success(dAppFee = null, onClick = {}),
            address = null,
            sendEnabled = true,
            feeErrorNotification = null,
            transactionValidationResult = null,
        ),
        WcSendTransactionItemUM(
            onDismiss = {},
            onSend = {},
            appInfo = WcTransactionAppInfoContentUM(
                appName = "React App React App React App React App React App",
                appIcon = "",
                verifiedState = VerifiedDAppState.Verified {},
                appSubtitle = "react-app.walletconnect.com",
            ),
            estimatedWalletChanges = WcSendReceiveTransactionCheckResultsUM(
                notification = BlockAidNotificationUM(
                    type = BlockAidNotificationUM.Type.ERROR,
                    title = TextReference.Res(R.string.wc_malicious_transaction),
                    text = TextReference.Str("The transaction approves erc20 tokens to a known malicious address"),
                ),
                estimatedWalletChanges = WcEstimatedWalletChangesUM(
                    items = persistentListOf(
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_send_new_24,
                            title = resourceReference(R.string.common_send),
                            description = "- 42 USDT",
                            tokenIconUrl = "https://tangem.com",
                        ),
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_receive_new_24,
                            title = resourceReference(R.string.common_receive),
                            description = "+ 1,131.46 MATIC",
                            tokenIconUrl = "https://tangem.com",
                        ),
                    ),
                ),
            ),
            portfolioName = walletPortfolioName,
            networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
            feeState = WcTransactionFeeState.Success(dAppFee = null, onClick = {}),
            address = "0xdac17f958d2ee523a2206206994597c13d831ec7",
            sendEnabled = true,
            feeErrorNotification = NotificationUM.Info(
                title = stringReference("Insufficient Ethereum"),
                subtitle = stringReference("Top up your balance to cover the network fee"),
            ),
            transactionValidationResult = ValidationResult.WARNING,
        ),
        WcSendTransactionItemUM(
            onDismiss = {},
            onSend = {},
            appInfo = WcTransactionAppInfoContentUM(
                appName = "React App",
                appIcon = "",
                verifiedState = VerifiedDAppState.Verified {},
                appSubtitle = "react-app.walletconnect.com",
            ),
            estimatedWalletChanges = WcSendReceiveTransactionCheckResultsUM(
                notification = BlockAidNotificationUM(
                    type = BlockAidNotificationUM.Type.ERROR,
                    title = TextReference.Res(R.string.wc_malicious_transaction),
                    text = TextReference.Str("The transaction approves erc20 tokens to a known malicious address"),
                ),
                estimatedWalletChanges = WcEstimatedWalletChangesUM(
                    items = persistentListOf(
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_send_new_24,
                            title = resourceReference(R.string.common_send),
                            description = "- 42 USDT",
                            tokenIconUrl = "https://tangem.com",
                        ),
                        WcEstimatedWalletChangeUM(
                            iconRes = R.drawable.ic_receive_new_24,
                            title = resourceReference(R.string.common_receive),
                            description = "+ 1,131.46 MATIC",
                            tokenIconUrl = "https://tangem.com",
                        ),
                    ),
                ),
            ),
            portfolioName = null,
            networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
            feeState = WcTransactionFeeState.None,
            address = null,
            sendEnabled = false,
            feeErrorNotification = NotificationUM.Info(
                title = resourceReference(R.string.send_fee_unreachable_error_title),
                subtitle = resourceReference(R.string.send_fee_unreachable_error_text),
                buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
                    text = resourceReference(R.string.warning_button_refresh),
                    onClick = {},
                ),
            ),
            transactionValidationResult = ValidationResult.SAFE,
        ),
        WcSendTransactionItemUM(
            onDismiss = {},
            onSend = {},
            appInfo = WcTransactionAppInfoContentUM(
                appName = "React App",
                appIcon = "",
                verifiedState = VerifiedDAppState.Verified {},
                appSubtitle = "react-app.walletconnect.com",
            ),
            estimatedWalletChanges = WcSendReceiveTransactionCheckResultsUM(
                isLoading = false,
                spendAllowance = WcSpendAllowanceUM(
                    amountValue = BigDecimal.ZERO,
                    isUnlimited = false,
                    amountText = stringReference("0.00 WPOL"),
                    tokenSymbol = "",
                    tokenImageUrl = "",
                    networkIconRes = 0,
                    onLearnMoreClicked = {},
                ),
            ),
            portfolioName = accountPortfolioName,
            networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
            feeState = WcTransactionFeeState.None,
            address = "0xdac17f958d2ee523a2206206994597c13d831ec7",
            sendEnabled = true,
            feeErrorNotification = null,
            transactionValidationResult = ValidationResult.SAFE,
        ),
    ),
)