package ru.forbion.f7cloud.mobile.ui

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import com.google.firebase.messaging.FirebaseMessaging
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import ru.forbion.f7cloud.core.auth.AppLockStore
import ru.forbion.f7cloud.core.auth.AuthSession
import androidx.compose.runtime.collectAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import ru.forbion.f7cloud.core.network.LoginFlowClient
import ru.forbion.f7cloud.core.push.F7PushEvent
import ru.forbion.f7cloud.core.push.F7PushEventHub
import ru.forbion.f7cloud.core.push.F7PushRegistrar
import ru.forbion.f7cloud.core.designsystem.F7OverlayNavigationProvider
import ru.forbion.f7cloud.core.designsystem.F7AppMenuSheet
import ru.forbion.f7cloud.core.designsystem.F7AppScaffold
import ru.forbion.f7cloud.core.designsystem.F7AutoHideBottomBar
import ru.forbion.f7cloud.core.designsystem.F7BottomBarActions
import ru.forbion.f7cloud.core.designsystem.F7BottomBarConfig
import ru.forbion.f7cloud.core.designsystem.F7MobileBottomBar
import ru.forbion.f7cloud.core.designsystem.F7Colors
import ru.forbion.f7cloud.core.designsystem.F7Theme
import ru.forbion.f7cloud.core.designsystem.f7SafeTopInsets
import ru.forbion.f7cloud.mobile.OfficeEditorActivity
import ru.forbion.f7cloud.mobile.qr.F7QrScannerActivity
import ru.forbion.f7cloud.feature.files.OfficeWarmup
import ru.forbion.f7cloud.mobile.permissions.F7AppPermissions
import ru.forbion.f7cloud.mobile.permissions.F7PermissionRationaleDialog
import ru.forbion.f7cloud.feature.calendar.CalendarScreen
import ru.forbion.f7cloud.feature.contacts.ContactsScreen
import ru.forbion.f7cloud.feature.deck.DeckScreen
import ru.forbion.f7cloud.feature.files.FilesScreen
import ru.forbion.f7cloud.feature.f7support.SupportScreen
import ru.forbion.f7cloud.feature.mail.MailScreen
import ru.forbion.f7cloud.feature.tasks.TasksScreen
import ru.forbion.f7cloud.feature.talk.TalkScreen
import ru.forbion.f7cloud.mobile.navigation.AppLinkResolver
import ru.forbion.f7cloud.mobile.navigation.AppLinkTarget

