Мне нужно сделать Margin на MaxiPaySubscriptionsListViewItem.MaxiPayAdditionalInfoData, если он находится в самом верху экрана, тоесть самый первый, то маржин 30 package ru.maxi.mobile.feature.maxiPay.ui.subscriptionsList

import android.Manifest
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.SimpleItemAnimator
import by.kirich1409.viewbindingdelegate.viewBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import ru.maxi.mobile.R
import ru.maxi.mobile.base.ui.MvvmBaseFragment
import ru.maxi.mobile.base.ui.manager.hideKeyboardOnOutEditableTouch
import ru.maxi.mobile.base.ui.manager.showSnackbar
import ru.maxi.mobile.common.utils.android.MarginItemDecoration
import ru.maxi.mobile.common.utils.android.permissions.PermissionManager
import ru.maxi.mobile.common.utils.android.permissions.model.OptionalPermission
import ru.maxi.mobile.common.utils.android.permissions.model.PermissionRequest
import ru.maxi.mobile.common.utils.android.permissions.model.PermissionState
import ru.maxi.mobile.common.utils.android.permissions.model.SinglePermissionRequestResult
import ru.maxi.mobile.core.navigation.parentRouter
import ru.maxi.mobile.databinding.FragmentMaxiPaySubscriptionsListBinding
import ru.maxi.mobile.feature.analytics.model.eventsource.SbpBankChooserEventSource
import ru.maxi.mobile.feature.maxiPay.MaxiPayScreens
import ru.maxi.mobile.feature.maxiPay.ui.subscriptionsList.model.MaxiPaySubscriptionListNavigationEvent
import ru.maxi.mobile.feature.maxiPay.ui.subscriptionsList.model.MaxiPaySubscriptionsListViewItem
import ru.maxi.mobile.feature.sbp.SbpScreens
import ru.maxi.mobile.feature.sbp.model.SbpBankChooserResult
import ru.maxi.mobile.feature.sbp.model.SbpSourceType
import ru.maxi.mobile.presentation.common.NegativeButton
import ru.maxi.mobile.presentation.common.PositiveButton
import ru.maxi.mobile.presentation.common.screens.CommonScreens
import ru.maxi.mobile.uikit.utils.lifecycleAwareLazy
import javax.inject.Inject
import ru.maxi.mobile.uikit.R as UIKitR

/**
 * [Fragment] экрана списка счетов Макси Pay
 */
@AndroidEntryPoint
class MaxiPaySubscriptionsListFragment : MvvmBaseFragment(R.layout.fragment_maxi_pay_subscriptions_list) {

    @Inject
    lateinit var permissionManager: PermissionManager

    private val viewModel by viewModels<MaxiPaySubscriptionsListViewModel>()

    private val viewBinding by viewBinding(FragmentMaxiPaySubscriptionsListBinding::bind)

    private var notificationsPermissionRequest: PermissionRequest<SinglePermissionRequestResult>? = null
    private var isNotificationsPermissionRequestInProgress = false

    private val adapter by lifecycleAwareLazy {
        MaxiPaySubscriptionsListAdapter(
            onSubscriptionClick = viewModel::onSubscriptionClick,
            onCreateSubscriptionClick = viewModel::onCreateSubscriptionClick,
            onEditMerchantClick = viewModel::onEditMerchantClick,
            paymentConfirmationActions = viewModel,
            onAdditionalInfoItemClick = viewModel::onAdditionalInfoItemClick,
        )
    }

