package com.swoosh.microblog.ui.composer

import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.*
import androidx.compose.animation.Crossfade
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.*
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.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.platform.LocalContext
import coil.compose.AsyncImage
import com.swoosh.microblog.data.AccountManager
import com.swoosh.microblog.data.HashtagParser
import com.swoosh.microblog.data.SiteMetadataCache
import com.swoosh.microblog.data.model.FeedPost
import com.swoosh.microblog.data.model.GhostNewsletter
import com.swoosh.microblog.data.model.GhostTagFull
import com.swoosh.microblog.data.model.PostStats
import com.swoosh.microblog.ui.animation.SwooshMotion
import kotlinx.coroutines.delay
import com.swoosh.microblog.ui.components.PulsingPlaceholder
import com.swoosh.microblog.ui.preview.HtmlPreviewWebView
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ComposerScreen(
    editPost: FeedPost? = null,
    onDismiss: () -> Unit,
    onFullScreenPreview: ((String) -> Unit)? = null,
    viewModel: ComposerViewModel = viewModel()
) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    var showLinkDialog by remember { mutableStateOf(false) }
    var showDatePicker by remember { mutableStateOf(false) }
    var showAltTextDialog by remember { mutableStateOf(false) }
    var linkInput by remember { mutableStateOf("") }
    var showSendMenu by remember { mutableStateOf(false) }
    var fullScreenImageIndex by remember { mutableIntStateOf(-1) }
    val fullScreenImageUri = if (fullScreenImageIndex >= 0 && fullScreenImageIndex < state.imageUris.size)
        state.imageUris[fullScreenImageIndex] else null
    val dismissFullScreen = { fullScreenImageIndex = -1 }

    // Focus requester for auto-focus on text field
    val focusRequester = remember { FocusRequester() }

    // Load post for editing
    LaunchedEffect(editPost) {
        if (editPost != null) {
            viewModel.loadForEdit(editPost)
        }
    }

    // Auto-focus on text input with a small delay
    LaunchedEffect(Unit) {
        delay(300)
        focusRequester.requestFocus()
    }

    LaunchedEffect(state.isSuccess) {
        if (state.isSuccess) {
            viewModel.reset()
            onDismiss()
        }
    }

    // Multi-image picker
    val multiImagePickerLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.GetMultipleContents()
    ) { uris: List<Uri> ->
        if (uris.isNotEmpty()) {
            viewModel.addImages(uris)
        }
    }

    // File picker
    val filePickerLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        if (uri != null) {
            viewModel.addFile(uri)
        }
    }

    // Video picker
    val videoPickerLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        uri?.let { viewModel.setVideo(it) }
    }

    // Audio picker
    val audioPickerLauncher = rememberLauncherForActivityResult(
        ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        uri?.let { viewModel.setAudio(it) }
    }

    val canSubmit by remember {
        derivedStateOf { !state.isSubmitting && (state.text.isNotBlank() || state.imageUris.isNotEmpty() || state.fileUri != null || state.videoUri != null || state.audioUri != null) }
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(if (state.isEditing) "Edit Post" else "New Post") },
                navigationIcon = {
                    IconButton(onClick = {
                        viewModel.reset()
                        onDismiss()
                    }) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back")
                    }
                },
                actions = {
                    // Full-screen preview button (only in preview mode)
                    if (state.isPreviewMode && state.previewHtml.isNotEmpty()) {
                        IconButton(onClick = {
                            onFullScreenPreview?.invoke(state.previewHtml)
                        }) {
                            Icon(Icons.Default.Fullscreen, "Full screen preview")
                        }
                    }

                    // Send button
                    if (state.isSubmitting) {
                        Box(
                            modifier = Modifier.size(48.dp),
                            contentAlignment = Alignment.Center
                        ) {
                            CircularProgressIndicator(
                                modifier = Modifier.size(24.dp),
                                strokeWidth = 2.dp
                            )
                        }
                    } else {
                        val isNewsletterPublish = state.sendAsNewsletter && state.selectedNewsletter != null
                        FilledIconButton(
                            onClick = viewModel::publish,
                            enabled = canSubmit,
                            colors = IconButtonDefaults.filledIconButtonColors(
                                containerColor = if (isNewsletterPublish)
                                    MaterialTheme.colorScheme.tertiaryContainer
                                else MaterialTheme.colorScheme.primary,
                                contentColor = if (isNewsletterPublish)
                                    MaterialTheme.colorScheme.onTertiaryContainer
                                else MaterialTheme.colorScheme.onPrimary
                            )
                        ) {
                            Icon(
                                if (isNewsletterPublish) Icons.Default.Email else Icons.Default.Send,
                                if (isNewsletterPublish) "Publish & Send Email" else "Publish"
                            )
                        }
                    }

                    // Dropdown arrow for more publish options
                    Box {
                        IconButton(
                            onClick = { showSendMenu = true },
                            enabled = !state.isSubmitting
                        ) {
                            Icon(
                                Icons.Default.ArrowDropDown,
                                "More publish options",
                                modifier = Modifier.size(20.dp)
                            )
                        }
                        DropdownMenu(
                            expanded = showSendMenu,
                            onDismissRequest = { showSendMenu = false }
                        ) {
                            val publishLabel = if (state.sendAsNewsletter && state.selectedNewsletter != null) {
                                if (state.isEditing) "Update & Send Email" else "Publish & Send Email"
                            } else {
                                if (state.isEditing) "Update & Publish" else "Publish Now"
                            }
                            DropdownMenuItem(
                                text = { Text(publishLabel) },
                                onClick = {
                                    showSendMenu = false
                                    viewModel.publish()
                                },
                                leadingIcon = {
                                    Icon(
                                        if (state.sendAsNewsletter && state.selectedNewsletter != null)
                                            Icons.Default.Email else Icons.Default.Send,
                                        null
                                    )
                                },
                                enabled = canSubmit
                            )
                            DropdownMenuItem(
                                text = { Text("Save as Draft") },
                                onClick = {
                                    showSendMenu = false
                                    viewModel.saveDraft()
                                },
                                leadingIcon = { Icon(Icons.Default.Save, null) },
                                enabled = canSubmit
                            )
                            DropdownMenuItem(
                                text = { Text("Schedule...") },
                                onClick = {
                                    showSendMenu = false
                                    showDatePicker = true
                                },
                                leadingIcon = { Icon(Icons.Default.Schedule, null) },
                                enabled = canSubmit
                            )

                            // Email-only option
                            if (state.newsletterEnabled) {
                                HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp))
                                DropdownMenuItem(
                                    text = { Text("Send via Email Only") },
                                    onClick = {
                                        showSendMenu = false
                                        viewModel.sendEmailOnly()
                                    },
                                    leadingIcon = { Icon(Icons.Default.Email, null) },
                                    enabled = canSubmit
                                )
                            }

                            // Newsletter options
                            if (state.newsletterEnabled) {
                                HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp))
                                NewsletterDropdownSection(
                                    state = state,
                                    onToggleSendAsNewsletter = viewModel::toggleSendAsNewsletter,
                                    onSelectNewsletter = viewModel::selectNewsletter,
                                    onSetEmailSegment = viewModel::setEmailSegment
                                )
                            }
                        }
                    }
                }
            )
        }
    ) { padding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
        ) {
            // "Publishing to" chip when multiple accounts exist
            val composerContext = LocalContext.current
            val composerAccountManager = remember { AccountManager(composerContext) }
            val composerAccounts = remember { composerAccountManager.getAccounts() }
            val composerActiveAccount = remember { composerAccountManager.getActiveAccount() }

            if (composerAccounts.size > 1 && composerActiveAccount != null) {
                val composerSiteCache = remember { SiteMetadataCache(composerContext) }
                val composerSiteData = remember {
                    composerSiteCache.get(composerActiveAccount.id)
                }
                val siteName = composerSiteData?.title ?: composerActiveAccount.name
                val siteIconUrl = composerSiteData?.icon ?: composerSiteData?.logo

                AssistChip(
                    onClick = { },
                    label = { Text("Publishing to: $siteName") },
                    leadingIcon = if (siteIconUrl != null) {
                        {
                            AsyncImage(
                                model = siteIconUrl,
                                contentDescription = null,
                                modifier = Modifier
                                    .size(18.dp)
                                    .clip(CircleShape),
                                contentScale = ContentScale.Crop
                            )
                        }
                    } else null,
                    modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
                )
            }

            // Hashtag visual transformation for edit mode text field
            val hashtagColor = MaterialTheme.colorScheme.primary
            val hashtagTransformation = remember(hashtagColor) {
                HashtagVisualTransformation(hashtagColor)
            }

            // Edit / Preview segmented button row
            SingleChoiceSegmentedButtonRow(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp, vertical = 8.dp)
            ) {
                SegmentedButton(
                    selected = !state.isPreviewMode,
                    onClick = { viewModel.setPreviewMode(false) },
                    shape = SegmentedButtonDefaults.itemShape(index = 0, count = 2),
                    icon = {
                        SegmentedButtonDefaults.Icon(active = !state.isPreviewMode) {
                            Icon(
                                Icons.Default.Edit,
                                contentDescription = null,
                                modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
                            )
                        }
                    }
                ) {
                    Text("Edit")
                }
                SegmentedButton(
                    selected = state.isPreviewMode,
                    onClick = { viewModel.setPreviewMode(true) },
                    shape = SegmentedButtonDefaults.itemShape(index = 1, count = 2),
                    icon = {
                        SegmentedButtonDefaults.Icon(active = state.isPreviewMode) {
                            Icon(
                                Icons.Default.Visibility,
                                contentDescription = null,
                                modifier = Modifier.size(SegmentedButtonDefaults.IconSize)
                            )
                        }
                    }
                ) {
                    Text("Preview")
                }
            }

            Crossfade(
                targetState = state.isPreviewMode,
                animationSpec = SwooshMotion.quick(),
                label = "editPreviewCrossfade"
            ) { isPreview ->
            if (isPreview) {
                // Preview mode: show rendered HTML
                if (state.text.isBlank() && state.imageUris.isEmpty() && state.linkPreview == null) {
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .weight(1f),
                        contentAlignment = Alignment.Center
                    ) {
                        Text(
                            text = "Nothing to preview yet.\nSwitch to Edit and write something.",
                            style = MaterialTheme.typography.bodyMedium,
                            color = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                } else {
                    HtmlPreviewWebView(
                        html = state.previewHtml,
                        modifier = Modifier
                            .fillMaxWidth()
                            .weight(1f)
                    )
                }
            } else {
                // Edit mode: composer UI
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .weight(1f)
                        .verticalScroll(rememberScrollState())
                        .padding(16.dp)
                ) {
                    // Text field — primary focus, takes most of the screen
                    OutlinedTextField(
                        value = state.text,
                        onValueChange = viewModel::updateText,
                        modifier = Modifier
                            .fillMaxWidth()
                            .heightIn(min = 200.dp)
                            .focusRequester(focusRequester),
                        placeholder = { Text("What's on your mind?") },
                        visualTransformation = hashtagTransformation,
                        supportingText = {
                            val charCount = state.text.length
                            val statsText = PostStats.formatComposerStats(state.text)
                            val targetColor = when {
                                charCount > 500 -> MaterialTheme.colorScheme.error
                                charCount > 280 -> MaterialTheme.colorScheme.tertiary
                                else -> MaterialTheme.colorScheme.onSurfaceVariant
                            }
                            val animatedColor by animateColorAsState(
                                targetValue = targetColor,
                                animationSpec = SwooshMotion.quick(),
                                label = "counterColor"
                            )
                            Text(
                                text = statsText,
                                style = MaterialTheme.typography.labelSmall,
                                color = animatedColor
                            )
                        }
                    )

                    // Tags section: input + suggestions + chips (only when tags enabled)
                    if (viewModel.isTagsEnabled()) {
                        Spacer(modifier = Modifier.height(12.dp))
                        TagsSection(
                            tagInput = state.tagInput,
                            onTagInputChange = viewModel::updateTagInput,
                            tagSuggestions = state.tagSuggestions,
                            extractedTags = state.extractedTags,
                            onAddTag = viewModel::addTag,
                            onRemoveTag = viewModel::removeTag
                        )
                    }

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

                    // Compact attachment buttons row
                    Row(
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        OutlinedIconButton(onClick = { multiImagePickerLauncher.launch("image/*") }) {
                            Icon(Icons.Default.Image, "Attach images")
                        }
                        OutlinedIconButton(onClick = { videoPickerLauncher.launch("video/*") }) {
                            Icon(Icons.Default.Videocam, "Attach video")
                        }
                        OutlinedIconButton(onClick = { audioPickerLauncher.launch("audio/*") }) {
                            Icon(Icons.Default.MusicNote, "Attach audio")
                        }
                        OutlinedIconButton(onClick = { showLinkDialog = true }) {
                            Icon(Icons.Default.Link, "Add link")
                        }
                        OutlinedIconButton(
                            onClick = { filePickerLauncher.launch("application/*") },
                            enabled = state.fileUri == null
                        ) {
                            Icon(Icons.Default.AttachFile, "Attach file")
                        }
                    }

                    // Image grid preview (multi-image) — 120dp thumbnails
                    AnimatedVisibility(
                        visible = state.imageUris.isNotEmpty(),
                        enter = scaleIn(initialScale = 0f, animationSpec = SwooshMotion.bouncy()) + fadeIn(SwooshMotion.quick()),
                        exit = scaleOut(animationSpec = SwooshMotion.quick()) + fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            ImageGridPreview(
                                imageUris = state.imageUris,
                                onRemoveImage = viewModel::removeImage,
                                onAddMore = { multiImagePickerLauncher.launch("image/*") },
                                onImageClick = { index, _ ->
                                    fullScreenImageIndex = index
                                }
                            )

                            // Alt text for the first/primary image
                            Spacer(modifier = Modifier.height(4.dp))
                            TextButton(
                                onClick = { showAltTextDialog = true },
                                contentPadding = PaddingValues(horizontal = 0.dp)
                            ) {
                                Text(
                                    text = if (state.imageAlt.isBlank()) "Add alt text" else "Edit alt text",
                                    style = MaterialTheme.typography.labelMedium,
                                    color = MaterialTheme.colorScheme.primary
                                )
                            }
                            // ALT badge when alt text is set
                            if (state.imageAlt.isNotBlank()) {
                                Text(
                                    text = "ALT",
                                    modifier = Modifier
                                        .background(
                                            MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.8f),
                                            RoundedCornerShape(4.dp)
                                        )
                                        .padding(horizontal = 6.dp, vertical = 2.dp),
                                    color = MaterialTheme.colorScheme.inverseOnSurface,
                                    fontSize = 11.sp,
                                    fontWeight = FontWeight.Bold
                                )
                            }
                        }
                    }

                    // Video preview card
                    AnimatedVisibility(
                        visible = state.videoUri != null,
                        enter = scaleIn(initialScale = 0f, animationSpec = SwooshMotion.bouncy()) + fadeIn(SwooshMotion.quick()),
                        exit = scaleOut(animationSpec = SwooshMotion.quick()) + fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            MediaPreviewCard(
                                icon = Icons.Default.Videocam,
                                label = "Video attached",
                                uri = state.videoUri,
                                onRemove = viewModel::removeVideo
                            )
                        }
                    }

                    // Audio preview card
                    AnimatedVisibility(
                        visible = state.audioUri != null,
                        enter = scaleIn(initialScale = 0f, animationSpec = SwooshMotion.bouncy()) + fadeIn(SwooshMotion.quick()),
                        exit = scaleOut(animationSpec = SwooshMotion.quick()) + fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            MediaPreviewCard(
                                icon = Icons.Default.MusicNote,
                                label = "Audio attached",
                                uri = state.audioUri,
                                onRemove = viewModel::removeAudio
                            )
                        }
                    }

                    // File attachment card
                    AnimatedVisibility(
                        visible = state.fileUri != null,
                        enter = scaleIn(initialScale = 0f, animationSpec = SwooshMotion.bouncy()) + fadeIn(SwooshMotion.quick()),
                        exit = scaleOut(animationSpec = SwooshMotion.quick()) + fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            FileAttachmentComposerCard(
                                fileName = state.fileName ?: "file",
                                fileSize = state.fileSize ?: 0,
                                fileMimeType = state.fileMimeType,
                                onRemove = viewModel::removeFile
                            )
                        }
                    }

                    // Link preview
                    AnimatedVisibility(
                        visible = state.isLoadingLink,
                        enter = fadeIn(SwooshMotion.quick()),
                        exit = fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            PulsingPlaceholder(height = 80.dp)
                        }
                    }

                    AnimatedVisibility(
                        visible = state.linkPreview != null && !state.isLoadingLink,
                        enter = slideInVertically(initialOffsetY = { it / 2 }, animationSpec = SwooshMotion.gentle()) + fadeIn(SwooshMotion.quick()),
                        exit = fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            OutlinedCard(modifier = Modifier.fillMaxWidth()) {
                                Column(modifier = Modifier.padding(12.dp)) {
                                    Row(
                                        modifier = Modifier.fillMaxWidth(),
                                        horizontalArrangement = Arrangement.SpaceBetween,
                                        verticalAlignment = Alignment.CenterVertically
                                    ) {
                                        Text(
                                            text = state.linkPreview!!.title ?: state.linkPreview!!.url,
                                            style = MaterialTheme.typography.titleSmall,
                                            modifier = Modifier.weight(1f)
                                        )
                                        IconButton(onClick = viewModel::removeLinkPreview) {
                                            Icon(Icons.Default.Close, "Remove link", Modifier.size(18.dp))
                                        }
                                    }
                                    if (state.linkPreview!!.description != null) {
                                        Text(
                                            text = state.linkPreview!!.description!!,
                                            style = MaterialTheme.typography.bodySmall,
                                            color = MaterialTheme.colorScheme.onSurfaceVariant,
                                            maxLines = 2
                                        )
                                    }
                                    if (state.linkPreview!!.imageUrl != null) {
                                        Spacer(modifier = Modifier.height(8.dp))
                                        AsyncImage(
                                            model = state.linkPreview!!.imageUrl,
                                            contentDescription = null,
                                            modifier = Modifier
                                                .fillMaxWidth()
                                                .height(120.dp)
                                                .clip(MaterialTheme.shapes.small),
                                            contentScale = ContentScale.Crop
                                        )
                                    }
                                }
                            }
                        }
                    }

                    // Scheduled time display
                    AnimatedVisibility(
                        visible = state.scheduledAt != null,
                        enter = scaleIn(animationSpec = SwooshMotion.bouncy()) + fadeIn(SwooshMotion.quick()),
                        exit = scaleOut(animationSpec = SwooshMotion.quick()) + fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            AssistChip(
                                onClick = { showDatePicker = true },
                                label = { Text("Scheduled: ${state.scheduledAt}") },
                                leadingIcon = { Icon(Icons.Default.Schedule, null, Modifier.size(18.dp)) },
                                trailingIcon = {
                                    IconButton(
                                        onClick = { viewModel.setScheduledDate(null) },
                                        modifier = Modifier.size(18.dp)
                                    ) {
                                        Icon(Icons.Default.Close, "Clear schedule", Modifier.size(14.dp))
                                    }
                                }
                            )
                        }
                    }

                    // Error display
                    AnimatedVisibility(
                        visible = state.error != null,
                        enter = slideInHorizontally(initialOffsetX = { -it / 4 }, animationSpec = SwooshMotion.snappy()) + fadeIn(SwooshMotion.quick()),
                        exit = fadeOut(SwooshMotion.quick())
                    ) {
                        Column {
                            Spacer(modifier = Modifier.height(12.dp))
                            Text(
                                text = state.error ?: "",
                                color = MaterialTheme.colorScheme.error,
                                style = MaterialTheme.typography.bodySmall
                            )
                        }
                    }
                }
            }
            } // end Crossfade
        }
    }

    // Link dialog
    if (showLinkDialog) {
        AlertDialog(
            onDismissRequest = { showLinkDialog = false },
            title = { Text("Add Link") },
            text = {
                OutlinedTextField(
                    value = linkInput,
                    onValueChange = { linkInput = it },
                    placeholder = { Text("https://...") },
                    singleLine = true,
                    modifier = Modifier.fillMaxWidth()
                )
            },
            confirmButton = {
                TextButton(onClick = {
                    viewModel.fetchLinkPreview(linkInput)
                    linkInput = ""
                    showLinkDialog = false
                }) {
                    Text("Fetch Preview")
                }
            },
            dismissButton = {
                TextButton(onClick = { showLinkDialog = false }) {
                    Text("Cancel")
                }
            }
        )
    }

    // Schedule date picker
    if (showDatePicker) {
        ScheduleDateTimePicker(
            onConfirm = { dateTime ->
                val isoString = dateTime.atZone(ZoneId.systemDefault())
                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
                viewModel.setScheduledDate(isoString)
                showDatePicker = false
                // Auto-submit as scheduled
                viewModel.schedule()
            },
            onDismiss = { showDatePicker = false }
        )
    }

    // Alt text dialog
    if (showAltTextDialog) {
        var altInput by remember { mutableStateOf(state.imageAlt) }
        AlertDialog(
            onDismissRequest = { showAltTextDialog = false },
            title = { Text("Alt Text") },
            text = {
                Column {
                    OutlinedTextField(
                        value = altInput,
                        onValueChange = { altInput = it.take(250) },
                        placeholder = { Text("Describe this image for people who can't see it") },
                        modifier = Modifier.fillMaxWidth(),
                        minLines = 2,
                        maxLines = 4,
                        supportingText = {
                            Text(
                                "${altInput.length}/250",
                                style = MaterialTheme.typography.labelSmall,
                                color = if (altInput.length >= 250)
                                    MaterialTheme.colorScheme.error
                                else MaterialTheme.colorScheme.onSurfaceVariant
                            )
                        }
                    )
                }
            },
            confirmButton = {
                TextButton(onClick = {
                    viewModel.updateImageAlt(altInput)
                    showAltTextDialog = false
                }) {
                    Text("Save")
                }
            },
            dismissButton = {
                TextButton(onClick = { showAltTextDialog = false }) {
                    Text("Cancel")
                }
            }
        )
    }

    // Full-screen image preview dialog
    if (fullScreenImageUri != null) {
        Dialog(
            onDismissRequest = {
                dismissFullScreen()
            },
            properties = DialogProperties(usePlatformDefaultWidth = false)
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.9f))
            ) {
                AsyncImage(
                    model = fullScreenImageUri,
                    contentDescription = "Full screen image preview",
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(16.dp),
                    contentScale = ContentScale.Fit
                )

                // Close button at top-left
                IconButton(
                    onClick = { dismissFullScreen() },
                    modifier = Modifier
                        .align(Alignment.TopStart)
                        .padding(16.dp),
                    colors = IconButtonDefaults.iconButtonColors(
                        containerColor = Color.Black.copy(alpha = 0.5f),
                        contentColor = Color.White
                    )
                ) {
                    Icon(Icons.Default.Close, "Close preview")
                }

                // Remove button at bottom-center
                FilledTonalButton(
                    onClick = {
                        if (fullScreenImageIndex >= 0) {
                            viewModel.removeImage(fullScreenImageIndex)
                        }
                        dismissFullScreen()
                    },
                    modifier = Modifier
                        .align(Alignment.BottomCenter)
                        .padding(bottom = 48.dp),
                    colors = ButtonDefaults.filledTonalButtonColors(
                        containerColor = MaterialTheme.colorScheme.errorContainer,
                        contentColor = MaterialTheme.colorScheme.onErrorContainer
                    )
                ) {
                    Icon(
                        Icons.Default.Delete,
                        contentDescription = null,
                        modifier = Modifier.size(18.dp)
                    )
                    Spacer(Modifier.width(8.dp))
                    Text("Remove")
                }
            }
        }
    }

    // Newsletter confirmation dialog
    val confirmNewsletter = state.selectedNewsletter
    if (state.showNewsletterConfirmation && confirmNewsletter != null) {
        NewsletterConfirmationDialog(
            newsletterName = confirmNewsletter.name,
            emailSegment = state.emailSegment,
            subscriberCount = state.subscriberCount,
            postTitle = state.text.take(60),
            onConfirm = viewModel::confirmNewsletterSend,
            onDismiss = viewModel::cancelNewsletterConfirmation
        )
    }

    // Email-only confirmation dialog
    if (state.showEmailOnlyConfirmation) {
        EmailOnlyConfirmationDialog(
            postPreview = state.text.take(80),
            availableNewsletters = state.availableNewsletters,
            selectedNewsletter = state.selectedNewsletter,
            onSelectNewsletter = viewModel::selectNewsletter,
            onConfirm = viewModel::confirmEmailOnly,
            onDismiss = viewModel::cancelEmailOnly
        )
    }
}