@Composable
fun AppScaffold(
    openUrl: String? = null,
    onOpenUrlConsumed: () -> Unit = {},
    onRequestRuntimePermissions: (onFinished: (() -> Unit)?) -> Unit = {},
) {
    val context = LocalContext.current
    val mainVm: MainViewModel = viewModel()
    val session by mainVm.session.collectAsState()
    var activeTab by rememberSaveable(
        saver = Saver(
            save = { state -> state.value.name },
            restore = { name ->
                mutableStateOf(
                    if (name == "Widgets") AppTab.Files
                    else runCatching { AppTab.valueOf(name) }.getOrDefault(AppTab.Files),
                )
            },
        ),
    ) { mutableStateOf(AppTab.Files) }
    var pendingOpenUrl by rememberSaveable { mutableStateOf<String?>(null) }
    var pendingTalkRoomToken by rememberSaveable { mutableStateOf<String?>(null) }
    var pendingTalkMessageId by rememberSaveable { mutableStateOf<Long?>(null) }
    var pendingSupportTicket by rememberSaveable { mutableStateOf<String?>(null) }
    var pendingMailMessageId by rememberSaveable { mutableIntStateOf(-1) }
    var pendingMailMailboxId by rememberSaveable { mutableIntStateOf(-1) }
    var pendingCalendarEventUid by rememberSaveable { mutableStateOf<String?>(null) }
    var pendingDeckCardId by rememberSaveable { mutableIntStateOf(-1) }
    var pendingTasksListSlug by rememberSaveable { mutableStateOf<String?>(null) }
    var pendingFileId by rememberSaveable { mutableStateOf<Long?>(null) }
    var tabHistory by rememberSaveable { mutableStateOf(emptyList<String>()) }
    var menuOpen by rememberSaveable { mutableStateOf(false) }
    var talkInRoom by rememberSaveable { mutableStateOf(false) }
    var mailInMessage by rememberSaveable { mutableStateOf(false) }
    var bottomBarActivity by remember { mutableIntStateOf(0) }
    var lastBottomBarPulse by remember { mutableLongStateOf(0L) }
    var profileOpen by rememberSaveable { mutableStateOf(false) }
    var notificationsOpen by rememberSaveable { mutableStateOf(false) }
    var mailSidebarOpen by rememberSaveable { mutableStateOf(false) }
    var calendarSidebarOpen by rememberSaveable { mutableStateOf(false) }
    var filesSidebarOpen by rememberSaveable { mutableStateOf(false) }
    var mailSettingsOpen by rememberSaveable { mutableStateOf(false) }
    var filesSettingsOpen by rememberSaveable { mutableStateOf(false) }
    val bottomBarPinned = menuOpen || profileOpen || notificationsOpen ||
        (activeTab == AppTab.Mail && (mailSidebarOpen || mailSettingsOpen)) ||
        (activeTab == AppTab.Calendar && calendarSidebarOpen) ||
        (activeTab == AppTab.Files && (filesSidebarOpen || filesSettingsOpen))
    var filesUploadRequest by remember { mutableIntStateOf(0) }
    var contactsCreateRequest by remember { mutableIntStateOf(0) }
    var tasksCreateRequest by remember { mutableIntStateOf(0) }
    var supportCreateRequest by remember { mutableIntStateOf(0) }
    var calendarSettingsRequest by remember { mutableIntStateOf(0) }
    var talkChatsRequest by remember { mutableIntStateOf(0) }
    var mailPushRequest by remember { mutableIntStateOf(0) }
    var talkPushRequest by remember { mutableIntStateOf(0) }
    var filesPushRequest by remember { mutableIntStateOf(0) }
    var notificationsPushRequest by remember { mutableIntStateOf(0) }
    var pushTalkRoomToken by remember { mutableStateOf<String?>(null) }
    var hasNotificationBadge by rememberSaveable { mutableStateOf(false) }
    val permissionPrefs = remember {
        context.applicationContext.getSharedPreferences("f7_permissions", android.content.Context.MODE_PRIVATE)
    }

    val forceLogout = { mainVm.logout() }
    LaunchedEffect(session?.serverUrl, session?.username) {
        session?.let { OfficeWarmup.warm(it) }
    }
    LaunchedEffect(openUrl) {
        if (!openUrl.isNullOrBlank()) {
            pendingOpenUrl = openUrl
            onOpenUrlConsumed()
        }
    }

    F7Theme {
        if (session == null) {
            LoginScreen(onLogin = { mainVm.login(it) })
            return@F7Theme
        }

        val currentSession = session!!
        var externalMenuSites by remember { mutableStateOf<List<AppMenuExternalSite>>(emptyList()) }
        val appMenuItemsList = remember(currentSession.serverUrl, activeTab, externalMenuSites) {
            appMenuItems(currentSession.serverUrl, activeTab, externalMenuSites)
        }
        LaunchedEffect(menuOpen, currentSession.serverUrl, currentSession.username) {
            if (!menuOpen) return@LaunchedEffect
            externalMenuSites = withContext(Dispatchers.IO) {
                AppMenuRepository.fetchExternalSites(currentSession)
            }
        }
        val lockStore = remember { AppLockStore(context) }
        var showAppLockSetup by rememberSaveable { mutableStateOf(false) }
        var lockUnlockNonce by remember { mutableIntStateOf(0) }
        LaunchedEffect(currentSession.serverUrl, currentSession.username) {
            if (lockStore.shouldOfferSetup()) {
                showAppLockSetup = true
            }
        }
        AppLockSetupDialog(
            visible = showAppLockSetup,
            lockStore = lockStore,
            onDismiss = { showAppLockSetup = false },
            onLockConfigured = { lockUnlockNonce++ },
        )
        AppLockGate(lockStore = lockStore, unlockNonce = lockUnlockNonce) {
        fun applyAppLink(target: AppLinkTarget) {
            activeTab = target.tab
            pendingTalkRoomToken = target.talkRoomToken
            pendingTalkMessageId = target.talkMessageId
            pendingSupportTicket = target.supportTicket
            pendingMailMessageId = target.mailMessageId ?: -1
            pendingMailMailboxId = target.mailMailboxId ?: -1
            pendingCalendarEventUid = target.calendarEventUid
            pendingDeckCardId = target.deckCardId ?: -1
            pendingFileId = target.fileId
            pendingTasksListSlug = target.tasksListSlug
        }
        fun openAppLink(url: String) {
            AppLinkResolver.resolve(url, currentSession.serverUrl)?.let { applyAppLink(it) }
        }
        LaunchedEffect(pendingOpenUrl) {
            val url = pendingOpenUrl ?: return@LaunchedEffect
            openAppLink(url)
            pendingOpenUrl = null
        }
        val userId = currentSession.davUserId ?: currentSession.username
        val lifecycleOwner = LocalLifecycleOwner.current
        val scope = rememberCoroutineScope()
        var browserQrBusy by rememberSaveable { mutableStateOf(false) }

        val browserQrLauncher = rememberLauncherForActivityResult(
            ActivityResultContracts.StartActivityForResult(),
        ) { result ->
            if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
            val qrData = result.data?.getStringExtra(F7QrScannerActivity.RESULT_EXTRA)
                ?: return@rememberLauncherForActivityResult
            scope.launch {
                browserQrBusy = true
                val approved = LoginFlowClient.approveBrowserLoginFromQr(
                    qrData = qrData,
                    username = currentSession.username,
                    appPassword = currentSession.appPassword,
                    trustAllCerts = currentSession.trustAllCerts,
                )
                browserQrBusy = false
                val message = if (approved) {
                    "Браузер авторизован"
                } else {
                    "Не удалось подтвердить вход в браузере"
                }
                Toast.makeText(context.applicationContext, message, Toast.LENGTH_LONG).show()
            }
        }

        val browserQrCameraLauncher = rememberLauncherForActivityResult(
            ActivityResultContracts.RequestPermission(),
        ) { granted ->
            if (granted) {
                browserQrLauncher.launch(F7QrScannerActivity.intent(context))
            }
        }

        fun launchBrowserQrScan() {
            if (browserQrBusy) return
            if (androidx.core.content.ContextCompat.checkSelfPermission(
                    context,
                    android.Manifest.permission.CAMERA,
                ) == android.content.pm.PackageManager.PERMISSION_GRANTED
            ) {
                browserQrLauncher.launch(F7QrScannerActivity.intent(context))
            } else {
                browserQrCameraLauncher.launch(android.Manifest.permission.CAMERA)
            }
        }

        var showPermissionRationale by rememberSaveable { mutableStateOf(false) }
        var permissionFlowStarted by rememberSaveable { mutableStateOf(false) }

        fun registerFcmPush() {
            scope.launch(Dispatchers.IO) {
                runCatching {
                    val token = FirebaseMessaging.getInstance().token.await()
                    val code = F7PushRegistrar.registerBlocking(context, currentSession, token)
                    android.util.Log.i("F7Push", "AppScaffold register result: $code")
                }.onFailure {
                    android.util.Log.e("F7Push", "AppScaffold register failed", it)
                }
            }
        }

        fun startPermissionRequest() {
            permissionFlowStarted = true
            onRequestRuntimePermissions { registerFcmPush() }
        }

        DisposableEffect(lifecycleOwner, currentSession.serverUrl, currentSession.username) {
            val observer = LifecycleEventObserver { _, event ->
                if (event != Lifecycle.Event.ON_RESUME) return@LifecycleEventObserver
                if (permissionFlowStarted) return@LifecycleEventObserver
                if (F7AppPermissions.hasAll(context)) {
                    permissionFlowStarted = true
                    registerFcmPush()
                    return@LifecycleEventObserver
                }
                val alreadyPrompted = permissionPrefs.getBoolean(PERMISSIONS_PROMPTED_KEY, false)
                if (!alreadyPrompted) {
                    permissionFlowStarted = true
                    showPermissionRationale = true
                } else {
                    startPermissionRequest()
                }
            }
            lifecycleOwner.lifecycle.addObserver(observer)
            onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
        }

        F7PermissionRationaleDialog(
            visible = showPermissionRationale,
            onConfirm = {
                showPermissionRationale = false
                permissionPrefs.edit().putBoolean(PERMISSIONS_PROMPTED_KEY, true).apply()
                startPermissionRequest()
            },
            onDismiss = {
                showPermissionRationale = false
                permissionPrefs.edit().putBoolean(PERMISSIONS_PROMPTED_KEY, true).apply()
                registerFcmPush()
            },
        )

        LaunchedEffect(activeTab) {
            if (activeTab == AppTab.Talk && !F7AppPermissions.hasAll(context)) {
                delay(400)
                onRequestRuntimePermissions(null)
            }
        }

        LaunchedEffect(Unit) {
            F7PushEventHub.events.collect { event ->
                when (event) {
                    is F7PushEvent.Mail -> {
                        mailPushRequest++
                        event.messageId?.let { pendingMailMessageId = it }
                        event.mailboxId?.let { pendingMailMailboxId = it }
                    }
                    is F7PushEvent.Talk -> {
                        pushTalkRoomToken = event.roomToken
                        talkPushRequest++
                        event.messageId?.let { pendingTalkMessageId = it }
                        event.roomToken?.let { pendingTalkRoomToken = it }
                    }
                    is F7PushEvent.Files -> {
                        filesPushRequest++
                        event.fileId?.let { pendingFileId = it }
                    }
                    is F7PushEvent.Notification -> {
                        notificationsPushRequest++
                        hasNotificationBadge = true
                    }
                    is F7PushEvent.Call -> Unit
                }
            }
        }

        LaunchedEffect(activeTab) {
            if (activeTab != AppTab.Mail) {
                mailInMessage = false
            }
            if (activeTab != AppTab.Calendar) {
                calendarSidebarOpen = false
            }
        }

        LaunchedEffect(mailInMessage) {
            if (mailInMessage) {
                bottomBarActivity++
            }
        }

        val bottomBarConfig = remember(activeTab, talkInRoom) {
            F7BottomBarConfig.forContext(activeTab.name, talkInRoom)
        }

        fun pushTabHistory(from: AppTab) {
            tabHistory = (tabHistory + from.name).takeLast(20)
        }
        fun popTabHistory(): AppTab? {
            if (tabHistory.isEmpty()) return null
            val name = tabHistory.last()
            tabHistory = tabHistory.dropLast(1)
            return runCatching { AppTab.valueOf(name) }.getOrNull()
        }
        fun dismissSwipeOverlay(): Boolean {
            when {
                menuOpen -> menuOpen = false
                profileOpen -> profileOpen = false
                notificationsOpen -> notificationsOpen = false
                mailSettingsOpen -> mailSettingsOpen = false
                filesSettingsOpen -> filesSettingsOpen = false
                mailSidebarOpen -> mailSidebarOpen = false
                calendarSidebarOpen -> calendarSidebarOpen = false
                filesSidebarOpen -> filesSidebarOpen = false
                else -> return false
            }
            return true
        }

        BackHandler {
            when {
                menuOpen -> menuOpen = false
                profileOpen -> profileOpen = false
                notificationsOpen -> notificationsOpen = false
                mailSidebarOpen -> mailSidebarOpen = false
                calendarSidebarOpen -> calendarSidebarOpen = false
                filesSidebarOpen -> filesSidebarOpen = false
                mailSettingsOpen -> mailSettingsOpen = false
                filesSettingsOpen -> filesSettingsOpen = false
                else -> {
                    val previous = popTabHistory()
                    if (previous != null) {
                        activeTab = previous
                    } else {
                        (context as? Activity)?.moveTaskToBack(false)
                    }
                }
            }
        }

        F7OverlayNavigationProvider(
            onSwipeDismiss = ::dismissSwipeOverlay,
            modifier = Modifier.fillMaxSize(),
        ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .pointerInput(Unit) {
                    awaitEachGesture {
                        awaitFirstDown(pass = PointerEventPass.Initial)
                        val now = System.currentTimeMillis()
                        if (now - lastBottomBarPulse >= 800L) {
                            lastBottomBarPulse = now
                            bottomBarActivity++
                        }
                    }
                },
        ) {
            F7AppScaffold(
                bottomBar = {
                    if ((activeTab != AppTab.Talk || !talkInRoom)) {
                        F7AutoHideBottomBar(
                            enabled = true,
                            pinned = bottomBarPinned,
                            activityNonce = bottomBarActivity,
                            hideDelayMs = 4000L,
                        ) {
                            F7MobileBottomBar(
                            serverUrl = currentSession.serverUrl,
                            userId = userId,
                            config = bottomBarConfig,
                            activeTabKey = activeTab.name,
                            menuOpen = menuOpen,
                            chatsHighlighted = activeTab == AppTab.Talk && !talkInRoom,
                            navBackHighlighted = (activeTab == AppTab.Mail && mailSidebarOpen) ||
                                (activeTab == AppTab.Calendar && calendarSidebarOpen) ||
                                (activeTab == AppTab.Files && filesSidebarOpen),
                            showNotificationBadge = hasNotificationBadge,
                            actions = F7BottomBarActions(
                                onChatsClick = { talkChatsRequest++ },
                                onNavBackClick = {
                                    when (activeTab) {
                                        AppTab.Mail -> mailSidebarOpen = !mailSidebarOpen
                                        AppTab.Calendar -> calendarSidebarOpen = !calendarSidebarOpen
                                        AppTab.Files -> filesSidebarOpen = !filesSidebarOpen
                                        // Разделы без сайдбара (Карточки/Конференции/Контакты/Задачи/
                                        // Поддержка): стрелка = «назад» к предыдущему разделу.
                                        else -> popTabHistory()?.let { activeTab = it }
                                    }
                                },
                                onMailClick = {
                                    if (activeTab != AppTab.Mail) {
                                        pushTabHistory(activeTab)
                                        activeTab = AppTab.Mail
                                    }
                                },
                                onTasksClick = {
                                    if (activeTab != AppTab.Tasks) {
                                        pushTabHistory(activeTab)
                                        activeTab = AppTab.Tasks
                                    }
                                },
                                onConferencesClick = {
                                    if (activeTab != AppTab.Talk) {
                                        pushTabHistory(activeTab)
                                        activeTab = AppTab.Talk
                                    }
                                },
                                onMenuClick = { menuOpen = !menuOpen },
                            ),
                        )
                        }
                    }
                },
            ) { contentModifier ->
            when (activeTab) {
                AppTab.Mail -> MailScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    openMessageId = pendingMailMessageId.takeIf { it > 0 },
                    openMailboxId = pendingMailMailboxId.takeIf { it > 0 },
                    sidebarOpen = mailSidebarOpen,
                    onSidebarOpenChange = { mailSidebarOpen = it },
                    settingsOpen = mailSettingsOpen,
                    onSettingsOpenChange = { mailSettingsOpen = it },
                    pushRefreshRequest = mailPushRequest,
                    onOpenMessageConsumed = { pendingMailMessageId = -1; pendingMailMailboxId = -1 },
                    onMessageOpenStateChange = { mailInMessage = it },
                    onUnauthorized = forceLogout,
                )
                AppTab.Files -> FilesScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    uploadRequest = filesUploadRequest,
                    pushRefreshRequest = filesPushRequest,
                    openFileId = pendingFileId,
                    sidebarOpen = filesSidebarOpen,
                    onSidebarOpenChange = { filesSidebarOpen = it },
                    settingsOpen = filesSettingsOpen,
                    onSettingsOpenChange = { filesSettingsOpen = it },
                    onOpenFileConsumed = { pendingFileId = null },
                    onUnauthorized = forceLogout,
                    onOpenOfficeEditor = { launch ->
                        context.startActivity(OfficeEditorActivity.intent(context, launch))
                    },
                )
                AppTab.Calendar -> CalendarScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    focusEventUid = pendingCalendarEventUid,
                    settingsRequest = calendarSettingsRequest,
                    sidebarOpen = calendarSidebarOpen,
                    onSidebarOpenChange = { calendarSidebarOpen = it },
                    onFocusEventConsumed = { pendingCalendarEventUid = null },
                    onUnauthorized = forceLogout,
                )
                AppTab.Contacts -> ContactsScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    createRequest = contactsCreateRequest,
                    onUnauthorized = forceLogout,
                )
                AppTab.Talk -> {
                    val onTalkConsumed = {
                        pendingTalkRoomToken = null
                        pendingTalkMessageId = null
                    }
                    TalkScreen(
                        session = currentSession,
                        modifier = contentModifier,
                        openRoomToken = pendingTalkRoomToken,
                        scrollToMessageId = pendingTalkMessageId,
                        chatsListRequest = talkChatsRequest,
                        pushSyncRequest = talkPushRequest,
                        pushRoomToken = pushTalkRoomToken,
                        onOpenRoomConsumed = onTalkConsumed,
                        onRoomOpenStateChange = { talkInRoom = it },
                        onOpenCalendar = { activeTab = AppTab.Calendar },
                        onUnauthorized = forceLogout,
                    )
                }
                AppTab.Deck -> DeckScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    openCardId = pendingDeckCardId.takeIf { it > 0 },
                    onOpenCardConsumed = { pendingDeckCardId = -1 },
                    onUnauthorized = forceLogout,
                )
                AppTab.Tasks -> TasksScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    createRequest = tasksCreateRequest,
                    openListSlug = pendingTasksListSlug,
                    onOpenListConsumed = { pendingTasksListSlug = null },
                    onUnauthorized = forceLogout,
                )
                AppTab.Support -> SupportScreen(
                    session = currentSession,
                    modifier = contentModifier,
                    createRequest = supportCreateRequest,
                    openTicketNumber = pendingSupportTicket,
                    onOpenTicketConsumed = { pendingSupportTicket = null },
                    onUnauthorized = forceLogout,
                )
            }
            }
            F7AppMenuSheet(
                visible = menuOpen,
                serverUrl = currentSession.serverUrl,
                items = appMenuItemsList,
                onDismiss = { menuOpen = false },
                onItemClick = { index ->
                    val item = appMenuItemsList.getOrNull(index) ?: return@F7AppMenuSheet
                    val external = item.externalUrl
                    val label = item.label.trim()
                    when {
                        // Профиль — нативная панель вместо веб-ЛК forbion
                        label.equals("Личный кабинет", ignoreCase = true) -> {
                            menuOpen = false
                            profileOpen = true
                        }
                        // Нативные пункты по дизайну меню
                        label.equals("Уведомления", ignoreCase = true) -> {
                            menuOpen = false
                            hasNotificationBadge = false
                            notificationsOpen = true
                        }
                        label.equals("Настройки", ignoreCase = true) -> {
                            menuOpen = false
                            when (activeTab) {
                                AppTab.Mail -> mailSettingsOpen = true
                                AppTab.Calendar -> calendarSettingsRequest++
                                AppTab.Files -> filesSettingsOpen = true
                                else -> Unit
                            }
                        }
                        !external.isNullOrBlank() -> {
                            runCatching {
                                context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(external)))
                            }
                            menuOpen = false
                        }
                        else -> {
                            appTabFromMenuIndex(index)?.let { tab ->
                                if (tab != activeTab) {
                                    pushTabHistory(activeTab)
                                    activeTab = tab
                                }
                            }
                            menuOpen = false
                        }
                    }
                },
            )
            ProfileSheet(
                visible = profileOpen,
                session = currentSession,
                onDismiss = { profileOpen = false },
                onLogout = forceLogout,
                onScanBrowserQr = ::launchBrowserQrScan,
            )
            NotificationsSheet(
                visible = notificationsOpen,
                session = currentSession,
                refreshRequest = notificationsPushRequest,
                onDismiss = { notificationsOpen = false },
                onUnauthorized = forceLogout,
                onNotificationClick = { notification ->
                    openAppLink(notification.link)
                },
            )
        }
        }
        }
    }
}

private const val PERMISSIONS_PROMPTED_KEY = "runtime_permissions_prompted_v2"
