package com.rosetta.messenger.ui.chats.attach

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.view.inputmethod.InputMethodManager
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.rosetta.messenger.ui.chats.components.ThumbnailPosition
import com.rosetta.messenger.ui.components.AppleEmojiTextField
import com.rosetta.messenger.ui.icons.TelegramIcons
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
import compose.icons.TablerIcons
import compose.icons.tablericons.ChevronDown
import compose.icons.tablericons.ChevronLeft
import compose.icons.tablericons.PhotoOff
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

// ═══════════════════════════════════════════════════════════════
// Media Grid
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun MediaGrid(
    mediaItems: List<MediaItem>,
    selectedItemOrder: List<Long>,
    showCameraItem: Boolean = true,
    cameraEnabled: Boolean = true,
    gridState: LazyGridState = rememberLazyGridState(),
    onCameraClick: () -> Unit,
    onItemClick: (MediaItem, ThumbnailPosition) -> Unit,
    onItemCheckClick: (MediaItem) -> Unit,
    onItemLongClick: (MediaItem) -> Unit,
    isDarkTheme: Boolean,
    modifier: Modifier = Modifier
) {
    val selectionIndexById =
        remember(selectedItemOrder) {
            selectedItemOrder.withIndex().associate { (index, id) -> id to (index + 1) }
        }

    LazyVerticalGrid(
        columns = GridCells.Fixed(3),
        state = gridState,
        modifier = modifier.fillMaxWidth(),
        contentPadding = PaddingValues(4.dp),
        horizontalArrangement = Arrangement.spacedBy(4.dp),
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        if (showCameraItem) {
            item(key = "camera_button") {
                CameraGridItem(
                    onClick = onCameraClick,
                    enabled = cameraEnabled,
                    isDarkTheme = isDarkTheme
                )
            }
        }

        items(
            items = mediaItems,
            key = { it.id }
        ) { item ->
            val selectionIndex = selectionIndexById[item.id] ?: 0
            MediaGridItem(
                item = item,
                isSelected = selectionIndex > 0,
                selectionIndex = selectionIndex,
                onContentClick = { position -> onItemClick(item, position) },
                onCheckClick = { onItemCheckClick(item) },
                onLongClick = { onItemLongClick(item) },
                isDarkTheme = isDarkTheme
            )
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Camera Grid Item — live CameraX preview
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun CameraGridItem(
    onClick: () -> Unit,
    enabled: Boolean = true,
    isDarkTheme: Boolean
) {
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current
    val backgroundColor = if (isDarkTheme) Color(0xFF2C2C2E) else Color(0xFFF2F2F7)
    var cameraProvider by remember { mutableStateOf<ProcessCameraProvider?>(null) }
    var previewUseCase by remember { mutableStateOf<Preview?>(null) }

    val iconScale = remember { Animatable(0f) }
    LaunchedEffect(Unit) {
        iconScale.animateTo(
            targetValue = 1f,
            animationSpec = spring(dampingRatio = 0.5f, stiffness = 400f)
        )
    }

    var hasCameraPermission by remember {
        mutableStateOf(
            ContextCompat.checkSelfPermission(
                context, Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED
        )
    }

    LaunchedEffect(Unit) {
        hasCameraPermission = ContextCompat.checkSelfPermission(
            context, Manifest.permission.CAMERA
        ) == PackageManager.PERMISSION_GRANTED
    }

    val enabledState = rememberUpdatedState(enabled)

    DisposableEffect(lifecycleOwner, hasCameraPermission, enabled) {
        onDispose {
            val provider = cameraProvider
            val preview = previewUseCase
            if (provider != null && preview != null) {
                try {
                    provider.unbind(preview)
                } catch (_: Exception) {
                }
            }
            previewUseCase = null
            cameraProvider = null
        }
    }

    Box(
        modifier = Modifier
            .aspectRatio(1f)
            .clip(RoundedCornerShape(4.dp))
            .background(backgroundColor)
            .clickable(enabled = enabled, onClick = onClick),
        contentAlignment = Alignment.Center
    ) {
        if (hasCameraPermission && enabled) {
            AndroidView(
                factory = { ctx ->
                    val previewView = PreviewView(ctx).apply {
                        scaleType = PreviewView.ScaleType.FILL_CENTER
                        implementationMode = PreviewView.ImplementationMode.COMPATIBLE
                    }

                    val cameraProviderFuture = ProcessCameraProvider.getInstance(ctx)
                    cameraProviderFuture.addListener({
                        try {
                            if (!enabledState.value) {
                                return@addListener
                            }
                            val provider = cameraProviderFuture.get()
                            cameraProvider = provider
                            val preview = Preview.Builder().build().also {
                                it.setSurfaceProvider(previewView.surfaceProvider)
                            }
                            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
                            previewUseCase?.let { existing ->
                                try {
                                    provider.unbind(existing)
                                } catch (_: Exception) {
                                }
                            }
                            provider.bindToLifecycle(
                                lifecycleOwner,
                                cameraSelector,
                                preview
                            )
                            previewUseCase = preview
                        } catch (_: Exception) {
                            // Camera init failed
                        }
                    }, ContextCompat.getMainExecutor(ctx))

                    previewView
                },
                modifier = Modifier.fillMaxSize()
            )

            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.3f)),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    painter = TelegramIcons.Camera,
                    contentDescription = "Camera",
                    tint = Color.White,
                    modifier = Modifier
                        .size(32.dp)
                        .graphicsLayer {
                            scaleX = iconScale.value
                            scaleY = iconScale.value
                        }
                )
            }
        } else {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Icon(
                    painter = TelegramIcons.Camera,
                    contentDescription = "Camera",
                    tint = PrimaryBlue,
                    modifier = Modifier
                        .size(40.dp)
                        .graphicsLayer {
                            scaleX = iconScale.value
                            scaleY = iconScale.value
                        }
                )
                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = "Camera",
                    color = PrimaryBlue,
                    fontSize = 12.sp,
                    fontWeight = FontWeight.Medium
                )
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Media Grid Item — single photo/video cell
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun MediaGridItem(
    item: MediaItem,
    isSelected: Boolean,
    selectionIndex: Int,
    onContentClick: (ThumbnailPosition) -> Unit,
    onCheckClick: () -> Unit,
    onLongClick: () -> Unit,
    isDarkTheme: Boolean
) {
    val context = LocalContext.current
    val selectedTransition = updateTransition(targetState = isSelected, label = "mediaSelection")
    val itemScale by selectedTransition.animateFloat(
        transitionSpec = { tween(durationMillis = 200, easing = FastOutSlowInEasing) },
        label = "itemScale"
    ) { selected -> if (selected) 0.787f else 1f }

    val tileBackgroundColor by animateColorAsState(
        targetValue = if (isSelected) {
            if (isDarkTheme) Color(0xFF2F2F31) else Color(0xFFE8EDF5)
        } else Color.Transparent,
        animationSpec = tween(durationMillis = 200, easing = FastOutSlowInEasing),
        label = "tileBackgroundColor"
    )
    val checkBackgroundColor by animateColorAsState(
        targetValue = if (isSelected) PrimaryBlue else Color(0xCCFFFFFF),
        animationSpec = tween(durationMillis = 170, easing = FastOutSlowInEasing),
        label = "checkBackgroundColor"
    )
    val checkBorderColor by animateColorAsState(
        targetValue = if (isSelected) PrimaryBlue else Color(0x80B0B0B0),
        animationSpec = tween(durationMillis = 170, easing = FastOutSlowInEasing),
        label = "checkBorderColor"
    )
    val checkContentAlpha by animateFloatAsState(
        targetValue = if (isSelected) 1f else 0f,
        animationSpec = tween(durationMillis = 140, easing = FastOutSlowInEasing),
        label = "checkContentAlpha"
    )
    val checkScale = remember { Animatable(1f) }
    LaunchedEffect(isSelected) {
        if (isSelected) {
            checkScale.snapTo(0.72f)
            checkScale.animateTo(
                targetValue = 1f,
                animationSpec = spring(
                    dampingRatio = Spring.DampingRatioMediumBouncy,
                    stiffness = Spring.StiffnessMedium
                )
            )
        }
    }

    var itemPosition by remember { mutableStateOf<ThumbnailPosition?>(null) }

    Box(
        modifier = Modifier
            .aspectRatio(1f)
            .clip(RoundedCornerShape(4.dp))
            .background(tileBackgroundColor)
            .onGloballyPositioned { coordinates ->
                val positionInWindow = coordinates.positionInWindow()
                itemPosition = ThumbnailPosition(
                    x = positionInWindow.x,
                    y = positionInWindow.y,
                    width = coordinates.size.width.toFloat(),
                    height = coordinates.size.height.toFloat(),
                    cornerRadius = 4f
                )
            }
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .pointerInput(Unit) {
                    detectTapGestures(
                        onTap = { itemPosition?.let { onContentClick(it) } },
                        onLongPress = { onLongClick() }
                    )
                }
                .graphicsLayer {
                    scaleX = itemScale
                    scaleY = itemScale
                }
                .clip(RoundedCornerShape(4.dp))
        ) {
            val imageRequest = remember(item.uri) {
                ImageRequest.Builder(context)
                    .data(item.uri)
                    .crossfade(false)
                    .build()
            }
            AsyncImage(
                model = imageRequest,
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxSize()
            )

            if (item.isVideo && item.duration > 0) {
                Box(
                    modifier = Modifier
                        .align(Alignment.BottomStart)
                        .padding(4.dp)
                        .background(Color.Black.copy(alpha = 0.6f), RoundedCornerShape(4.dp))
                        .padding(horizontal = 4.dp, vertical = 2.dp)
                ) {
                    Text(
                        text = formatDuration(item.duration),
                        color = Color.White,
                        fontSize = 11.sp,
                        fontWeight = FontWeight.Medium
                    )
                }
            }
        }

        // Selection checkbox
        Box(
            modifier = Modifier
                .align(Alignment.TopEnd)
                .padding(6.dp)
                .size(24.dp)
                .graphicsLayer {
                    scaleX = checkScale.value
                    scaleY = checkScale.value
                }
                .clip(CircleShape)
                .background(checkBackgroundColor)
                .border(width = 2.dp, color = checkBorderColor, shape = CircleShape)
                .clickable(
                    interactionSource = remember { MutableInteractionSource() },
                    indication = null,
                    onClick = onCheckClick
                ),
            contentAlignment = Alignment.Center
        ) {
            if (selectionIndex > 0) {
                Text(
                    text = selectionIndex.toString(),
                    color = Color.White.copy(alpha = checkContentAlpha),
                    fontSize = 12.sp,
                    fontWeight = FontWeight.Bold
                )
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Album Dropdown Menu
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun AlbumDropdownMenu(
    expanded: Boolean,
    onDismissRequest: () -> Unit,
    albums: List<MediaAlbum>,
    selectedAlbumId: Long,
    onAlbumSelected: (Long) -> Unit,
    isDarkTheme: Boolean,
    textColor: Color,
    secondaryTextColor: Color
) {
    val menuBg = if (isDarkTheme) Color(0xFF2C2C2E) else Color.White

    DropdownMenu(
        expanded = expanded,
        onDismissRequest = onDismissRequest,
        modifier = Modifier
            .background(menuBg)
            .widthIn(min = 220.dp, max = 300.dp)
    ) {
        albums.forEach { album ->
            val isSelected = album.id == selectedAlbumId
            val coverUri = album.items.firstOrNull()?.uri

            DropdownMenuItem(
                text = {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        Box(
                            modifier = Modifier
                                .size(32.dp)
                                .clip(RoundedCornerShape(4.dp))
                                .background(if (isDarkTheme) Color(0xFF3A3A3C) else Color(0xFFE5E5EA))
                        ) {
                            if (coverUri != null) {
                                AsyncImage(
                                    model = ImageRequest.Builder(LocalContext.current)
                                        .data(coverUri)
                                        .crossfade(false)
                                        .size(80)
                                        .build(),
                                    contentDescription = null,
                                    contentScale = ContentScale.Crop,
                                    modifier = Modifier.fillMaxSize()
                                )
                            }
                        }

                        Column(modifier = Modifier.weight(1f)) {
                            Text(
                                text = if (album.isAllMedia) "All media" else album.name,
                                color = textColor,
                                fontSize = 15.sp,
                                fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal,
                                maxLines = 1
                            )
                            Text(
                                text = album.items.size.toString(),
                                color = secondaryTextColor,
                                fontSize = 12.sp,
                                maxLines = 1
                            )
                        }

                        if (isSelected) {
                            Icon(
                                imageVector = Icons.Default.Check,
                                contentDescription = null,
                                tint = PrimaryBlue,
                                modifier = Modifier.size(18.dp)
                            )
                        }
                    }
                },
                onClick = { onAlbumSelected(album.id) },
                modifier = Modifier.height(48.dp)
            )
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Tab Bar — replaces QuickActionsRow with active tab highlight
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun AttachTabBar(
    currentTab: AttachAlertTab,
    onTabSelected: (AttachAlertTab) -> Unit,
    isDarkTheme: Boolean,
    modifier: Modifier = Modifier
) {
    Row(
        modifier = modifier
            .fillMaxWidth()
            .padding(start = 28.dp, end = 28.dp, top = 8.dp, bottom = 12.dp),
        horizontalArrangement = Arrangement.SpaceEvenly,
        verticalAlignment = Alignment.Bottom
    ) {
        TabButton(
            icon = TelegramIcons.Photos,
            contentDescription = "Gallery",
            label = "Gallery",
            isActive = currentTab == AttachAlertTab.PHOTO,
            isDarkTheme = isDarkTheme,
            animationDelayMs = 0,
            onClick = { onTabSelected(AttachAlertTab.PHOTO) }
        )
        TabButton(
            icon = TelegramIcons.File,
            contentDescription = "File",
            label = "File",
            isActive = currentTab == AttachAlertTab.FILE,
            isDarkTheme = isDarkTheme,
            animationDelayMs = 32,
            onClick = { onTabSelected(AttachAlertTab.FILE) }
        )
        TabButton(
            icon = TelegramIcons.Contact,
            contentDescription = "Avatar",
            label = "Avatar",
            isActive = currentTab == AttachAlertTab.AVATAR,
            isDarkTheme = isDarkTheme,
            animationDelayMs = 64,
            onClick = { onTabSelected(AttachAlertTab.AVATAR) }
        )
    }
}

@Composable
private fun TabButton(
    icon: androidx.compose.ui.graphics.painter.Painter,
    contentDescription: String,
    label: String,
    isDarkTheme: Boolean,
    isActive: Boolean = false,
    animationDelayMs: Int,
    onClick: () -> Unit
) {
    val scale = remember { Animatable(0f) }
    val alpha = remember { Animatable(0f) }
    val easeOut = remember { CubicBezierEasing(0f, 0f, 0.58f, 1f) }
    val easeIn = remember { CubicBezierEasing(0.42f, 0f, 1f, 1f) }
    LaunchedEffect(Unit) {
        delay(animationDelayMs.toLong())
        alpha.snapTo(0f)
        scale.snapTo(0f)
        coroutineScope {
            launch { alpha.animateTo(1f, animationSpec = tween(200, easing = easeOut)) }
            launch {
                scale.animateTo(1.1f, animationSpec = tween(200, easing = easeOut))
                scale.animateTo(1f, animationSpec = tween(100, easing = easeIn))
            }
        }
    }

    Column(
        modifier = Modifier.width(72.dp).graphicsLayer { this.alpha = alpha.value },
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Box(
            modifier = Modifier
                .size(56.dp)
                .graphicsLayer {
                    scaleX = scale.value
                    scaleY = scale.value
                }
                .clip(CircleShape)
                .background(PrimaryBlue)
                .clickable(
                    interactionSource = remember { MutableInteractionSource() },
                    indication = null,
                    onClick = onClick
                ),
            contentAlignment = Alignment.Center
        ) {
            Icon(
                painter = icon,
                contentDescription = contentDescription,
                tint = Color.White,
                modifier = Modifier.size(24.dp)
            )
        }

        Spacer(modifier = Modifier.height(6.dp))
        Text(
            text = label,
            fontSize = 18.sp * 0.72f,
            fontWeight = FontWeight.Medium,
            color = when {
                isActive -> PrimaryBlue
                isDarkTheme -> Color(0xFF9AA1AB)
                else -> Color(0xFF7A8190)
            },
            maxLines = 1
        )
    }
}

// ═══════════════════════════════════════════════════════════════
// Collapsed Header — drag handle + selection text
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun CollapsedHeader(
    selectionHeaderText: String,
    selectionHeaderHeightDp: androidx.compose.ui.unit.Dp,
    selectionHeaderAlpha: Float,
    handleAlpha: Float,
    collapsedHeaderAlpha: Float,
    textColor: Color,
    secondaryTextColor: Color
) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .graphicsLayer { alpha = collapsedHeaderAlpha }
    ) {
        // Drag handle
        Column(
            modifier = Modifier.fillMaxWidth(),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Spacer(modifier = Modifier.height(8.dp))
            Box(
                modifier = Modifier
                    .width(36.dp)
                    .height(4.dp)
                    .graphicsLayer { alpha = handleAlpha }
                    .clip(RoundedCornerShape(2.dp))
                    .background(secondaryTextColor.copy(alpha = 0.3f))
            )
            Spacer(modifier = Modifier.height(6.dp))
        }

        // "N photo(s) selected" — height derived from sheet growth
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(selectionHeaderHeightDp)
                .graphicsLayer {
                    alpha = selectionHeaderAlpha
                    clip = true
                },
            contentAlignment = Alignment.CenterStart
        ) {
            if (selectionHeaderAlpha > 0.01f) {
                Text(
                    text = selectionHeaderText,
                    color = textColor,
                    fontSize = 16.sp,
                    fontWeight = FontWeight.Bold,
                    maxLines = 1,
                    modifier = Modifier.padding(start = 23.dp)
                )
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Expanded Header — back button + album dropdown / selection count
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun ExpandedHeader(
    fullScreenHeaderProgress: Float,
    statusBarTopPadding: androidx.compose.ui.unit.Dp,
    selectedCount: Int,
    currentAlbumTitle: String,
    canSwitchAlbums: Boolean,
    showAlbumMenu: Boolean,
    onShowAlbumMenu: () -> Unit,
    onDismissAlbumMenu: () -> Unit,
    albums: List<MediaAlbum>,
    selectedAlbumId: Long,
    onAlbumSelected: (Long) -> Unit,
    onClose: () -> Unit,
    isDarkTheme: Boolean,
    textColor: Color,
    secondaryTextColor: Color,
    density: androidx.compose.ui.unit.Density
) {
    val fullScreenHeaderHeight = (statusBarTopPadding + 52.dp) * fullScreenHeaderProgress
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(fullScreenHeaderHeight)
            .graphicsLayer { clip = true }
    ) {
        if (fullScreenHeaderProgress > 0.001f) {
            val headerTranslationY = with(density) { (1f - fullScreenHeaderProgress) * (-14).dp.toPx() }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = statusBarTopPadding, start = 4.dp, end = 8.dp)
                    .graphicsLayer {
                        alpha = fullScreenHeaderProgress
                        translationY = headerTranslationY
                    },
                verticalAlignment = Alignment.CenterVertically
            ) {
                IconButton(
                    onClick = onClose,
                    modifier = Modifier.size(40.dp)
                ) {
                    Icon(
                        imageVector = TablerIcons.ChevronLeft,
                        contentDescription = "Close gallery",
                        tint = textColor
                    )
                }

                Box(modifier = Modifier.weight(1f)) {
                    AnimatedContent(
                        targetState = selectedCount > 0,
                        transitionSpec = {
                            fadeIn(tween(160)) togetherWith fadeOut(tween(160))
                        },
                        label = "expanded_header_title"
                    ) { hasSelection ->
                        if (hasSelection) {
                            Text(
                                text = when (selectedCount) {
                                    1 -> "1 photo selected"
                                    else -> "$selectedCount photos selected"
                                },
                                color = textColor,
                                fontSize = 19.sp,
                                fontWeight = FontWeight.SemiBold,
                                maxLines = 1
                            )
                        } else {
                            Row(
                                modifier = Modifier
                                    .clip(RoundedCornerShape(18.dp))
                                    .clickable(
                                        enabled = canSwitchAlbums,
                                        interactionSource = remember { MutableInteractionSource() },
                                        indication = null
                                    ) { if (canSwitchAlbums) onShowAlbumMenu() }
                                    .padding(horizontal = 6.dp, vertical = 6.dp),
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                Text(
                                    text = currentAlbumTitle,
                                    color = textColor,
                                    fontSize = 19.sp,
                                    fontWeight = FontWeight.SemiBold,
                                    maxLines = 1
                                )
                                if (canSwitchAlbums) {
                                    Spacer(modifier = Modifier.width(2.dp))
                                    Icon(
                                        imageVector = TablerIcons.ChevronDown,
                                        contentDescription = null,
                                        tint = textColor.copy(alpha = 0.7f),
                                        modifier = Modifier.size(18.dp)
                                    )
                                }
                            }
                        }
                    }

                    AlbumDropdownMenu(
                        expanded = showAlbumMenu && canSwitchAlbums && fullScreenHeaderProgress > 0.5f,
                        onDismissRequest = onDismissAlbumMenu,
                        albums = albums,
                        selectedAlbumId = selectedAlbumId,
                        onAlbumSelected = { albumId ->
                            onAlbumSelected(albumId)
                            onDismissAlbumMenu()
                        },
                        isDarkTheme = isDarkTheme,
                        textColor = textColor,
                        secondaryTextColor = secondaryTextColor
                    )
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Caption Bar
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun CaptionBar(
    captionBarProgress: Float,
    captionText: String,
    onCaptionChange: (String) -> Unit,
    isCaptionKeyboardVisible: Boolean,
    isEmojiVisible: Boolean = false,
    onToggleKeyboard: () -> Unit,
    onFocusCaption: () -> Unit,
    onViewCreated: (com.rosetta.messenger.ui.components.AppleEmojiEditTextView) -> Unit,
    isDarkTheme: Boolean,
    density: androidx.compose.ui.unit.Density
) {
    // Telegram-style CaptionBar:
    // - AnimatedVisibility for show/hide (expandVertically + fadeIn/Out, 180ms)
    // - animateContentSize for smooth multiline expansion (200ms CubicBezier,
    //   matching Telegram's captionEditTextTopOffset animation)
    val captionMultilineEasing = CubicBezierEasing(0.25f, 0.1f, 0.25f, 1f)
    val captionLiftEasing = CubicBezierEasing(0f, 0f, 0.2f, 1f)
    val isVisible = captionBarProgress > 0.001f

    AnimatedVisibility(
        visible = isVisible,
        enter = expandVertically(
            animationSpec = tween(180, easing = captionLiftEasing),
            expandFrom = Alignment.Bottom
        ) + fadeIn(animationSpec = tween(180, easing = captionLiftEasing)),
        exit = shrinkVertically(
            animationSpec = tween(180, easing = captionLiftEasing),
            shrinkTowards = Alignment.Bottom
        ) + fadeOut(animationSpec = tween(180, easing = captionLiftEasing))
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                // animateContentSize: smooth multiline expansion/collapse
                // like Telegram's captionEditTextTopOffset (200ms CubicBezier)
                .animateContentSize(
                    animationSpec = tween(200, easing = captionMultilineEasing)
                )
        ) {
            // Thin divider
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(0.5.dp)
                    .background(
                        if (isDarkTheme) Color.White.copy(alpha = 0.08f)
                        else Color.Black.copy(alpha = 0.12f)
                    )
            )
            // Flat caption row
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 6.dp, end = 84.dp, top = 4.dp, bottom = 4.dp),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                // Emoji visible → show Keyboard icon (to switch back)
                // Keyboard visible → show Smile icon (to switch to emoji)
                // Neither → show Smile icon (to open keyboard on first tap)
                val captionIconPainter =
                    if (isEmojiVisible) TelegramIcons.Keyboard
                    else TelegramIcons.Smile
                Icon(
                    painter = captionIconPainter,
                    contentDescription = "Caption keyboard toggle",
                    tint = if (isDarkTheme) Color.White.copy(alpha = 0.55f) else Color.Gray,
                    modifier = Modifier
                        .size(32.dp)
                        .clip(CircleShape)
                        .clickable(
                            interactionSource = remember { MutableInteractionSource() },
                            indication = null
                        ) { onToggleKeyboard() }
                        .padding(4.dp)
                )

                Box(
                    modifier = Modifier
                        .weight(1f)
                        .heightIn(min = 28.dp, max = 120.dp),
                    contentAlignment = Alignment.CenterStart
                ) {
                    AppleEmojiTextField(
                        value = captionText,
                        onValueChange = onCaptionChange,
                        textColor = if (isDarkTheme) Color.White else Color.Black,
                        textSize = 16f,
                        hint = "Add a caption...",
                        hintColor = if (isDarkTheme) Color.White.copy(alpha = 0.35f)
                        else Color.Gray.copy(alpha = 0.5f),
                        modifier = Modifier.fillMaxWidth(),
                        requestFocus = false,
                        onViewCreated = onViewCreated,
                        onFocusChanged = { hasFocus ->
                            // When EditText gets native touch → gains focus →
                            // trigger FLAG_ALT_FOCUSABLE_IM management in ChatAttachAlert.
                            android.util.Log.d("AttachAlert", "CaptionBar EditText onFocusChanged: hasFocus=$hasFocus")
                            if (hasFocus) onFocusCaption()
                        }
                    )
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Floating Send Button
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun FloatingSendButton(
    selectedCount: Int,
    sendButtonProgress: Float,
    backgroundColor: Color,
    onSend: () -> Unit,
    modifier: Modifier = Modifier
) {
    if (sendButtonProgress > 0.001f) {
        val sendScale = 0.2f + 0.8f * sendButtonProgress
        Box(
            modifier = modifier
                .padding(end = 14.dp, bottom = 8.dp)
                .graphicsLayer {
                    scaleX = sendScale
                    scaleY = sendScale
                    alpha = sendButtonProgress
                },
            contentAlignment = Alignment.Center
        ) {
            Box(
                modifier = Modifier
                    .size(56.dp)
                    .shadow(elevation = 6.dp, shape = CircleShape, clip = false)
                    .clip(CircleShape)
                    .background(PrimaryBlue)
                    .clickable { onSend() },
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    painter = TelegramIcons.Send,
                    contentDescription = "Send",
                    tint = Color.White,
                    modifier = Modifier.size(24.dp)
                )
            }
            if (selectedCount > 0) {
                Box(
                    modifier = Modifier
                        .align(Alignment.TopEnd)
                        .offset(x = 4.dp, y = (-2).dp)
                        .sizeIn(minWidth = 22.dp, minHeight = 22.dp)
                        .border(width = 2.dp, color = backgroundColor, shape = CircleShape)
                        .clip(CircleShape)
                        .background(PrimaryBlue)
                        .padding(horizontal = 4.dp),
                    contentAlignment = Alignment.Center
                ) {
                    Text(
                        text = selectedCount.toString(),
                        color = Color.White,
                        fontSize = 12.sp,
                        fontWeight = FontWeight.Bold,
                        maxLines = 1
                    )
                }
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Permission Request View
// ═══════════════════════════════════════════════════════════════

@Composable
internal fun PermissionRequestView(
    isDarkTheme: Boolean,
    textColor: Color,
    secondaryTextColor: Color,
    onRequestPermission: () -> Unit
) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(32.dp),
        contentAlignment = Alignment.Center
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Icon(
                TablerIcons.PhotoOff,
                contentDescription = null,
                tint = secondaryTextColor,
                modifier = Modifier.size(64.dp)
            )
            Spacer(modifier = Modifier.height(16.dp))
            Text(
                text = "Access to gallery",
                color = textColor,
                fontSize = 18.sp,
                fontWeight = FontWeight.SemiBold
            )
            Spacer(modifier = Modifier.height(8.dp))
            Text(
                text = "Allow access to your photos and videos to share them in chat",
                color = secondaryTextColor,
                fontSize = 14.sp,
                textAlign = TextAlign.Center
            )
            Spacer(modifier = Modifier.height(24.dp))
            Button(
                onClick = onRequestPermission,
                colors = ButtonDefaults.buttonColors(containerColor = PrimaryBlue),
                shape = RoundedCornerShape(12.dp)
            ) {
                Text("Allow Access", color = Color.White)
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════
// Utilities
// ═══════════════════════════════════════════════════════════════

internal fun formatDuration(durationMs: Long): String {
    val totalSeconds = durationMs / 1000
    val minutes = totalSeconds / 60
    val seconds = totalSeconds % 60
    return "%d:%02d".format(minutes, seconds)
}
