package com.rosetta.messenger.ui.chats

import android.content.Context
import android.net.Uri
import android.app.Activity
import android.view.inputmethod.InputMethodManager
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
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.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
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.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.rosetta.messenger.R
import com.rosetta.messenger.data.GroupRepository
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.database.DialogDao
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.network.GroupStatus
import com.rosetta.messenger.network.SearchUser
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.components.VerifiedBadge
import com.rosetta.messenger.ui.components.AppleEmojiTextField
import com.rosetta.messenger.ui.components.KeyboardHeightProvider
import com.rosetta.messenger.ui.components.OptimizedEmojiPicker
import com.rosetta.messenger.ui.components.AppleEmojiText
import com.rosetta.messenger.ui.components.AvatarImage
import com.rosetta.messenger.ui.icons.TelegramIcons
import com.rosetta.messenger.utils.AvatarFileManager
import com.rosetta.messenger.utils.ImageCropHelper
import com.rosetta.messenger.ui.settings.ProfilePhotoPicker
import app.rosette.android.ui.keyboard.AnimatedKeyboardTransition
import app.rosette.android.ui.keyboard.rememberKeyboardTransitionCoordinator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private enum class GroupSetupStep {
    MEMBERS,
    DETAILS,
    DESCRIPTION
}

@Composable
@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class)
fun GroupSetupScreen(
    isDarkTheme: Boolean,
    accountPublicKey: String,
    accountPrivateKey: String,
    accountName: String,
    accountUsername: String,
    messageRepository: MessageRepository,
    groupRepository: GroupRepository,
    avatarRepository: AvatarRepository? = null,
    dialogDao: DialogDao? = null,
    onBack: () -> Unit,
    onGroupOpened: (SearchUser) -> Unit
) {
    val scope = rememberCoroutineScope()
    val context = LocalContext.current
    val view = LocalView.current
    val focusManager = LocalFocusManager.current
    val keyboardController = LocalSoftwareKeyboardController.current
    val nameFocusRequester = remember { FocusRequester() }

    var step by rememberSaveable { mutableStateOf(GroupSetupStep.MEMBERS) }
    var title by rememberSaveable { mutableStateOf("") }
    var description by rememberSaveable { mutableStateOf("") }

    // Members selection state
    var memberSearchQuery by rememberSaveable { mutableStateOf("") }
    var selectedMembers by remember { mutableStateOf<List<SearchUser>>(emptyList()) }
    var allContacts by remember { mutableStateOf<List<SearchUser>>(emptyList()) }
    val memberSearchFocusRequester = remember { FocusRequester() }

    // Load contacts from database
    val resolvedDialogDao = dialogDao ?: remember(context) {
        RosettaDatabase.getDatabase(context).dialogDao()
    }
    LaunchedEffect(accountPublicKey) {
        withContext(Dispatchers.IO) {
            val dialogs = resolvedDialogDao.getDialogsPaged(accountPublicKey, limit = 200, offset = 0)
            allContacts = dialogs
                .filter { dialog ->
                    val key = dialog.opponentKey.lowercase()
                    !key.startsWith("#group:") && !key.startsWith("group:") &&
                    dialog.opponentKey != accountPublicKey &&
                    dialog.opponentKey != "0x000000000000000000000000000000000000000001" &&
                    dialog.opponentKey != "0x000000000000000000000000000000000000000002"
                }
                .map { dialog ->
                    SearchUser(
                        publicKey = dialog.opponentKey,
                        title = dialog.opponentTitle,
                        username = dialog.opponentUsername,
                        verified = dialog.verified,
                        online = dialog.isOnline
                    )
                }
        }
    }

    val filteredContacts = remember(allContacts, memberSearchQuery) {
        if (memberSearchQuery.isBlank()) allContacts
        else {
            val q = memberSearchQuery.lowercase()
            allContacts.filter { user ->
                user.title.lowercase().contains(q) ||
                user.username.lowercase().contains(q)
            }
        }
    }
    var selectedAvatarUri by rememberSaveable { mutableStateOf<String?>(null) }
    var isLoading by rememberSaveable { mutableStateOf(false) }
    var errorText by rememberSaveable { mutableStateOf<String?>(null) }
    var showEmojiKeyboard by rememberSaveable { mutableStateOf(false) }
    var showPhotoPicker by rememberSaveable { mutableStateOf(false) }
    val coordinator = rememberKeyboardTransitionCoordinator()
    var lastToggleTime by remember { mutableLongStateOf(0L) }
    val toggleCooldownMs = 500L

    val cropLauncher =
        rememberLauncherForActivityResult(
            contract = ActivityResultContracts.StartActivityForResult()
        ) { result ->
            val croppedUri = ImageCropHelper.getCroppedImageUri(result)
            val cropError = ImageCropHelper.getCropError(result)
            if (croppedUri != null) {
                selectedAvatarUri = croppedUri.toString()
            } else if (cropError != null) {
                android.widget.Toast
                    .makeText(context, "Failed to crop photo", android.widget.Toast.LENGTH_SHORT)
                    .show()
            }
        }

    val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFF2F2F7)
    val topSurfaceColor = if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFF228BE6)
    val cardColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color.White
    val sectionColor = if (isDarkTheme) Color(0xFF222224) else Color.White
    val primaryTextColor = if (isDarkTheme) Color.White else Color.Black
    val secondaryTextColor = Color(0xFF8E8E93)
    val accentColor = if (isDarkTheme) Color(0xFF5AA5FF) else Color(0xFF228BE6)
    val disabledActionColor = if (isDarkTheme) Color(0xFF5A5A5E) else Color(0xFFC7C7CC)
    val disabledActionContentColor = if (isDarkTheme) Color(0xFFAAAAAF) else Color(0xFF8E8E93)
    val groupAvatarCameraButtonColor =
        if (isDarkTheme) sectionColor else accentColor
    val groupAvatarCameraIconColor =
        if (isDarkTheme) accentColor else Color.White

    androidx.compose.runtime.DisposableEffect(topSurfaceColor, view) {
        val window = (view.context as? Activity)?.window
        if (window == null) {
            onDispose { }
        } else {
            val controller = WindowCompat.getInsetsController(window, view)
            val previousColor = window.statusBarColor
            val previousLightIcons = controller.isAppearanceLightStatusBars

            window.statusBarColor = topSurfaceColor.toArgb()
            controller.isAppearanceLightStatusBars = false

            onDispose {
                window.statusBarColor = previousColor
                controller.isAppearanceLightStatusBars = previousLightIcons
            }
        }
    }

    val normalizedUsername = remember(accountUsername) {
        accountUsername.trim().trimStart('@')
    }
    val selfTitle =
        remember(accountName, normalizedUsername, accountPublicKey) {
            accountName.trim()
                .ifBlank { normalizedUsername }
                .ifBlank { shortPublicKey(accountPublicKey) }
        }
    val selfSubtitle = "online"

    fun openGroup(dialogPublicKey: String, groupTitle: String) {
        onGroupOpened(
            SearchUser(
                publicKey = dialogPublicKey,
                title = groupTitle.ifBlank { "Group" },
                username = "",
                verified = 0,
                online = 0
            )
        )
    }

    suspend fun createGroup() =
        groupRepository.createGroup(
            accountPublicKey = accountPublicKey,
            accountPrivateKey = accountPrivateKey,
            title = title.trim(),
            description = description.trim()
        )

    fun mapError(status: GroupStatus, fallback: String): String {
        return when (status) {
            GroupStatus.BANNED -> "You are banned in this group"
            GroupStatus.INVALID -> "Invite is invalid"
            else -> fallback
        }
    }

    fun dismissInputUi() {
        if (showEmojiKeyboard || coordinator.isEmojiVisible || coordinator.isEmojiBoxVisible) {
            coordinator.closeEmoji(hideEmoji = { showEmojiKeyboard = false })
        } else {
            showEmojiKeyboard = false
        }
        focusManager.clearFocus(force = true)
        keyboardController?.hide()
        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
        (context as? Activity)?.window?.let { window ->
            WindowCompat.getInsetsController(window, view).hide(WindowInsetsCompat.Type.ime())
        }
    }

    fun handleBack() {
        if (isLoading) return
        errorText = null
        when (step) {
            GroupSetupStep.DESCRIPTION -> step = GroupSetupStep.DETAILS
            GroupSetupStep.DETAILS -> step = GroupSetupStep.MEMBERS
            GroupSetupStep.MEMBERS -> {
                dismissInputUi()
                onBack()
            }
        }
    }

    BackHandler(onBack = ::handleBack)

    val canGoNext = title.trim().isNotEmpty()
    val canCreate = canGoNext && !isLoading
    val actionEnabled = when (step) {
        GroupSetupStep.MEMBERS -> true
        GroupSetupStep.DETAILS -> canGoNext
        GroupSetupStep.DESCRIPTION -> canCreate
    }
    val density = LocalDensity.current
    val imeBottomPx = WindowInsets.ime.getBottom(density)
    val imeBottomDp = with(density) { imeBottomPx.toDp() }

    LaunchedEffect(step) {
        if (step != GroupSetupStep.DETAILS) {
            if (showEmojiKeyboard || coordinator.isEmojiVisible || coordinator.isEmojiBoxVisible) {
                coordinator.closeEmoji(hideEmoji = { showEmojiKeyboard = false })
            }
        }
        if (step == GroupSetupStep.MEMBERS) {
            delay(120)
            memberSearchFocusRequester.requestFocus()
            keyboardController?.show()
        }
        if (step == GroupSetupStep.DETAILS) {
            delay(120)
            nameFocusRequester.requestFocus()
            keyboardController?.show()
        }
    }

    LaunchedEffect(Unit) {
        val savedPx = KeyboardHeightProvider.getSavedKeyboardHeight(context)
        if (savedPx > 0) {
            coordinator.initializeEmojiHeight(with(density) { savedPx.toDp() })
        }
    }

    var lastStableKeyboardHeight by remember { mutableStateOf(0.dp) }
    var isKeyboardVisible by remember { mutableStateOf(false) }
    LaunchedEffect(imeBottomPx) {
        val currentImeHeight = with(density) { imeBottomPx.toDp() }
        coordinator.updateKeyboardHeight(currentImeHeight)
        isKeyboardVisible = currentImeHeight > 50.dp
        if (currentImeHeight > 100.dp) {
            coordinator.syncHeights()
            lastStableKeyboardHeight = currentImeHeight
        }
    }

    // Save keyboard height for emoji picker sync
    LaunchedEffect(isKeyboardVisible, showEmojiKeyboard) {
        if (isKeyboardVisible && !showEmojiKeyboard) {
            kotlinx.coroutines.delay(350)
            if (isKeyboardVisible && !showEmojiKeyboard && lastStableKeyboardHeight > 300.dp) {
                val heightPx = with(density) { lastStableKeyboardHeight.toPx().toInt() }
                KeyboardHeightProvider.saveKeyboardHeight(context, heightPx)
            }
        }
    }

    fun toggleEmojiPicker() {
        val now = System.currentTimeMillis()
        if (now - lastToggleTime < toggleCooldownMs || step != GroupSetupStep.DETAILS || isLoading) return
        lastToggleTime = now

        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        if (coordinator.isEmojiVisible) {
            coordinator.requestShowKeyboard(
                showKeyboard = {
                    nameFocusRequester.requestFocus()
                    keyboardController?.show()
                    @Suppress("DEPRECATION")
                    imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
                },
                hideEmoji = { showEmojiKeyboard = false }
            )
            return
        }

        if (imeBottomPx > 0) {
            coordinator.requestShowEmoji(
                hideKeyboard = {
                    imm.hideSoftInputFromWindow(view.windowToken, 0)
                    keyboardController?.hide()
                },
                showEmoji = {
                    focusManager.clearFocus(force = true)
                    showEmojiKeyboard = true
                }
            )
            return
        }

        if (coordinator.emojiHeight == 0.dp) {
            val fallbackHeight = if (lastStableKeyboardHeight > 0.dp) {
                lastStableKeyboardHeight
            } else {
                with(density) { KeyboardHeightProvider.getSavedKeyboardHeight(context).toDp() }
            }
            coordinator.initializeEmojiHeight(fallbackHeight)
        }

        coordinator.openEmojiOnly(
            showEmoji = {
                focusManager.clearFocus(force = true)
                showEmojiKeyboard = true
            }
        )
    }

    LaunchedEffect(Unit) {
        if (step == GroupSetupStep.MEMBERS) {
            delay(120)
            memberSearchFocusRequester.requestFocus()
            keyboardController?.show()
        } else if (step == GroupSetupStep.DETAILS) {
            delay(120)
            nameFocusRequester.requestFocus()
            keyboardController?.show()
        }
    }

    Scaffold(
        containerColor = backgroundColor,
        topBar = {
            TopAppBar(
                title = {
                    Column {
                        Text(
                            text = when (step) {
                                GroupSetupStep.MEMBERS -> "New Group"
                                GroupSetupStep.DETAILS -> "New Group"
                                GroupSetupStep.DESCRIPTION -> "Group Description"
                            },
                            fontWeight = FontWeight.SemiBold,
                            color = Color.White,
                            fontSize = 20.sp
                        )
                        if (step == GroupSetupStep.MEMBERS) {
                            val countText = if (selectedMembers.isEmpty()) "up to 200 members"
                                else "${selectedMembers.size} of 200 selected"
                            Text(
                                text = countText,
                                color = Color.White.copy(alpha = 0.7f),
                                fontSize = 13.sp
                            )
                        }
                    }
                },
                navigationIcon = {
                    IconButton(onClick = ::handleBack) {
                        Icon(
                            painter = TelegramIcons.ArrowBack,
                            contentDescription = "Back",
                            tint = Color.White
                        )
                    }
                },
                colors =
                    TopAppBarDefaults.topAppBarColors(
                        containerColor = topSurfaceColor,
                        titleContentColor = Color.White,
                        navigationIconContentColor = Color.White
                    )
            )
        },
        bottomBar = {
            if (step == GroupSetupStep.DETAILS) {
                AnimatedKeyboardTransition(
                    coordinator = coordinator,
                    showEmojiPicker = showEmojiKeyboard
                ) {
                    OptimizedEmojiPicker(
                        isVisible = true,
                        isDarkTheme = isDarkTheme,
                        onEmojiSelected = { emojiCode ->
                            val emoji = decodeEmojiCodeToUnicode(emojiCode)
                            title = (title + emoji).take(80)
                        },
                        onClose = { toggleEmojiPicker() },
                        modifier = Modifier.fillMaxWidth()
                    )
                }
            }
        }
    ) { paddingValues ->
        // Outer Box fills the full Scaffold area (no paddingValues applied)
        // so the FAB can be positioned consistently above *any* keyboard.
        Box(modifier = Modifier.fillMaxSize()) {
            // Content area respects Scaffold padding (topBar + bottomBar/emoji)
            Column(
                modifier =
                    Modifier
                        .fillMaxSize()
                        .padding(paddingValues)
                        .navigationBarsPadding()
            ) {
                if (step == GroupSetupStep.MEMBERS) {
                    // Search bar
                    TextField(
                        value = memberSearchQuery,
                        onValueChange = { memberSearchQuery = it },
                        modifier = Modifier
                            .fillMaxWidth()
                            .focusRequester(memberSearchFocusRequester),
                        placeholder = {
                            Text(
                                text = "Who would you like to add?",
                                color = secondaryTextColor,
                                fontSize = 15.sp
                            )
                        },
                        textStyle = MaterialTheme.typography.bodyLarge.copy(
                            color = primaryTextColor,
                            fontSize = 15.sp
                        ),
                        singleLine = true,
                        colors = TextFieldDefaults.colors(
                            focusedTextColor = primaryTextColor,
                            unfocusedTextColor = primaryTextColor,
                            focusedContainerColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color.White,
                            unfocusedContainerColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color.White,
                            focusedIndicatorColor = Color.Transparent,
                            unfocusedIndicatorColor = Color.Transparent,
                            cursorColor = accentColor
                        )
                    )

                    // Selected members chips
                    if (selectedMembers.isNotEmpty()) {
                        LazyRow(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(horizontal = 12.dp, vertical = 8.dp),
                            horizontalArrangement = Arrangement.spacedBy(8.dp)
                        ) {
                            items(selectedMembers, key = { it.publicKey }) { user ->
                                val chipName = user.title.ifEmpty { user.username.ifEmpty { user.publicKey.take(8) } }
                                Column(
                                    horizontalAlignment = Alignment.CenterHorizontally,
                                    modifier = Modifier
                                        .width(60.dp)
                                        .clickable {
                                            selectedMembers = selectedMembers.filter { it.publicKey != user.publicKey }
                                        }
                                ) {
                                    Box(contentAlignment = Alignment.BottomEnd) {
                                        AvatarImage(
                                            publicKey = user.publicKey,
                                            avatarRepository = avatarRepository,
                                            size = 46.dp,
                                            isDarkTheme = isDarkTheme,
                                            displayName = user.title.ifEmpty { user.username }
                                        )
                                        Box(
                                            modifier = Modifier
                                                .size(18.dp)
                                                .clip(CircleShape)
                                                .background(backgroundColor)
                                                .padding(1.dp)
                                                .clip(CircleShape)
                                                .background(secondaryTextColor.copy(alpha = 0.6f)),
                                            contentAlignment = Alignment.Center
                                        ) {
                                            Icon(
                                                painter = TelegramIcons.Close,
                                                contentDescription = "Remove",
                                                tint = Color.White,
                                                modifier = Modifier.size(10.dp)
                                            )
                                        }
                                    }
                                    Spacer(modifier = Modifier.height(4.dp))
                                    Text(
                                        text = chipName,
                                        fontSize = 11.sp,
                                        color = primaryTextColor,
                                        maxLines = 1,
                                        overflow = TextOverflow.Ellipsis,
                                        textAlign = TextAlign.Center
                                    )
                                }
                            }
                        }
                    }

                    // Divider
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(0.5.dp)
                            .background(secondaryTextColor.copy(alpha = 0.2f))
                    )

                    // Contact list
                    val listState = androidx.compose.foundation.lazy.rememberLazyListState()
                    LaunchedEffect(listState.isScrollInProgress) {
                        if (listState.isScrollInProgress) {
                            focusManager.clearFocus()
                            keyboardController?.hide()
                        }
                    }
                    LazyColumn(state = listState, modifier = Modifier.fillMaxSize()) {
                        items(filteredContacts, key = { it.publicKey }) { user ->
                            val isSelected = selectedMembers.any { it.publicKey == user.publicKey }
                            val displayName = user.title.ifEmpty {
                                user.username.ifEmpty { user.publicKey.take(8) + "..." }
                            }

                            Row(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .clickable {
                                        selectedMembers = if (isSelected) {
                                            selectedMembers.filter { it.publicKey != user.publicKey }
                                        } else {
                                            selectedMembers + user
                                        }
                                    }
                                    .padding(horizontal = 16.dp, vertical = 8.dp),
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                AvatarImage(
                                    publicKey = user.publicKey,
                                    avatarRepository = avatarRepository,
                                    size = 42.dp,
                                    isDarkTheme = isDarkTheme,
                                    showOnlineIndicator = false,
                                    isOnline = false,
                                    displayName = user.title.ifEmpty { user.username }
                                )

                                Spacer(modifier = Modifier.width(14.dp))

                                Column(modifier = Modifier.weight(1f)) {
                                    Row(verticalAlignment = Alignment.CenterVertically) {
                                        Text(
                                            text = displayName,
                                            fontSize = 16.sp,
                                            fontWeight = FontWeight.Medium,
                                            color = primaryTextColor,
                                            maxLines = 1,
                                            overflow = TextOverflow.Ellipsis
                                        )
                                        if (user.verified != 0) {
                                            Spacer(modifier = Modifier.width(4.dp))
                                            VerifiedBadge(
                                                verified = user.verified,
                                                size = 16
                                            )
                                        }
                                    }
                                    if (user.username.isNotEmpty()) {
                                        Text(
                                            text = "@${user.username}",
                                            fontSize = 14.sp,
                                            color = secondaryTextColor,
                                            maxLines = 1,
                                            overflow = TextOverflow.Ellipsis
                                        )
                                    }
                                }

                                // Checkmark
                                if (isSelected) {
                                    Box(
                                        modifier = Modifier
                                            .size(24.dp)
                                            .clip(CircleShape)
                                            .background(accentColor),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        Icon(
                                            painter = TelegramIcons.Done,
                                            contentDescription = "Selected",
                                            tint = Color.White,
                                            modifier = Modifier.size(14.dp)
                                        )
                                    }
                                }
                            }
                        }
                    }
                } else if (step == GroupSetupStep.DETAILS) {
                Column(modifier = Modifier.padding(horizontal = 16.dp)) {
                Spacer(modifier = Modifier.height(16.dp))

                Row(
                    modifier = Modifier.fillMaxWidth(),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Box(
                        contentAlignment = Alignment.Center,
                        modifier =
                            Modifier
                                .size(72.dp)
                    ) {
                        Box(
                            modifier =
                                Modifier
                                    .size(64.dp)
                                    .clip(CircleShape)
                                    .background(groupAvatarCameraButtonColor)
                                    .clickable(enabled = !isLoading) {
                                        showPhotoPicker = true
                                    },
                            contentAlignment = Alignment.Center
                        ) {
                            if (!selectedAvatarUri.isNullOrBlank()) {
                                AsyncImage(
                                    model =
                                        ImageRequest.Builder(context)
                                            .data(Uri.parse(selectedAvatarUri))
                                            .crossfade(true)
                                            .build(),
                                    contentDescription = "Group avatar",
                                    modifier = Modifier.fillMaxSize(),
                                    contentScale = ContentScale.Crop
                                )
                            } else {
                                Icon(
                                    painter = TelegramIcons.Camera,
                                    contentDescription = "Set group avatar",
                                    tint = groupAvatarCameraIconColor,
                                    modifier = Modifier.size(24.dp)
                                )
                            }
                        }
                    }

                    Spacer(modifier = Modifier.size(12.dp))

                    Column(modifier = Modifier.weight(1f)) {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            Box(modifier = Modifier.weight(1f)) {
                                AppleEmojiTextField(
                                    value = title,
                                    onValueChange = { newValue -> title = newValue.take(80) },
                                    textColor = primaryTextColor,
                                    textSize = 18f,
                                    hint = "Group name",
                                    hintColor = secondaryTextColor.copy(alpha = 0.88f),
                                    modifier =
                                        Modifier
                                            .fillMaxWidth()
                                            .focusRequester(nameFocusRequester)
                                            .padding(vertical = 2.dp),
                                    onViewCreated = { editText ->
                                        editText.isSingleLine = true
                                        editText.maxLines = 1
                                        editText.setHorizontallyScrolling(true)
                                    },
                                    onFocusChanged = { hasFocus ->
                                        if (hasFocus &&
                                            showEmojiKeyboard &&
                                            !coordinator.isTransitioning
                                        ) {
                                            coordinator.closeEmoji(hideEmoji = { showEmojiKeyboard = false })
                                        }
                                    }
                                )
                            }

                            IconButton(
                                onClick = { toggleEmojiPicker() },
                                enabled = !isLoading
                            ) {
                                Icon(
                                    painter = if (showEmojiKeyboard || coordinator.isEmojiBoxVisible) {
                                        TelegramIcons.Keyboard
                                    } else {
                                        TelegramIcons.Smile
                                    },
                                    contentDescription = "Emoji",
                                    tint = secondaryTextColor,
                                    modifier = Modifier.size(22.dp)
                                )
                            }
                        }

                        Spacer(modifier = Modifier.height(6.dp))

                        Box(
                            modifier =
                                Modifier
                                    .fillMaxWidth()
                                    .height(2.dp)
                                    .background(accentColor.copy(alpha = 0.9f), RoundedCornerShape(1.dp))
                        )
                    }
                }

                Spacer(modifier = Modifier.height(22.dp))

                val totalMembers = 1 + selectedMembers.size
                Text(
                    text = "$totalMembers member${if (totalMembers > 1) "s" else ""}",
                    color = accentColor,
                    fontWeight = FontWeight.Medium,
                    fontSize = 15.sp,
                    modifier = Modifier.padding(start = 0.dp, bottom = 0.dp)
                )

                Spacer(modifier = Modifier.height(8.dp))

                // Self (admin)
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 0.dp, vertical = 8.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    AvatarImage(
                        publicKey = accountPublicKey,
                        avatarRepository = avatarRepository,
                        size = 42.dp,
                        isDarkTheme = isDarkTheme,
                        displayName = selfTitle
                    )

                    Spacer(modifier = Modifier.size(14.dp))

                    Column(
                        modifier = Modifier.weight(1f),
                        verticalArrangement = Arrangement.Center
                    ) {
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            horizontalArrangement = Arrangement.spacedBy(6.dp)
                        ) {
                            Text(
                                text = selfTitle,
                                color = primaryTextColor,
                                fontSize = 16.sp,
                                fontWeight = FontWeight.Medium,
                                maxLines = 1,
                                overflow = TextOverflow.Ellipsis
                            )
                            Icon(
                                painter = painterResource(id = R.drawable.ic_arrow_badge_down_filled),
                                contentDescription = "Admin",
                                tint = Color(0xFFF6C445),
                                modifier = Modifier.size(14.dp)
                            )
                        }
                        Spacer(modifier = Modifier.height(2.dp))
                        Text(
                            text = selfSubtitle,
                            color = secondaryTextColor,
                            fontSize = 13.sp
                        )
                    }
                }

                // Separator after self
                if (selectedMembers.isNotEmpty()) {
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(start = 56.dp)
                            .height(0.5.dp)
                            .background(secondaryTextColor.copy(alpha = 0.25f))
                    )
                }

                // Selected members
                selectedMembers.forEachIndexed { index, member ->
                    val memberName = member.title.ifEmpty {
                        member.username.ifEmpty { member.publicKey.take(8) + "..." }
                    }
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(horizontal = 0.dp, vertical = 8.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        AvatarImage(
                            publicKey = member.publicKey,
                            avatarRepository = avatarRepository,
                            size = 42.dp,
                            isDarkTheme = isDarkTheme,
                            displayName = member.title.ifEmpty { member.username }
                        )

                        Spacer(modifier = Modifier.size(14.dp))

                        Column(
                            modifier = Modifier.weight(1f),
                            verticalArrangement = Arrangement.Center
                        ) {
                            Row(
                                verticalAlignment = Alignment.CenterVertically,
                                horizontalArrangement = Arrangement.spacedBy(4.dp)
                            ) {
                                Text(
                                    text = memberName,
                                    color = primaryTextColor,
                                    fontSize = 16.sp,
                                    fontWeight = FontWeight.Medium,
                                    maxLines = 1,
                                    overflow = TextOverflow.Ellipsis
                                )
                                if (member.verified != 0) {
                                    VerifiedBadge(verified = member.verified, size = 16)
                                }
                            }
                            if (member.username.isNotEmpty()) {
                                Spacer(modifier = Modifier.height(2.dp))
                                Text(
                                    text = "@${member.username}",
                                    color = secondaryTextColor,
                                    fontSize = 13.sp
                                )
                            }
                        }
                    }
                    // Separator between members
                    if (index < selectedMembers.lastIndex) {
                        Box(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(start = 56.dp)
                                .height(0.5.dp)
                                .background(secondaryTextColor.copy(alpha = 0.25f))
                        )
                    }
                }
                } // end DETAILS Column
                } else {
                Column(modifier = Modifier.padding(horizontal = 16.dp)) {
                Spacer(modifier = Modifier.height(16.dp))

                Row(
                    modifier =
                        Modifier
                            .fillMaxWidth()
                            .clip(RoundedCornerShape(14.dp))
                            .background(cardColor)
                            .padding(horizontal = 14.dp, vertical = 12.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Box(
                        modifier = Modifier.size(50.dp).clip(CircleShape).background(accentColor.copy(alpha = 0.2f)),
                        contentAlignment = Alignment.Center
                    ) {
                        if (!selectedAvatarUri.isNullOrBlank()) {
                            AsyncImage(
                                model =
                                    ImageRequest.Builder(context)
                                        .data(Uri.parse(selectedAvatarUri))
                                        .crossfade(true)
                                        .build(),
                                contentDescription = "Group avatar preview",
                                modifier = Modifier.fillMaxSize(),
                                contentScale = ContentScale.Crop
                            )
                        } else {
                            Icon(
                                painter = TelegramIcons.Photos,
                                contentDescription = null,
                                tint = accentColor,
                                modifier = Modifier.size(24.dp)
                            )
                        }
                    }

                    Spacer(modifier = Modifier.size(12.dp))

                    Column(modifier = Modifier.weight(1f)) {
                        AppleEmojiText(
                            text = title.trim(),
                            color = primaryTextColor,
                            fontSize = 16.sp,
                            fontWeight = FontWeight.Medium,
                            maxLines = 1,
                            overflow = android.text.TextUtils.TruncateAt.END,
                            enableLinks = false
                        )
                        Spacer(modifier = Modifier.height(2.dp))
                        Text(
                            text = "Add a description (optional)",
                            color = secondaryTextColor,
                            fontSize = 13.sp
                        )
                    }
                }

                Spacer(modifier = Modifier.height(16.dp))

                Text(
                    text = "Description",
                    color = secondaryTextColor,
                    fontWeight = FontWeight.Medium,
                    fontSize = 15.sp,
                    modifier = Modifier.padding(bottom = 8.dp)
                )

                TextField(
                    value = description,
                    onValueChange = { newValue -> description = newValue.take(400) },
                    modifier =
                        Modifier
                            .fillMaxWidth()
                            .height(150.dp)
                            .clip(RoundedCornerShape(14.dp))
                            .background(sectionColor),
                    minLines = 6,
                    maxLines = 8,
                    textStyle = MaterialTheme.typography.bodyLarge.copy(color = primaryTextColor, fontSize = 16.sp),
                    placeholder = {
                        Text(
                            text = "Group description",
                            color = secondaryTextColor,
                            fontSize = 16.sp
                        )
                    },
                    colors =
                        TextFieldDefaults.colors(
                            focusedTextColor = primaryTextColor,
                            unfocusedTextColor = primaryTextColor,
                            focusedContainerColor = sectionColor,
                            unfocusedContainerColor = sectionColor,
                            disabledContainerColor = sectionColor,
                            focusedIndicatorColor = Color.Transparent,
                            unfocusedIndicatorColor = Color.Transparent,
                            focusedPlaceholderColor = secondaryTextColor,
                            unfocusedPlaceholderColor = secondaryTextColor,
                            cursorColor = accentColor
                        )
                )

                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = "Description is optional. You can change it later in group info.",
                    color = secondaryTextColor,
                    fontSize = 13.sp,
                    textAlign = TextAlign.Start
                )
            } // end DESCRIPTION Column
            }

                if (!errorText.isNullOrBlank()) {
                    Spacer(modifier = Modifier.height(12.dp))
                    Text(
                        text = errorText.orEmpty(),
                        color = MaterialTheme.colorScheme.error,
                        style = MaterialTheme.typography.bodyMedium
                    )
                }
            }

            FloatingActionButton(
                elevation = androidx.compose.material3.FloatingActionButtonDefaults.elevation(0.dp, 0.dp, 0.dp, 0.dp),
                onClick = {
                    if (step == GroupSetupStep.MEMBERS) {
                        dismissInputUi()
                        memberSearchQuery = ""
                        step = GroupSetupStep.DETAILS
                        return@FloatingActionButton
                    }

                    if (step == GroupSetupStep.DETAILS) {
                        if (canGoNext) {
                            errorText = null
                            step = GroupSetupStep.DESCRIPTION
                        }
                        return@FloatingActionButton
                    }

                    if (!canCreate) return@FloatingActionButton

                    errorText = null
                    isLoading = true

                    scope.launch {
                        val result = withContext(Dispatchers.IO) { createGroup() }
                        if (result.success && !result.dialogPublicKey.isNullOrBlank()) {
                            withContext(Dispatchers.IO) {
                                persistLocalGroupAvatar(
                                    context = context,
                                    avatarRepository = avatarRepository,
                                    groupDialogPublicKey = result.dialogPublicKey,
                                    avatarUriString = selectedAvatarUri
                                )
                            }

                            // Send invite to all selected members
                            if (selectedMembers.isNotEmpty()) {
                                withContext(Dispatchers.IO) {
                                    val groupKey = groupRepository.getGroupKey(
                                        accountPublicKey, accountPrivateKey,
                                        result.dialogPublicKey
                                    )
                                    if (!groupKey.isNullOrBlank()) {
                                        val invite = groupRepository.constructInviteString(
                                            groupId = result.dialogPublicKey,
                                            title = result.title.ifBlank { title.trim() },
                                            encryptKey = groupKey,
                                            description = description.trim()
                                        )
                                        if (invite.isNotBlank()) {
                                            selectedMembers.forEach { member ->
                                                runCatching {
                                                    messageRepository.sendMessage(
                                                        toPublicKey = member.publicKey,
                                                        text = invite
                                                    )
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            dismissInputUi()
                            openGroup(
                                dialogPublicKey = result.dialogPublicKey,
                                groupTitle = result.title.ifBlank { title.trim() }
                            )
                        } else {
                            errorText = mapError(result.status, result.error ?: "Cannot create group")
                        }
                        isLoading = false
                    }
                },
                containerColor = if (actionEnabled) accentColor else disabledActionColor,
                contentColor = if (actionEnabled) Color.White else disabledActionContentColor,
                shape = CircleShape,
                modifier = run {
                    val navBarHeight = with(density) { WindowInsets.navigationBars.getBottom(density).toDp() }
                    val keyboardBottom = if (imeBottomDp > 0.dp) imeBottomDp + 14.dp else 0.dp
                    val emojiBottom = if (coordinator.isEmojiBoxVisible && coordinator.emojiHeight > 0.dp) coordinator.emojiHeight + 14.dp else 0.dp
                    val fabBottom = maxOf(keyboardBottom, emojiBottom, navBarHeight + 18.dp)
                    Modifier
                        .align(Alignment.BottomEnd)
                        .padding(end = 16.dp, bottom = fabBottom)
                        .size(58.dp)
                }
            ) {
                if (isLoading && step == GroupSetupStep.DESCRIPTION) {
                    CircularProgressIndicator(
                        color = if (actionEnabled) Color.White else disabledActionContentColor,
                        strokeWidth = 2.dp,
                        modifier = Modifier.size(22.dp)
                    )
                } else {
                    Icon(
                        painter = TelegramIcons.Done,
                        contentDescription = "Continue"
                    )
                }
            }
        }
    }

    ProfilePhotoPicker(
        isVisible = showPhotoPicker,
        onDismiss = { showPhotoPicker = false },
        onPhotoSelected = { uri ->
            showPhotoPicker = false
            val cropIntent = ImageCropHelper.createCropIntent(context, uri, isDarkTheme)
            cropLauncher.launch(cropIntent)
        },
        isDarkTheme = isDarkTheme
    )
}

private suspend fun persistLocalGroupAvatar(
    context: android.content.Context,
    avatarRepository: AvatarRepository?,
    groupDialogPublicKey: String,
    avatarUriString: String?
) {
    val repository = avatarRepository ?: return
    val safeUri = avatarUriString?.takeIf { it.isNotBlank() } ?: return

    val uri = runCatching { Uri.parse(safeUri) }.getOrNull() ?: return
    val rawBytes =
        runCatching {
            context.contentResolver.openInputStream(uri)?.use { stream -> stream.readBytes() }
        }.getOrNull() ?: return

    if (rawBytes.isEmpty()) return

    val preparedBase64 = AvatarFileManager.imagePrepareForNetworkTransfer(context, rawBytes)
    if (preparedBase64.isBlank()) return

    repository.saveAvatar(
        fromPublicKey = groupDialogPublicKey,
        base64Image = "data:image/png;base64,$preparedBase64"
    )
}

private fun decodeEmojiCodeToUnicode(value: String): String {
    val match = Regex("^:emoji_([a-fA-F0-9_-]+):$").matchEntire(value) ?: return value
    val codePoints =
        match.groupValues[1]
            .split("-")
            .mapNotNull { code -> code.toIntOrNull(16) }

    if (codePoints.isEmpty()) return value
    return String(codePoints.toIntArray(), 0, codePoints.size)
}

private fun shortPublicKey(publicKey: String): String {
    val normalized = publicKey.trim()
    return if (normalized.length <= 12) normalized else "${normalized.take(6)}...${normalized.takeLast(4)}"
}