    override val analyticsName: String = "_MaxiPaySubscriptionsListScreen"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            notificationsPermissionRequest = permissionManager.registerPermissionRequest(
                fragment = this,
                permission = OptionalPermission(Manifest.permission.POST_NOTIFICATIONS),
            )
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        with(viewBinding) {
            contentView.adapter = adapter
            contentView.addItemDecoration(
                MarginItemDecoration { itemPosition ->
                    val currItem = adapter.currentList.getOrNull(itemPosition)
                    val prevItem = adapter.currentList.getOrNull(itemPosition - 1)
                    val margin = when {
                        currItem is MaxiPaySubscriptionsListViewItem.MerchantHeader ->
                            resources.getDimension(UIKitR.dimen.std_margin)

                        currItem is MaxiPaySubscriptionsListViewItem.Title ->
                            resources.getDimension(UIKitR.dimen.std_half_margin)

                        currItem is MaxiPaySubscriptionsListViewItem.MaxiPayAdditionalInfoData &&
                            prevItem !is MaxiPaySubscriptionsListViewItem.MaxiPayAdditionalInfoData ->
                            resources.getDimension(UIKitR.dimen.std_double_margin)

                        else -> 0
                    }
                    return@MarginItemDecoration margin.toInt()
                },
            )
            (contentView.itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false
            keyboardManager.hideKeyboardOnOutEditableTouch(contentView)
        }

        with(viewLifecycleOwner) {
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    launch { viewModel.viewState.collect(::onViewStateChange) }
                    launch { viewModel.navigationEvent.collect(::onNavigationEvent) }
                    launch { viewModel.messageEvent.collect(notificationManager::showSnackbar) }
                    launch {
                        viewModel.blockingLoaderState.collect { isVisible ->
                            blockingLoaderManager.isShowing = isVisible
                        }
                    }
                }
            }
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.RESUMED) {
                    launch { viewModel.sseEvents.collect(viewModel::onSseEvent) }
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (!isNotificationsPermissionRequestInProgress) {
            viewModel.checkNotificationPermission()
        }
        isNotificationsPermissionRequestInProgress = false
    }

    private fun onViewStateChange(viewItems: List<MaxiPaySubscriptionsListViewItem>) {
        if (adapter.currentList.isEmpty() && !isNotificationsPermissionRequestInProgress) {
            viewModel.checkNotificationPermission()
        }
        adapter.submitList(viewItems)
    }

    private fun onNavigationEvent(event: MaxiPaySubscriptionListNavigationEvent) {
        when (event) {
            MaxiPaySubscriptionListNavigationEvent.OpenAboutScreen ->
                parentRouter.replaceScreen(MaxiPayScreens.AboutScreen())

            MaxiPaySubscriptionListNavigationEvent.LaunchNotificationsPermissionRequest ->
                notificationsPermissionRequest?.let {
                    isNotificationsPermissionRequestInProgress = true
                    it.launch(ignoreRationaleRequest = true) { result ->
                        when (result.permissionState) {
                            PermissionState.Granted -> {
                                viewModel.onNotificationsPermissionGranted()
                                isNotificationsPermissionRequestInProgress = false
                            }

                            PermissionState.Denied -> onNotificationPermissionDenied()

                            PermissionState.RequestRationale -> {
                                isNotificationsPermissionRequestInProgress = false
                            }
                        }
                    }
                }

            is MaxiPaySubscriptionListNavigationEvent.OpenBankChooserScreen -> {
                parentRouter.setResultListener(BANK_CHOOSER_RESULT_KEY) { data ->
                    val result = data as? SbpBankChooserResult ?: return@setResultListener
                    viewModel.onBankChooserResult(event.subscriptionUuid, result)
                }
                val screen = SbpScreens.BankChooserScreen(
                    paymentUri = event.paymentUri,
                    sbpSourceType = SbpSourceType.SUBSCRIBE,
                    resultKey = BANK_CHOOSER_RESULT_KEY,
                    eventSource = SbpBankChooserEventSource.MaxiPay,
                    merchantName = event.merchantName,
                )
                parentRouter.navigateTo(screen)
            }

            is MaxiPaySubscriptionListNavigationEvent.OpenEditMerchantSubscriptionsScreen -> {
                parentRouter.navigateTo(
                    MaxiPayScreens.EditMerchantSubscriptionsScreen(
                        merchantCode = event.merchantCode,
                    ),
                )
            }

            is MaxiPaySubscriptionListNavigationEvent.OpenFaqScreen -> {
                parentRouter.navigateTo(
                    MaxiPayScreens.FaqScreen(),
                )
            }

            MaxiPaySubscriptionListNavigationEvent.ShowAddOtherSubscriptionDialog ->
                dialogManager.showDialog(
                    title = getString(R.string.maxi_pay_add_other_subscription_dialog_title),
                    button = PositiveButton(),
                )

            MaxiPaySubscriptionListNavigationEvent.OpenAboutServiceScreen -> {
                Log.d("TESTING", "MaxiPaySubscriptionsListFragment onNavigationEvent.AboutServiceScreen")
                parentRouter.navigateTo(MaxiPayScreens.AboutServiceScreen())
            }
        }
    }

    private fun onNotificationPermissionDenied() {
        dialogManager.showConfirmDialog(
            title = getString(R.string.maxi_pay_payment_confirmation_block_dialog_title),
            message = getString(R.string.maxi_pay_payment_confirmation_block_dialog_description),
            positiveButton = PositiveButton(getString(R.string.maxi_pay_payment_confirmation_block_dialog_positive)) {
                parentRouter.navigateTo(CommonScreens.AppSystemSettingsScreen())
            },
            negativeButton = NegativeButton(getString(R.string.maxi_pay_payment_confirmation_block_dialog_negative)) {
                viewModel.onNotificationsPermissionDenied()
                isNotificationsPermissionRequestInProgress = false
            },
        )
    }

    private companion object {
        const val BANK_CHOOSER_RESULT_KEY = "MAXI_PAY_BANK_CHOOSER_RESULT"
    }
}