/**
 * Newsletter options section in the publish dropdown menu.
 */
@Composable
fun NewsletterDropdownSection(
    state: ComposerUiState,
    onToggleSendAsNewsletter: () -> Unit,
    onSelectNewsletter: (GhostNewsletter) -> Unit,
    onSetEmailSegment: (String) -> Unit
) {
    // Send as newsletter switch
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClick = onToggleSendAsNewsletter)
            .padding(horizontal = 12.dp, vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(
            text = "Send as newsletter",
            style = MaterialTheme.typography.bodyMedium,
            modifier = Modifier.weight(1f)
        )
        Switch(
            checked = state.sendAsNewsletter,
            onCheckedChange = { onToggleSendAsNewsletter() },
            modifier = Modifier.padding(start = 8.dp)
        )
    }

    // Newsletter picker and segment (only when sending)
    AnimatedVisibility(
        visible = state.sendAsNewsletter,
        enter = fadeIn(SwooshMotion.quick()) + expandVertically(animationSpec = SwooshMotion.snappy()),
        exit = fadeOut(SwooshMotion.quick()) + shrinkVertically(animationSpec = SwooshMotion.snappy())
    ) {
        Column(modifier = Modifier.padding(horizontal = 12.dp)) {
            // Newsletter picker
            if (state.availableNewsletters.size > 1) {
                Text(
                    text = "Newsletter:",
                    style = MaterialTheme.typography.labelSmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    modifier = Modifier.padding(top = 4.dp)
                )
                Column(modifier = Modifier.selectableGroup()) {
                    state.availableNewsletters.forEach { newsletter ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .selectable(
                                    selected = state.selectedNewsletter?.id == newsletter.id,
                                    onClick = { onSelectNewsletter(newsletter) }
                                )
                                .padding(vertical = 4.dp),
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            RadioButton(
                                selected = state.selectedNewsletter?.id == newsletter.id,
                                onClick = { onSelectNewsletter(newsletter) }
                            )
                            Text(
                                text = newsletter.name,
                                style = MaterialTheme.typography.bodySmall,
                                modifier = Modifier.padding(start = 4.dp)
                            )
                        }
                    }
                }
            } else if (state.availableNewsletters.size == 1) {
                Text(
                    text = "Newsletter: ${state.availableNewsletters.first().name}",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    modifier = Modifier.padding(vertical = 4.dp)
                )
            }

            // Segment picker
            Text(
                text = "Send to:",
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                modifier = Modifier.padding(top = 8.dp)
            )
            val segments = listOf("all" to "All subscribers", "status:free" to "Free members", "status:-free" to "Paid members")
            Column(modifier = Modifier.selectableGroup()) {
                segments.forEach { (value, label) ->
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .selectable(
                                selected = state.emailSegment == value,
                                onClick = { onSetEmailSegment(value) }
                            )
                            .padding(vertical = 2.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        RadioButton(
                            selected = state.emailSegment == value,
                            onClick = { onSetEmailSegment(value) }
                        )
                        Text(
                            text = label,
                            style = MaterialTheme.typography.bodySmall,
                            modifier = Modifier.padding(start = 4.dp)
                        )
                    }
                }
            }

            // Warning text
            val countText = state.subscriberCount?.let { "~$it" } ?: "your"
            Text(
                text = "\u26A0 Email will be sent to $countText subscribers. This cannot be undone.",
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.error,
                modifier = Modifier.padding(vertical = 8.dp)
            )
        }
    }
}

/**
 * Confirmation dialog for newsletter sending.
 * Requires typing "WYSLIJ" to confirm.
 */
@Composable
fun NewsletterConfirmationDialog(
    newsletterName: String,
    emailSegment: String,
    subscriberCount: Int?,
    postTitle: String,
    onConfirm: () -> Unit,
    onDismiss: () -> Unit
) {
    var confirmInput by remember { mutableStateOf("") }
    val isConfirmEnabled = confirmInput == "WYSLIJ"
    val segmentLabel = when (emailSegment) {
        "all" -> "All subscribers"
        "status:free" -> "Free members"
        "status:-free" -> "Paid members"
        else -> emailSegment
    }

    AlertDialog(
        onDismissRequest = onDismiss,
        title = {
            Text(
                text = "Confirm Newsletter Send",
                style = MaterialTheme.typography.titleMedium
            )
        },
        text = {
            Column {
                Text(
                    text = "You are about to send an email newsletter:",
                    style = MaterialTheme.typography.bodyMedium
                )
                Spacer(modifier = Modifier.height(12.dp))

                // Summary card
                OutlinedCard(modifier = Modifier.fillMaxWidth()) {
                    Column(modifier = Modifier.padding(12.dp)) {
                        Text(
                            text = "Newsletter: $newsletterName",
                            style = MaterialTheme.typography.bodySmall,
                            fontWeight = FontWeight.Bold
                        )
                        Text(
                            text = "Segment: $segmentLabel",
                            style = MaterialTheme.typography.bodySmall
                        )
                        if (subscriberCount != null) {
                            Text(
                                text = "Recipients: ~$subscriberCount",
                                style = MaterialTheme.typography.bodySmall
                            )
                        }
                        Text(
                            text = "Post: ${postTitle.take(40)}${if (postTitle.length > 40) "..." else ""}",
                            style = MaterialTheme.typography.bodySmall
                        )
                    }
                }

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

                // Warning
                Text(
                    text = "\u26A0 IRREVERSIBLE: Once sent, this email cannot be recalled.",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.error,
                    fontWeight = FontWeight.Bold
                )

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

                // Confirmation input
                Text(
                    text = "Type WYSLIJ to confirm:",
                    style = MaterialTheme.typography.labelMedium
                )
                Spacer(modifier = Modifier.height(4.dp))
                OutlinedTextField(
                    value = confirmInput,
                    onValueChange = { confirmInput = it },
                    modifier = Modifier.fillMaxWidth(),
                    singleLine = true,
                    placeholder = { Text("WYSLIJ") }
                )
            }
        },
        confirmButton = {
            Button(
                onClick = onConfirm,
                enabled = isConfirmEnabled,
                colors = ButtonDefaults.buttonColors(
                    containerColor = MaterialTheme.colorScheme.error,
                    contentColor = MaterialTheme.colorScheme.onError
                )
            ) {
                Icon(
                    Icons.Default.Email,
                    contentDescription = null,
                    modifier = Modifier.size(18.dp)
                )
                Spacer(modifier = Modifier.width(8.dp))
                Text("Send Email")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    )
}

/**
 * Confirmation dialog for email-only sending.
 * Shows a warning that the post will NOT appear on the blog.
 */
@Composable
fun EmailOnlyConfirmationDialog(
    postPreview: String,
    availableNewsletters: List<GhostNewsletter>,
    selectedNewsletter: GhostNewsletter?,
    onSelectNewsletter: (GhostNewsletter) -> Unit,
    onConfirm: () -> Unit,
    onDismiss: () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        icon = {
            Icon(
                Icons.Default.Warning,
                contentDescription = null,
                tint = MaterialTheme.colorScheme.error,
                modifier = Modifier.size(32.dp)
            )
        },
        title = {
            Text(
                text = "Send via email only?",
                style = MaterialTheme.typography.titleMedium
            )
        },
        text = {
            Column {
                // Post content preview
                if (postPreview.isNotBlank()) {
                    OutlinedCard(modifier = Modifier.fillMaxWidth()) {
                        Text(
                            text = postPreview + if (postPreview.length >= 80) "..." else "",
                            style = MaterialTheme.typography.bodySmall,
                            modifier = Modifier.padding(12.dp),
                            maxLines = 3,
                            overflow = TextOverflow.Ellipsis
                        )
                    }
                    Spacer(modifier = Modifier.height(12.dp))
                }

                // Newsletter picker (only if multiple)
                if (availableNewsletters.size > 1) {
                    Text(
                        text = "Newsletter:",
                        style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                    Column(modifier = Modifier.selectableGroup()) {
                        availableNewsletters.forEach { newsletter ->
                            Row(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .selectable(
                                        selected = selectedNewsletter?.id == newsletter.id,
                                        onClick = { onSelectNewsletter(newsletter) }
                                    )
                                    .padding(vertical = 4.dp),
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                RadioButton(
                                    selected = selectedNewsletter?.id == newsletter.id,
                                    onClick = { onSelectNewsletter(newsletter) }
                                )
                                Text(
                                    text = newsletter.name,
                                    style = MaterialTheme.typography.bodySmall,
                                    modifier = Modifier.padding(start = 4.dp)
                                )
                            }
                        }
                    }
                    Spacer(modifier = Modifier.height(12.dp))
                } else if (selectedNewsletter != null) {
                    Text(
                        text = "Newsletter: ${selectedNewsletter.name}",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                    Spacer(modifier = Modifier.height(12.dp))
                }

                // Bold warning
                Text(
                    text = "This cannot be undone. Post will NOT appear on blog.",
                    style = MaterialTheme.typography.bodySmall.copy(fontWeight = FontWeight.Bold),
                    color = MaterialTheme.colorScheme.error
                )
            }
        },
        confirmButton = {
            Button(
                onClick = onConfirm,
                colors = ButtonDefaults.buttonColors(
                    containerColor = MaterialTheme.colorScheme.error,
                    contentColor = MaterialTheme.colorScheme.onError
                )
            ) {
                Text("\u2709 SEND EMAIL")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    )
}

/**
 * Displays a 2-column grid of image thumbnails with remove buttons.
 * Includes an "Add more" button at the end.
 * Images are 120dp tall and tappable for full-screen preview.
 */
@Composable
fun ImageGridPreview(
    imageUris: List<Uri>,
    onRemoveImage: (Int) -> Unit,
    onAddMore: () -> Unit,
    onImageClick: ((Int, Uri) -> Unit)? = null
) {
    val itemCount = imageUris.size + 1 // +1 for "add more" button
    val rows = (itemCount + 1) / 2 // ceiling division for 2 columns
    val gridHeight = (rows * 130).dp // 120dp + spacing

    LazyVerticalGrid(
        columns = GridCells.Fixed(2),
        modifier = Modifier
            .fillMaxWidth()
            .heightIn(max = gridHeight),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        userScrollEnabled = false
    ) {
        itemsIndexed(imageUris) { index, uri ->
            Box(
                modifier = Modifier
                    .height(120.dp)
                    .clip(MaterialTheme.shapes.medium)
                    .clickable { onImageClick?.invoke(index, uri) }
            ) {
                AsyncImage(
                    model = uri,
                    contentDescription = "Image ${index + 1}",
                    modifier = Modifier.fillMaxSize(),
                    contentScale = ContentScale.Crop
                )
                IconButton(
                    onClick = { onRemoveImage(index) },
                    modifier = Modifier.align(Alignment.TopEnd),
                    colors = IconButtonDefaults.iconButtonColors(
                        containerColor = MaterialTheme.colorScheme.surface.copy(alpha = 0.7f)
                    )
                ) {
                    Icon(
                        Icons.Default.Close, "Remove image",
                        tint = MaterialTheme.colorScheme.onSurface,
                        modifier = Modifier.size(18.dp)
                    )
                }
            }
        }

        item {
            OutlinedCard(
                onClick = onAddMore,
                modifier = Modifier.height(120.dp)
            ) {
                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center
                ) {
                    Column(horizontalAlignment = Alignment.CenterHorizontally) {
                        Icon(
                            Icons.Default.AddPhotoAlternate,
                            contentDescription = "Add more images",
                            modifier = Modifier.size(32.dp),
                            tint = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                        Spacer(modifier = Modifier.height(4.dp))
                        Text(
                            "Add more",
                            style = MaterialTheme.typography.labelSmall,
                            color = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScheduleDateTimePicker(
    onConfirm: (LocalDateTime) -> Unit,
    onDismiss: () -> Unit
) {
    val today = remember { java.time.LocalDate.now() }
    val todayMillis = remember {
        today.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()
    }
    val currentYear = remember { today.year }

    val datePickerState = rememberDatePickerState(
        selectableDates = object : SelectableDates {
            override fun isSelectableDate(utcTimeMillis: Long): Boolean {
                return utcTimeMillis >= todayMillis
            }
            override fun isSelectableYear(year: Int): Boolean {
                return year >= currentYear
            }
        }
    )
    var showTimePicker by remember { mutableStateOf(false) }
    var pastTimeError by remember { mutableStateOf(false) }

    if (!showTimePicker) {
        DatePickerDialog(
            onDismissRequest = onDismiss,
            confirmButton = {
                TextButton(onClick = {
                    if (datePickerState.selectedDateMillis != null) {
                        showTimePicker = true
                    }
                }) { Text("Next") }
            },
            dismissButton = {
                TextButton(onClick = onDismiss) { Text("Cancel") }
            }
        ) {
            DatePicker(state = datePickerState)
        }
    } else {
        val timePickerState = rememberTimePickerState()
        AlertDialog(
            onDismissRequest = onDismiss,
            title = { Text("Select Time") },
            text = {
                Column {
                    TimePicker(state = timePickerState)
                    if (pastTimeError) {
                        Spacer(modifier = Modifier.height(8.dp))
                        Text(
                            text = "Cannot schedule in the past",
                            color = MaterialTheme.colorScheme.error,
                            style = MaterialTheme.typography.bodySmall
                        )
                    }
                }
            },
            confirmButton = {
                TextButton(onClick = {
                    val millis = datePickerState.selectedDateMillis
                    if (millis == null) {
                        onDismiss()
                        return@TextButton
                    }
                    val date = java.time.Instant.ofEpochMilli(millis)
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate()
                    val dateTime = date.atTime(timePickerState.hour, timePickerState.minute)
                    if (dateTime.isBefore(LocalDateTime.now())) {
                        pastTimeError = true
                    } else {
                        onConfirm(dateTime)
                    }
                }) { Text("Schedule") }
            },
            dismissButton = {
                TextButton(onClick = onDismiss) { Text("Cancel") }
            }
        )
    }
}

/**
 * VisualTransformation that highlights #hashtags in a different color.
 */
class HashtagVisualTransformation(private val hashtagColor: Color) : VisualTransformation {
    override fun filter(text: androidx.compose.ui.text.AnnotatedString): TransformedText {
        val ranges = HashtagParser.findHashtagRanges(text.text)
        if (ranges.isEmpty()) {
            return TransformedText(text, OffsetMapping.Identity)
        }

        val annotated = buildAnnotatedString {
            append(text.text)
            for (range in ranges) {
                val safeEnd = minOf(range.last + 1, text.text.length)
                addStyle(
                    SpanStyle(color = hashtagColor),
                    start = range.first,
                    end = safeEnd
                )
            }
        }
        return TransformedText(annotated, OffsetMapping.Identity)
    }
}

/**
 * Compact preview card for attached video or audio files.
 * Shows an icon, label, filename (from URI), and a remove button.
 */
@Composable
fun MediaPreviewCard(
    icon: androidx.compose.ui.graphics.vector.ImageVector,
    label: String,
    uri: Uri?,
    onRemove: () -> Unit
) {
    val context = LocalContext.current
    val fileName = remember(uri) {
        uri?.let { mediaUri ->
            try {
                context.contentResolver.query(mediaUri, null, null, null, null)?.use { cursor ->
                    val nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
                    if (cursor.moveToFirst() && nameIndex >= 0) {
                        cursor.getString(nameIndex)
                    } else null
                }
            } catch (_: Exception) {
                null
            } ?: mediaUri.lastPathSegment ?: "Unknown file"
        } ?: "Unknown file"
    }

    val fileSize = remember(uri) {
        uri?.let { mediaUri ->
            try {
                context.contentResolver.query(mediaUri, null, null, null, null)?.use { cursor ->
                    val sizeIndex = cursor.getColumnIndex(android.provider.OpenableColumns.SIZE)
                    if (cursor.moveToFirst() && sizeIndex >= 0) {
                        formatFileSize(cursor.getLong(sizeIndex))
                    } else null
                }
            } catch (_: Exception) {
                null
            }
        }
    }

    OutlinedCard(modifier = Modifier.fillMaxWidth()) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(12.dp),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.weight(1f)
            ) {
                Icon(
                    imageVector = icon,
                    contentDescription = null,
                    modifier = Modifier.size(24.dp),
                    tint = MaterialTheme.colorScheme.primary
                )
                Spacer(modifier = Modifier.width(12.dp))
                Column {
                    Text(
                        text = fileName,
                        style = MaterialTheme.typography.bodyMedium,
                        maxLines = 1,
                        overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
                    )
                    if (fileSize != null) {
                        Text(
                            text = fileSize,
                            style = MaterialTheme.typography.labelSmall,
                            color = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }
            IconButton(onClick = onRemove) {
                Icon(Icons.Default.Close, "Remove $label", Modifier.size(18.dp))
            }
        }
    }
}

/**
 * Tag input section with autocomplete suggestions and tag chips.
 */
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun TagsSection(
    tagInput: String,
    onTagInputChange: (String) -> Unit,
    tagSuggestions: List<GhostTagFull>,
    extractedTags: List<String>,
    onAddTag: (String) -> Unit,
    onRemoveTag: (String) -> Unit
) {
    Column {
        Text(
            text = "Tags:",
            style = MaterialTheme.typography.labelMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )

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

        // Tag input field
        Box {
            OutlinedTextField(
                value = tagInput,
                onValueChange = onTagInputChange,
                modifier = Modifier.fillMaxWidth(),
                placeholder = { Text("Add a tag...") },
                singleLine = true,
                leadingIcon = {
                    Icon(
                        Icons.Default.Tag,
                        contentDescription = null,
                        modifier = Modifier.size(18.dp)
                    )
                }
            )

            // Suggestions dropdown
            DropdownMenu(
                expanded = tagSuggestions.isNotEmpty() || tagInput.isNotBlank(),
                onDismissRequest = { onTagInputChange("") },
                modifier = Modifier.fillMaxWidth(0.9f)
            ) {
                tagSuggestions.take(5).forEach { tag ->
                    DropdownMenuItem(
                        text = {
                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text(tag.name)
                                if (tag.count?.posts != null) {
                                    Text(
                                        "(${tag.count.posts})",
                                        style = MaterialTheme.typography.bodySmall,
                                        color = MaterialTheme.colorScheme.onSurfaceVariant
                                    )
                                }
                            }
                        },
                        onClick = { onAddTag(tag.name) }
                    )
                }

                // "Create new" option when input doesn't exactly match an existing tag
                if (tagInput.isNotBlank() && tagSuggestions.none {
                        it.name.equals(tagInput, ignoreCase = true)
                    }) {
                    DropdownMenuItem(
                        text = {
                            Text(
                                "+ Create '$tagInput' as new",
                                color = MaterialTheme.colorScheme.primary
                            )
                        },
                        onClick = { onAddTag(tagInput) }
                    )
                }
            }
        }

        // Added tags as chips
        AnimatedVisibility(
            visible = extractedTags.isNotEmpty(),
            enter = fadeIn(SwooshMotion.quick()) + expandVertically(animationSpec = SwooshMotion.snappy()),
            exit = fadeOut(SwooshMotion.quick()) + shrinkVertically(animationSpec = SwooshMotion.snappy())
        ) {
            Column {
                Spacer(modifier = Modifier.height(8.dp))
                FlowRow(
                    horizontalArrangement = Arrangement.spacedBy(6.dp),
                    verticalArrangement = Arrangement.spacedBy(4.dp)
                ) {
                    extractedTags.forEach { tag ->
                        InputChip(
                            selected = false,
                            onClick = { onRemoveTag(tag) },
                            label = {
                                Text(
                                    "#$tag",
                                    style = MaterialTheme.typography.labelSmall
                                )
                            },
                            trailingIcon = {
                                Icon(
                                    Icons.Default.Close,
                                    contentDescription = "Remove tag $tag",
                                    modifier = Modifier.size(14.dp)
                                )
                            },
                            colors = InputChipDefaults.inputChipColors(
                                containerColor = MaterialTheme.colorScheme.primaryContainer,
                                labelColor = MaterialTheme.colorScheme.onPrimaryContainer
                            ),
                            border = null
                        )
                    }
                }
            }
        }
    }
}


/**
 * Formats file size in human-readable units.
 */
private fun formatFileSize(bytes: Long): String {
    return when {
        bytes < 1024 -> "$bytes B"
        bytes < 1024 * 1024 -> "${bytes / 1024} KB"
        else -> String.format("%.1f MB", bytes / (1024.0 * 1024.0))
    }
}

/**
 * File attachment card shown in the composer with file info and remove button.
 */
@Composable
fun FileAttachmentComposerCard(
    fileName: String,
    fileSize: Long,
    fileMimeType: String?,
    onRemove: () -> Unit
) {
    val iconTint = com.swoosh.microblog.ui.components.fileTypeColor(mimeType = fileMimeType)

    OutlinedCard(modifier = Modifier.fillMaxWidth()) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(12.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(
                Icons.Default.InsertDriveFile,
                contentDescription = "File",
                modifier = Modifier.size(32.dp),
                tint = iconTint
            )
            Spacer(modifier = Modifier.width(12.dp))
            Column(modifier = Modifier.weight(1f)) {
                Text(
                    text = fileName,
                    style = MaterialTheme.typography.bodyMedium,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
                if (fileSize > 0) {
                    Text(
                        text = formatFileSize(fileSize),
                        style = MaterialTheme.typography.labelSmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
            }
            IconButton(onClick = onRemove) {
                Icon(
                    Icons.Default.Close,
                    contentDescription = "Remove file",
                    modifier = Modifier.size(18.dp)
                )
            }
        }
    }
}
