package ru.forbion.f7cloud.feature.mail

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.IconButton
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.DialogProperties
import coil.compose.AsyncImage
import kotlin.OptIn
import ru.forbion.f7cloud.core.designsystem.F7Colors
import ru.forbion.f7cloud.core.designsystem.F7ListCard
import ru.forbion.f7cloud.core.designsystem.F7OutlinedField
import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton
import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton
import ru.forbion.f7cloud.core.designsystem.f7SwipeFromRightToDismiss
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import kotlin.math.abs
import android.app.DatePickerDialog

private val StarColor = Color(0xFFF9CF3D)
private val MailAvatarBackground = Color(0xFFE8F5D6)
private val MailAvatarForeground = Color(0xFF5A7A2E)
private val MailCardSurface = Color(0xFFFDFDFD)

@Composable
fun MailInboxToolbar(
    serverUrl: String,
    query: String,
    onQueryChange: (String) -> Unit,
    onComposeClick: () -> Unit,
    onFilterClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val base = serverUrl.trimEnd('/')
    Row(
        modifier = modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Box(
            modifier = Modifier
                .weight(1f)
                .height(40.dp)
                .shadow(
                    elevation = 2.dp,
                    shape = RoundedCornerShape(100.dp),
                    spotColor = Color(0xFFCBCBCB),
                )
                .clip(RoundedCornerShape(100.dp))
                .background(MailCardSurface)
                .border(1.dp, F7Colors.Border, RoundedCornerShape(100.dp)),
            contentAlignment = Alignment.CenterStart,
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight()
                    .padding(start = 12.dp, end = 44.dp),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                AsyncImage(
                    model = "$base/themes/forbion/images/search-gray.svg",
                    contentDescription = null,
                    modifier = Modifier.size(16.dp),
                    contentScale = ContentScale.Fit,
                )
                BasicTextField(
                    value = query,
                    onValueChange = onQueryChange,
                    modifier = Modifier
                        .weight(1f)
                        .padding(horizontal = 8.dp),
                    singleLine = true,
                    textStyle = TextStyle(
                        fontSize = 14.sp,
                        fontWeight = FontWeight.Medium,
                        color = F7Colors.TextPrimary,
                        platformStyle = PlatformTextStyle(includeFontPadding = false),
                    ),
                    cursorBrush = SolidColor(F7Colors.Primary),
                    decorationBox = { inner ->
                        Box(
                            modifier = Modifier.fillMaxHeight(),
                            contentAlignment = Alignment.CenterStart,
                        ) {
                            if (query.isEmpty()) {
                                Text(
                                    "Поиск",
                                    style = TextStyle(
                                        fontSize = 14.sp,
                                        fontWeight = FontWeight.Medium,
                                        color = F7Colors.TextSecondary,
                                        platformStyle = PlatformTextStyle(includeFontPadding = false),
                                    ),
                                )
                            }
                            inner()
                        }
                    },
                )
            }
            if (query.isNotEmpty()) {
                Box(
                    modifier = Modifier
                        .align(Alignment.CenterEnd)
                        .padding(end = 44.dp)
                        .size(24.dp)
                        .clip(CircleShape)
                        .clickable { onQueryChange("") },
                    contentAlignment = Alignment.Center,
                ) {
                    Text("✕", fontSize = 14.sp, color = F7Colors.TextSecondary)
                }
            }
            Box(
                modifier = Modifier
                    .align(Alignment.CenterEnd)
                    .padding(end = 12.dp)
                    .size(24.dp)
                    .clip(CircleShape)
                    .clickable(onClick = onFilterClick),
                contentAlignment = Alignment.Center,
            ) {
                AsyncImage(
                    model = "$base/themes/forbion/images/mail/filter-sliders-gray.svg",
                    contentDescription = "Фильтр",
                    modifier = Modifier.size(16.dp),
                    contentScale = ContentScale.Fit,
                )
            }
        }
        MailComposeButton(
            serverUrl = serverUrl,
            onClick = onComposeClick,
        )
    }
}

@Composable
fun MailQuickFilterChips(
    searchParams: MailSearchParams,
    onFilterToggle: (MailQuickFilter) -> Unit,
    modifier: Modifier = Modifier,
) {
    LazyRow(
        modifier = modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        items(MailQuickFilter.entries.toList(), key = { it.name }) { filter ->
            MailQuickFilterChip(
                label = filter.label,
                selected = searchParams.isQuickFilterActive(filter),
                onClick = { onFilterToggle(filter) },
            )
        }
    }
}

@Composable
private fun MailQuickFilterChip(
    label: String,
    selected: Boolean,
    onClick: () -> Unit,
) {
    val background = if (selected) F7Colors.PrimaryLight else MailCardSurface
    val borderColor = if (selected) F7Colors.Primary.copy(alpha = 0.35f) else F7Colors.Border
    Text(
        label,
        modifier = Modifier
            .clip(RoundedCornerShape(100.dp))
            .background(background)
            .border(1.dp, borderColor, RoundedCornerShape(100.dp))
            .clickable(onClick = onClick)
            .padding(horizontal = 14.dp, vertical = 8.dp),
        style = MaterialTheme.typography.labelMedium,
        fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
        color = if (selected) F7Colors.Primary else F7Colors.TextPrimary,
        maxLines = 1,
    )
}

@Composable
fun MailYearHeader(
    year: Int,
    modifier: Modifier = Modifier,
) {
    Text(
        year.toString(),
        modifier = modifier
            .fillMaxWidth()
            .padding(top = 4.dp, bottom = 2.dp),
        style = MaterialTheme.typography.titleSmall,
        fontWeight = FontWeight.SemiBold,
        color = F7Colors.TextSecondary,
    )
}

@Composable
private fun MailComposeButton(
    serverUrl: String,
    onClick: () -> Unit,
) {
    val base = serverUrl.trimEnd('/')
    val shape = CircleShape
    Box(
        modifier = Modifier
            .size(40.dp)
            .shadow(
                elevation = 2.dp,
                shape = shape,
                spotColor = Color(0xFFE6E6E6),
            )
            .clip(shape)
            .background(
                brush = Brush.linearGradient(
                    colors = listOf(F7Colors.PrimaryGradientStart, F7Colors.PrimaryGradientEnd),
                ),
            )
            .border(1.dp, F7Colors.Primary.copy(alpha = 0.22f), shape)
            .clickable(onClick = onClick),
        contentAlignment = Alignment.Center,
    ) {
        AsyncImage(
            model = "$base/themes/forbion/images/tasks/plus-white.svg",
            contentDescription = "Новое письмо",
            modifier = Modifier.size(18.dp),
            contentScale = ContentScale.Fit,
        )
    }
}

@Composable
fun MailNavigationSidebar(
    serverUrl: String,
    visible: Boolean,
    accounts: List<MailAccount>,
    folders: List<MailFolderEntry>,
    selected: MailFolderEntry?,
    collapsedAccountIds: Set<Int>,
    onDismiss: () -> Unit,
    onComposeClick: () -> Unit,
    onRefreshClick: () -> Unit,
    onFolderClick: (MailFolderEntry) -> Unit,
    onToggleAccountCollapsed: (Int) -> Unit,
    onPriorityInboxClick: () -> Unit,
    onOutboxClick: () -> Unit,
) {
    val base = serverUrl.trimEnd('/')
    AnimatedVisibility(
        visible = visible,
        enter = slideInHorizontally(initialOffsetX = { -it }),
        exit = slideOutHorizontally(targetOffsetX = { -it }),
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .f7SwipeFromRightToDismiss(onDismiss = onDismiss),
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = 0.18f))
                    .clickable(
                        interactionSource = remember { MutableInteractionSource() },
                        indication = null,
                        onClick = onDismiss,
                    ),
            )
            Column(
                modifier = Modifier
                    .fillMaxHeight()
                    .fillMaxWidth(0.9f)
                    .background(F7Colors.Background)
                    .verticalScroll(rememberScrollState())
                    .padding(horizontal = 12.dp, vertical = 12.dp),
            ) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Row(
                        modifier = Modifier
                            .weight(1f)
                            .height(40.dp)
                            .clip(RoundedCornerShape(100.dp))
                            .background(
                                brush = Brush.linearGradient(
                                    colors = listOf(F7Colors.PrimaryGradientStart, F7Colors.PrimaryGradientEnd),
                                ),
                            )
                            .border(1.dp, F7Colors.Primary.copy(alpha = 0.22f), RoundedCornerShape(100.dp))
                            .clickable(onClick = onComposeClick)
                            .padding(horizontal = 14.dp),
                        verticalAlignment = Alignment.CenterVertically,
                    ) {
                        Text(
                            "Создать сообщение",
                            modifier = Modifier.weight(1f),
                            style = MaterialTheme.typography.labelLarge,
                            color = F7Colors.TextOnPrimary,
                            maxLines = 1,
                            overflow = TextOverflow.Ellipsis,
                        )
                        Box(
                            modifier = Modifier
                                .padding(horizontal = 10.dp)
                                .width(1.dp)
                                .height(18.dp)
                                .background(Color.White.copy(alpha = 0.45f)),
                        )
                        AsyncImage(
                            model = "$base/themes/forbion/images/tasks/plus-white.svg",
                            contentDescription = null,
                            modifier = Modifier.size(16.dp),
                            contentScale = ContentScale.Fit,
                        )
                    }
                    Box(
                        modifier = Modifier
                            .size(40.dp)
                            .clip(CircleShape)
                            .background(Color(0xFFFDFDFD))
                            .border(1.dp, F7Colors.Border, CircleShape)
                            .clickable(onClick = onRefreshClick),
                        contentAlignment = Alignment.Center,
                    ) {
                        AsyncImage(
                            model = "$base/themes/forbion/images/files/reload-black.svg",
                            contentDescription = "Обновить",
                            modifier = Modifier.size(18.dp),
                            contentScale = ContentScale.Fit,
                        )
                    }
                }
                Spacer(Modifier.height(12.dp))
                MailSidebarRow(
                    serverUrl = serverUrl,
                    iconPath = "mail/message-icon-gray.svg",
                    title = "Приоритетные входящие",
                    selected = selected?.specialRole == "inbox" && selected.filter == MailListFilter.ALL,
                    onClick = onPriorityInboxClick,
                )
                MailSidebarRow(
                    serverUrl = serverUrl,
                    iconPath = "mail/outbox-unsent-16.svg",
                    title = "Исходящие",
                    selected = selected?.specialRole == "outbox",
                    onClick = onOutboxClick,
                )
                Spacer(Modifier.height(8.dp))
                val accountList = accounts.ifEmpty {
                    listOf(MailAccount(0, "", "", null, null, null, null, null))
                }
                accountList.forEach { account ->
                    val accountFolders = folders.filter { it.accountId == account.id || account.id == 0 }
                    val collapsed = account.id != 0 && account.id in collapsedAccountIds
                    if (account.email.isNotBlank() && account.id != 0) {
                        MailAccountHeader(
                            email = account.email,
                            menuIconUrl = "$base/themes/forbion/images/mail/dots-icon-black.svg",
                            chevronIconUrl = "$base/themes/forbion/images/mail/nav-chevron-down-gray.svg",
                            expanded = !collapsed,
                            onToggleExpanded = { onToggleAccountCollapsed(account.id) },
                        )
                        HorizontalDivider(
                            modifier = Modifier.padding(bottom = 8.dp),
                            color = F7Colors.Border,
                        )
                    }
                    if (!collapsed) {
                        accountFolders.forEach { folder ->
                            val isSelected = selected?.let {
                                it.mailboxId == folder.mailboxId && it.filter == folder.filter
                            } == true
                            MailSidebarFolderRow(
                                serverUrl = serverUrl,
                                folder = folder,
                                selected = isSelected,
                                onClick = { onFolderClick(folder) },
                            )
                        }
                    }
                    Spacer(Modifier.height(8.dp))
                }
            }
        }
    }
}

@Composable
private fun MailAccountHeader(
    email: String,
    menuIconUrl: String,
    chevronIconUrl: String,
    expanded: Boolean,
    onToggleExpanded: () -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 4.dp, vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        Box(
            modifier = Modifier
                .size(8.dp)
                .clip(CircleShape)
                .background(F7Colors.Primary),
        )
        Text(
            email,
            modifier = Modifier.weight(1f),
            style = MaterialTheme.typography.bodyMedium,
            fontWeight = FontWeight.Medium,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
        AsyncImage(
            model = menuIconUrl,
            contentDescription = null,
            modifier = Modifier.size(16.dp),
            contentScale = ContentScale.Fit,
        )
        Box(
            modifier = Modifier
                .size(28.dp)
                .clip(RoundedCornerShape(6.dp))
                .clickable(
                    interactionSource = remember { MutableInteractionSource() },
                    indication = null,
                    onClick = onToggleExpanded,
                ),
            contentAlignment = Alignment.Center,
        ) {
            AsyncImage(
                model = chevronIconUrl,
                contentDescription = if (expanded) "Свернуть папки" else "Показать папки",
                modifier = Modifier
                    .size(14.dp)
                    .graphicsLayer { rotationZ = if (expanded) 0f else 180f },
                contentScale = ContentScale.Fit,
            )
        }
    }
}

@Composable
private fun MailSidebarRow(
    serverUrl: String,
    iconPath: String,
    title: String,
    onClick: () -> Unit,
    unread: Int? = null,
    showChevron: Boolean = false,
    selected: Boolean = false,
) {
    val base = serverUrl.trimEnd('/')
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clip(RoundedCornerShape(8.dp))
            .background(if (selected) F7Colors.PrimaryLight else Color.Transparent)
            .clickable(onClick = onClick)
            .padding(horizontal = 8.dp, vertical = 10.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(10.dp),
    ) {
        AsyncImage(
            model = "$base/themes/forbion/images/$iconPath",
            contentDescription = null,
            modifier = Modifier.size(16.dp),
            contentScale = ContentScale.Fit,
        )
        Text(
            title,
            modifier = Modifier.weight(1f),
            style = MaterialTheme.typography.bodyMedium,
            fontWeight = FontWeight.Medium,
            color = F7Colors.TextPrimary,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
        if (unread != null && unread > 0) {
            // Живая тема: счётчик 16/500, серый, без фона
            Text(
                unread.toString(),
                style = MaterialTheme.typography.bodyLarge,
                fontWeight = FontWeight.Medium,
                color = F7Colors.TextSecondary,
            )
        }
        if (showChevron) {
            AsyncImage(
                model = "$base/themes/forbion/images/mail/nav-chevron-down-gray.svg",
                contentDescription = null,
                modifier = Modifier.size(14.dp),
                contentScale = ContentScale.Fit,
            )
        }
    }
}

@Composable
private fun MailSidebarFolderRow(
    serverUrl: String,
    folder: MailFolderEntry,
    selected: Boolean,
    onClick: () -> Unit,
) {
    val showUnread = folder.filter == MailListFilter.ALL ||
        folder.filter == MailListFilter.UNREAD
    MailSidebarRow(
        serverUrl = serverUrl,
        iconPath = folderIconPath(folder),
        title = folder.title,
        onClick = onClick,
        unread = if (showUnread && folder.unread > 0) folder.unread else null,
        showChevron = folder.filter != MailListFilter.ALL || folder.specialRole == "inbox",
        selected = selected,
    )
}

private fun folderIconPath(folder: MailFolderEntry): String = when {
    folder.filter == MailListFilter.STARRED -> "mail/star-gray.svg"
    folder.filter == MailListFilter.UNREAD -> "mail/all-new-message-gray.svg"
    folder.specialRole == "inbox" -> "mail/all-new-message-gray.svg"
    folder.specialRole == "sent" -> "mail/send-message-gray.svg"
    folder.specialRole == "drafts" -> "mail/edit-icon-gray.svg"
    folder.specialRole == "trash" -> "mail/basket-gray.svg"
    folder.specialRole == "archive" -> "mail/arhiv-gray.svg"
    folder.specialRole == "junk" -> "mail/spam-icon-gray.svg"
    else -> "mail/folder-gray.svg"
}

@Composable
fun MailEnvelopeRow(
    message: MailMessage,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    serverUrl: String = "",
) {
    val unread = !message.flags.seen
    val sender = message.fromEmail.takeIf { it.isNotBlank() }
        ?: message.from.takeIf { it.isNotBlank() && !it.equals("Unknown", ignoreCase = true) }
        ?: "Неизвестный"
    // Живая тема (_mobile-mail.css): карточка #FDFDFD r8, нижняя граница #E6E6E6 + тень #CBCBCB,
    // отправитель 16/500 чёрный, тема 14/600 и превью/дата 14/500 — чёрный 50%.
    val fadedColor = Color(0x80151515)
    val subject = message.subject.ifBlank { "(без темы)" }

    Box(
        modifier = modifier
            .fillMaxWidth()
            .shadow(
                elevation = 1.dp,
                shape = RoundedCornerShape(8.dp),
                spotColor = Color(0xFFCBCBCB),
            )
            .clip(RoundedCornerShape(8.dp))
            .background(MailCardSurface)
            .drawBehind {
                drawLine(
                    color = Color(0xFFE6E6E6),
                    start = androidx.compose.ui.geometry.Offset(0f, size.height - 0.5f),
                    end = androidx.compose.ui.geometry.Offset(size.width, size.height - 0.5f),
                    strokeWidth = 1.dp.toPx(),
                )
            }
            .clickable(onClick = onClick)
            .padding(8.dp),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            MailAvatar(
                name = message.from,
                email = message.fromEmail,
                modifier = Modifier.size(40.dp),
            )
            Spacer(Modifier.width(8.dp))
            Column(modifier = Modifier.weight(1f)) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Text(
                        sender,
                        modifier = Modifier.weight(1f),
                        style = MaterialTheme.typography.bodyLarge,
                        fontWeight = FontWeight.Medium,
                        color = F7Colors.TextPrimary,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                    )
                    Text(
                        formatEnvelopeDate(message.dateInt),
                        style = MaterialTheme.typography.bodyMedium,
                        color = fadedColor,
                    )
                    if (message.flags.flagged) {
                        Spacer(Modifier.width(4.dp))
                        AsyncImage(
                            model = "${serverUrl.trimEnd('/')}/themes/forbion/images/mail/star-green-full.svg",
                            contentDescription = null,
                            modifier = Modifier.size(14.dp),
                            contentScale = ContentScale.Fit,
                        )
                    }
                }
                Text(
                    subject,
                    style = MaterialTheme.typography.bodyMedium,
                    fontWeight = FontWeight.SemiBold,
                    color = fadedColor,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
                if (message.preview.isNotBlank()) {
                    Text(
                        message.preview,
                        style = MaterialTheme.typography.bodyMedium,
                        fontWeight = FontWeight.Medium,
                        color = fadedColor,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                    )
                }
                // Теги письма цветными пилюлями (макет «Список сообщений»)
                if (message.tags.isNotEmpty()) {
                    Spacer(Modifier.height(4.dp))
                    Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
                        message.tags.take(4).forEach { MailTagChip(it) }
                    }
                }
            }
            if (unread) {
                Spacer(Modifier.width(6.dp))
                Box(
                    modifier = Modifier
                        .size(8.dp)
                        .clip(CircleShape)
                        .background(F7Colors.Primary),
                )
            }
        }
    }
}

@Composable
private fun MailTagChip(tag: MailTag) {
    val colors = tagChipColors(tag)
    Text(
        tag.displayName,
        modifier = Modifier
            .clip(RoundedCornerShape(100.dp))
            .background(colors.background)
            .padding(horizontal = 10.dp, vertical = 4.dp),
        style = MaterialTheme.typography.labelSmall,
        fontWeight = FontWeight.Medium,
        color = colors.text,
        maxLines = 1,
    )
}

private data class TagChipColors(val background: Color, val text: Color)

private fun tagChipColors(tag: MailTag): TagChipColors {
    val parsed = parseHexColor(tag.colorHex)
    if (parsed != null) {
        return TagChipColors(
            background = parsed.copy(alpha = 0.18f),
            text = parsed.copy(alpha = 0.95f),
        )
    }
    // Точные цвета чипов из макета «Почта · Список сообщений» (Figma, сняты пипеткой)
    return when (tag.displayName.lowercase(Locale("ru"))) {
        "работа", "work" -> TagChipColors(Color(0xFFDAEDD6), Color(0xFF28A413))
        "позже", "later" -> TagChipColors(Color(0xFFF1EEE0), Color(0xFFC1B464))
        "личное", "personal" -> TagChipColors(Color(0xFFEFE4FB), Color(0xFFB574F7))
        else -> TagChipColors(F7Colors.SurfaceMuted, F7Colors.TextSecondary)
    }
}

private fun parseHexColor(hex: String): Color? {
    val value = hex.trim()
    if (value.isBlank()) return null
    return runCatching {
        Color(android.graphics.Color.parseColor(if (value.startsWith("#")) value else "#$value"))
    }.getOrNull()
}

@Composable
fun MailThreadSection(
    currentMessageId: Int,
    threadMessages: List<MailMessage>,
    expanded: Boolean,
    onToggleExpanded: () -> Unit,
    onMessageClick: (Int) -> Unit,
    modifier: Modifier = Modifier,
) {
    if (threadMessages.size <= 1) return
    Column(
        modifier = modifier
            .fillMaxWidth()
            .clip(RoundedCornerShape(12.dp))
            .background(F7Colors.SurfaceMuted)
            .padding(12.dp),
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clickable(onClick = onToggleExpanded),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(
                if (expanded) "Скрыть переписку" else "Переписка (${threadMessages.size})",
                style = MaterialTheme.typography.labelLarge,
                fontWeight = FontWeight.SemiBold,
                color = F7Colors.TextPrimary,
            )
            Text(
                if (expanded) "▲" else "▼",
                color = F7Colors.TextSecondary,
            )
        }
        AnimatedVisibility(visible = expanded) {
            Column(
                modifier = Modifier.padding(top = 8.dp),
                verticalArrangement = Arrangement.spacedBy(6.dp),
            ) {
                threadMessages.sortedByDescending { it.dateInt }.forEach { message ->
                    MailThreadMessageRow(
                        message = message,
                        selected = message.id == currentMessageId,
                        onClick = {
                            if (message.id != currentMessageId) onMessageClick(message.id)
                        },
                    )
                }
            }
        }
    }
}

@Composable
private fun MailThreadMessageRow(
    message: MailMessage,
    selected: Boolean,
    onClick: () -> Unit,
) {
    val background = if (selected) F7Colors.PrimaryLight else MailCardSurface
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clip(RoundedCornerShape(8.dp))
            .background(background)
            .then(if (!selected) Modifier.clickable(onClick = onClick) else Modifier)
            .padding(10.dp),
        verticalAlignment = Alignment.Top,
    ) {
        MailAvatar(name = message.from, email = message.fromEmail, modifier = Modifier.size(32.dp))
        Spacer(Modifier.width(8.dp))
        Column(modifier = Modifier.weight(1f)) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text(
                    message.from.ifBlank { message.fromEmail }.ifBlank { "Неизвестный" },
                    style = MaterialTheme.typography.bodySmall,
                    fontWeight = FontWeight.SemiBold,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                    modifier = Modifier.weight(1f),
                )
                Spacer(Modifier.width(8.dp))
                Text(
                    formatEnvelopeDate(message.dateInt),
                    style = MaterialTheme.typography.labelSmall,
                    color = F7Colors.TextSecondary,
                )
            }
            if (message.preview.isNotBlank()) {
                Text(
                    message.preview,
                    style = MaterialTheme.typography.bodySmall,
                    color = F7Colors.TextSecondary,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis,
                    modifier = Modifier.padding(top = 2.dp),
                )
            }
        }
    }
}

@Composable
fun MailDetailBackButton(
    serverUrl: String,
    onBack: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val base = serverUrl.trimEnd('/')
    Box(
        modifier = modifier
            .size(40.dp)
            .clip(CircleShape)
            .clickable(onClick = onBack),
        contentAlignment = Alignment.Center,
    ) {
        AsyncImage(
            model = "$base/themes/forbion/images/mail/arrow-back-gray.svg",
            contentDescription = "Назад",
            modifier = Modifier.size(20.dp),
            contentScale = ContentScale.Fit,
        )
    }
}

@Composable
fun MailDetailTopBar(
    subject: String,
    accountEmail: String,
    serverUrl: String,
    onBack: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val base = serverUrl.trimEnd('/')
    Column(
        modifier = modifier
            .fillMaxWidth()
            .background(F7Colors.Surface)
            .padding(horizontal = 8.dp, vertical = 8.dp),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Box(
                modifier = Modifier
                    .size(40.dp)
                    .clip(CircleShape)
                    .clickable(onClick = onBack),
                contentAlignment = Alignment.Center,
            ) {
                AsyncImage(
                    model = "$base/themes/forbion/images/mail/arrow-back-gray.svg",
                    contentDescription = "Назад",
                    modifier = Modifier.size(20.dp),
                    contentScale = ContentScale.Fit,
                )
            }
            Column(
                modifier = Modifier
                    .weight(1f)
                    .padding(end = 40.dp),
            ) {
                Text(
                    subject.ifBlank { "(без темы)" },
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.SemiBold,
                    color = F7Colors.TextPrimary,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis,
                )
                if (accountEmail.isNotBlank()) {
                    Spacer(Modifier.height(4.dp))
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text(
                            "От:",
                            style = MaterialTheme.typography.bodySmall,
                            color = F7Colors.TextSecondary,
                        )
                        Spacer(Modifier.width(6.dp))
                        MailAvatar(
                            name = accountEmail,
                            email = accountEmail,
                            modifier = Modifier.size(20.dp),
                        )
                        Spacer(Modifier.width(6.dp))
                        Text(
                            accountEmail,
                            style = MaterialTheme.typography.bodySmall,
                            color = F7Colors.TextSecondary,
                            maxLines = 1,
                            overflow = TextOverflow.Ellipsis,
                        )
                    }
                }
            }
        }
    }
}

@Composable
fun MailMessageSenderCard(
    fromName: String,
    fromEmail: String,
    subject: String,
    to: String,
    cc: String,
    dateInt: Long,
    flagged: Boolean,
    seen: Boolean,
    important: Boolean,
    serverUrl: String,
    onReply: () -> Unit,
    onToggleStar: () -> Unit,
    onMarkUnread: () -> Unit,
    onDelete: () -> Unit,
    onToggleImportant: () -> Unit,
    onForward: () -> Unit,
    onMarkSpam: () -> Unit,
    onEditTags: () -> Unit,
    onMove: () -> Unit,
    onSnooze: () -> Unit,
    modifier: Modifier = Modifier,
    onCreateTask: (() -> Unit)? = null,
    onCreateEvent: (() -> Unit)? = null,
) {
    val base = serverUrl.trimEnd('/')
    var headersExpanded by remember { mutableStateOf(false) }
    var menuOpen by remember { mutableStateOf(false) }
    val displayEmail = fromEmail.ifBlank { fromName }
    val displayName = fromName.ifBlank { displayEmail }.ifBlank { "Неизвестный" }
    val showEmailLine = displayEmail.isNotBlank() &&
        !displayEmail.equals(displayName, ignoreCase = true)
    val displaySubject = subject.ifBlank { "(без темы)" }
    val hasHeaderDetails = showEmailLine || to.isNotBlank() || cc.isNotBlank()

    Column(
        modifier = modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 8.dp)
            .shadow(
                elevation = 1.dp,
                shape = RoundedCornerShape(12.dp),
                spotColor = Color(0x14000000),
            )
            .clip(RoundedCornerShape(12.dp))
            .background(MailCardSurface)
            .border(1.dp, F7Colors.Border.copy(alpha = 0.45f), RoundedCornerShape(12.dp))
            .padding(12.dp),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.Top,
        ) {
            MailAvatar(
                name = fromName,
                email = fromEmail,
                modifier = Modifier.size(40.dp),
            )
            Spacer(Modifier.width(8.dp))
            Column(modifier = Modifier.weight(1f)) {
                Text(
                    displayName,
                    modifier = Modifier.fillMaxWidth(),
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Medium,
                    color = F7Colors.TextPrimary,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .then(
                            if (hasHeaderDetails) {
                                Modifier
                                    .clip(RoundedCornerShape(8.dp))
                                    .clickable { headersExpanded = !headersExpanded }
                            } else {
                                Modifier
                            },
                        )
                        .padding(top = 4.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Text(
                        displaySubject,
                        modifier = Modifier.weight(1f),
                        style = MaterialTheme.typography.bodySmall,
                        color = F7Colors.TextSecondary,
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis,
                    )
                    if (hasHeaderDetails) {
                        Text(
                            if (headersExpanded) "▴" else "▾",
                            color = F7Colors.TextSecondary,
                            fontSize = 12.sp,
                        )
                    }
                }
                if (headersExpanded) {
                    if (showEmailLine) {
                        Text(
                            displayEmail,
                            style = MaterialTheme.typography.bodySmall,
                            color = F7Colors.TextSecondary,
                            modifier = Modifier.padding(top = 4.dp),
                            maxLines = 1,
                            overflow = TextOverflow.Ellipsis,
                        )
                    }
                    if (to.isNotBlank()) {
                        Text(
                            "Кому: $to",
                            style = MaterialTheme.typography.bodySmall,
                            color = F7Colors.TextSecondary,
                            modifier = Modifier.padding(top = 4.dp),
                        )
                    }
                    if (cc.isNotBlank()) {
                        Text(
                            "Копия: $cc",
                            style = MaterialTheme.typography.bodySmall,
                            color = F7Colors.TextSecondary,
                            modifier = Modifier.padding(top = 2.dp),
                        )
                    }
                }
            }
            Column(
                horizontalAlignment = Alignment.End,
                verticalArrangement = Arrangement.Top,
            ) {
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(2.dp),
                ) {
                    if (dateInt > 0) {
                        Text(
                            formatEnvelopeDate(dateInt),
                            style = MaterialTheme.typography.labelSmall,
                            color = F7Colors.TextSecondary,
                            modifier = Modifier.padding(end = 2.dp),
                        )
                    }
                    Box {
                        MailMessageIconButton(
                            iconUrl = "$base/themes/forbion/images/mail/dots-icon-black.svg",
                            contentDescription = "Ещё",
                            onClick = { menuOpen = true },
                        )
                        MailMessageActionsMenu(
                            expanded = menuOpen,
                            serverUrl = serverUrl,
                            flagged = flagged,
                            seen = seen,
                            important = important,
                            onDismiss = { menuOpen = false },
                            onReply = onReply,
                            onToggleStar = onToggleStar,
                            onMarkUnread = onMarkUnread,
                            onDelete = onDelete,
                            onToggleImportant = onToggleImportant,
                            onForward = onForward,
                            onMarkSpam = onMarkSpam,
                            onEditTags = onEditTags,
                            onMove = onMove,
                            onSnooze = onSnooze,
                            onCreateTask = onCreateTask,
                            onCreateEvent = onCreateEvent,
                        )
                    }
                }
            }
        }
    }
}

@Composable
private fun MailMessageIconMenuItem(
    serverUrl: String,
    iconPath: String,
    label: String,
    onClick: () -> Unit,
) {
    val base = serverUrl.trimEnd('/')
    DropdownMenuItem(
        text = {
            Text(
                label,
                style = MaterialTheme.typography.bodyMedium,
                color = F7Colors.TextPrimary,
                maxLines = 2,
            )
        },
        leadingIcon = {
            AsyncImage(
                model = "$base/themes/forbion/images/mail/$iconPath",
                contentDescription = null,
                modifier = Modifier.size(20.dp),
                contentScale = ContentScale.Fit,
            )
        },
        onClick = onClick,
        colors = MenuDefaults.itemColors(
            textColor = F7Colors.TextPrimary,
            leadingIconColor = F7Colors.TextPrimary,
        ),
    )
}

@Composable
fun MailMessageActionsMenu(
    expanded: Boolean,
    serverUrl: String,
    flagged: Boolean,
    seen: Boolean,
    important: Boolean,
    onDismiss: () -> Unit,
    onReply: () -> Unit,
    onToggleStar: () -> Unit,
    onMarkUnread: () -> Unit,
    onDelete: () -> Unit,
    onToggleImportant: () -> Unit,
    onForward: () -> Unit,
    onMarkSpam: () -> Unit,
    onEditTags: () -> Unit,
    onMove: () -> Unit,
    onSnooze: () -> Unit,
    onCreateTask: (() -> Unit)? = null,
    onCreateEvent: (() -> Unit)? = null,
) {
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = onDismiss,
        modifier = Modifier
            .widthIn(min = 300.dp)
            .background(Color.White, RoundedCornerShape(12.dp)),
        containerColor = Color.White,
        tonalElevation = 0.dp,
        shadowElevation = 8.dp,
    ) {
        MailMessageIconMenuItem(serverUrl, "reply-icon-black.svg", "Ответить") {
            onDismiss()
            onReply()
        }
        MailMessageIconMenuItem(
            serverUrl,
            if (flagged) "star-green-full.svg" else "star-black.svg",
            if (flagged) "Снять отметку избранного" else "Отметить как избранное",
        ) {
            onDismiss()
            onToggleStar()
        }
        if (seen) {
            MailMessageIconMenuItem(serverUrl, "message-icon-black.svg", "Пометить непрочитанным") {
                onDismiss()
                onMarkUnread()
            }
        }
        MailMessageIconMenuItem(serverUrl, "basket-black.svg", "Удалить сообщение") {
            onDismiss()
            onDelete()
        }
        MailMessageIconMenuItem(
            serverUrl,
            if (important) "impotant-icon-green-full.svg" else "impotant-icon-black.svg",
            if (important) "Снять важность" else "Важное",
        ) {
            onDismiss()
            onToggleImportant()
        }
        MailMessageIconMenuItem(serverUrl, "send-message-black.svg", "Переслать") {
            onDismiss()
            onForward()
        }
        MailMessageIconMenuItem(serverUrl, "spam-icon-black.svg", "Пометить как спам") {
            onDismiss()
            onMarkSpam()
        }
        MailMessageIconMenuItem(serverUrl, "tags-black.svg", "Изменить метки") {
            onDismiss()
            onEditTags()
        }
        onCreateTask?.let { create ->
            MailMessageIconMenuItem(serverUrl, "create-task-black.svg", "Создать задачу") {
                onDismiss()
                create()
            }
        }
        onCreateEvent?.let { create ->
            MailMessageIconMenuItem(serverUrl, "calendar-black.svg", "Создать событие") {
                onDismiss()
                create()
            }
        }
        MailMessageIconMenuItem(serverUrl, "folder-black.svg", "Переместить сообщение") {
            onDismiss()
            onMove()
        }
        MailMessageIconMenuItem(serverUrl, "show-images-clock.svg", "Запланированная отправка") {
            onDismiss()
            onSnooze()
        }
    }
}

@Composable
fun MailMoveMailboxSheet(
    visible: Boolean,
    mailboxes: List<MailMailbox>,
    onDismiss: () -> Unit,
    onSelect: (MailMailbox) -> Unit,
) {
    if (!visible) return
    androidx.compose.ui.window.Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            modifier = Modifier
                .fillMaxWidth(0.92f)
                .fillMaxHeight(0.6f)
                .f7SwipeFromRightToDismiss(onDismiss = onDismiss),
            shape = RoundedCornerShape(16.dp),
            color = Color.White,
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    "Переместить сообщение",
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.SemiBold,
                )
                Spacer(Modifier.height(12.dp))
                Column(
                    modifier = Modifier
                        .weight(1f)
                        .verticalScroll(rememberScrollState()),
                    verticalArrangement = Arrangement.spacedBy(4.dp),
                ) {
                    mailboxes.forEach { mailbox ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clip(RoundedCornerShape(8.dp))
                                .clickable {
                                    onSelect(mailbox)
                                    onDismiss()
                                }
                                .padding(horizontal = 12.dp, vertical = 10.dp),
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            Text(
                                mailbox.displayName,
                                style = MaterialTheme.typography.bodyMedium,
                                color = F7Colors.TextPrimary,
                            )
                        }
                    }
                }
                Spacer(Modifier.height(8.dp))
                F7SecondaryButton("Отмена", onClick = onDismiss, modifier = Modifier.fillMaxWidth())
            }
        }
    }
}

@Composable
fun MailMessageTagsSheet(
    visible: Boolean,
    availableTags: List<MailTag>,
    selectedTags: List<MailTag>,
    onDismiss: () -> Unit,
    onToggle: (MailTag) -> Unit,
) {
    if (!visible) return
    androidx.compose.ui.window.Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            modifier = Modifier
                .fillMaxWidth(0.92f)
                .f7SwipeFromRightToDismiss(onDismiss = onDismiss),
            shape = RoundedCornerShape(16.dp),
            color = Color.White,
        ) {
            Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
                // Живая тема: заголовок модалки 18/600; строки тегов — плашки #F5F5F5 r10
                // (minHeight 36), имя тега — цветная пилюля.
                Text(
                    "Изменить метки",
                    style = MaterialTheme.typography.titleMedium.copy(fontSize = 18.sp),
                    fontWeight = FontWeight.SemiBold,
                    color = F7Colors.TextPrimary,
                )
                if (availableTags.isEmpty()) {
                    Text("Нет доступных меток", color = F7Colors.TextSecondary)
                } else {
                    availableTags.forEach { tag ->
                        val checked = selectedTags.any { it.imapLabel == tag.imapLabel && tag.imapLabel.isNotBlank() }
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .heightIn(min = 36.dp)
                                .clip(RoundedCornerShape(10.dp))
                                .background(F7Colors.SurfaceMuted)
                                .clickable { onToggle(tag) }
                                .padding(horizontal = 8.dp, vertical = 4.dp),
                            verticalAlignment = Alignment.CenterVertically,
                            horizontalArrangement = Arrangement.spacedBy(8.dp),
                        ) {
                            Checkbox(
                                checked = checked,
                                onCheckedChange = { onToggle(tag) },
                                colors = CheckboxDefaults.colors(checkedColor = F7Colors.Primary),
                            )
                            MailTagChip(tag)
                        }
                    }
                }
                Spacer(Modifier.height(8.dp))
                F7SecondaryButton("Готово", onClick = onDismiss, modifier = Modifier.fillMaxWidth())
            }
        }
    }
}

@Composable
fun MailSnoozeSheet(
    visible: Boolean,
    options: List<MailSendLaterOption>,
    onDismiss: () -> Unit,
    onSelect: (MailSendLaterOption) -> Unit,
) {
    if (!visible) return
    androidx.compose.ui.window.Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            modifier = Modifier
                .fillMaxWidth(0.92f)
                .f7SwipeFromRightToDismiss(onDismiss = onDismiss),
            shape = RoundedCornerShape(16.dp),
            color = Color.White,
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    "Запланированная отправка",
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.SemiBold,
                )
                Spacer(Modifier.height(12.dp))
                options.filter { it.preset != MailSendLaterPreset.NOW && it.sendAtEpochSeconds != null }
                    .forEach { option ->
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .clip(RoundedCornerShape(8.dp))
                                .clickable {
                                    onSelect(option)
                                    onDismiss()
                                }
                                .padding(horizontal = 12.dp, vertical = 10.dp),
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            Text(option.title, style = MaterialTheme.typography.bodyMedium)
                        }
                    }
                Spacer(Modifier.height(8.dp))
                F7SecondaryButton("Отмена", onClick = onDismiss, modifier = Modifier.fillMaxWidth())
            }
        }
    }
}

@Composable
fun MailReplyFab(
    serverUrl: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val base = serverUrl.trimEnd('/')
    val shape = RoundedCornerShape(100.dp)
    Row(
        modifier = modifier
            .shadow(
                elevation = 4.dp,
                shape = shape,
                spotColor = F7Colors.Primary.copy(alpha = 0.25f),
            )
            .clip(shape)
            .background(
                brush = Brush.linearGradient(
                    colors = listOf(F7Colors.PrimaryGradientStart, F7Colors.PrimaryGradientEnd),
                ),
            )
            .border(1.dp, F7Colors.Primary.copy(alpha = 0.22f), shape)
            .clickable(onClick = onClick)
            .padding(horizontal = 18.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        AsyncImage(
            model = "$base/themes/forbion/images/mail/reply-icon-white.svg",
            contentDescription = null,
            modifier = Modifier.size(18.dp),
            contentScale = ContentScale.Fit,
        )
        Text(
            "Ответить",
            style = MaterialTheme.typography.bodyMedium,
            fontWeight = FontWeight.SemiBold,
            color = F7Colors.TextOnPrimary,
        )
    }
}

@Composable
private fun MailMessageIconButton(
    iconUrl: String?,
    contentDescription: String,
    onClick: () -> Unit,
    highlighted: Boolean = false,
    label: String? = null,
) {
    Box(
        modifier = Modifier
            .size(36.dp)
            .clip(CircleShape)
            .border(1.dp, F7Colors.Border, CircleShape)
            .background(if (highlighted) F7Colors.PrimaryLight else MailCardSurface)
            .clickable(onClick = onClick),
        contentAlignment = Alignment.Center,
    ) {
        when {
            !iconUrl.isNullOrBlank() -> {
                AsyncImage(
                    model = iconUrl,
                    contentDescription = contentDescription,
                    modifier = Modifier.size(16.dp),
                    contentScale = ContentScale.Fit,
                )
            }
            !label.isNullOrBlank() -> {
                Text(
                    label,
                    style = MaterialTheme.typography.titleLarge,
                    color = F7Colors.TextSecondary,
                )
            }
        }
    }
}

@Composable
fun MailAvatar(name: String, email: String, modifier: Modifier = Modifier) {
    val label = name.ifBlank { email }.trim()
    val letter = label.firstOrNull()?.uppercaseChar()?.toString() ?: "?"
    Box(
        modifier = modifier
            .clip(CircleShape)
            .background(MailAvatarBackground),
        contentAlignment = Alignment.Center,
    ) {
        Text(
            letter,
            style = MaterialTheme.typography.titleMedium,
            color = MailAvatarForeground,
            fontWeight = FontWeight.SemiBold,
        )
    }
}

fun formatEnvelopeDate(dateInt: Long): String {
    if (dateInt <= 0) return ""
    val date = Date(dateInt * 1000L)
    val now = Calendar.getInstance()
    val then = Calendar.getInstance().apply { time = date }
    val locale = Locale("ru")
    return when {
        now.get(Calendar.YEAR) == then.get(Calendar.YEAR) &&
            now.get(Calendar.DAY_OF_YEAR) == then.get(Calendar.DAY_OF_YEAR) -> {
            DateFormat.getTimeInstance(DateFormat.SHORT, locale).format(date)
        }
        now.get(Calendar.YEAR) == then.get(Calendar.YEAR) &&
            abs(now.get(Calendar.WEEK_OF_YEAR) - then.get(Calendar.WEEK_OF_YEAR)) <= 1 -> {
            then.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, locale)?.lowercase(locale).orEmpty()
        }
        now.get(Calendar.YEAR) == then.get(Calendar.YEAR) -> {
            val month = SimpleDateFormat("LLL", locale).format(date).trimEnd('.')
            val day = then.get(Calendar.DAY_OF_MONTH)
            "$month $day"
        }
        else -> {
            val month = SimpleDateFormat("LLL", locale).format(date).trimEnd('.')
            val day = then.get(Calendar.DAY_OF_MONTH)
            val year = then.get(Calendar.YEAR)
            "$day $month $year"
        }
    }
}

fun formatMessageDate(dateInt: Long): String {
    if (dateInt <= 0) return ""
    return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale("ru"))
        .format(Date(dateInt * 1000L))
}

fun formatAttachmentSize(size: Long): String {
    if (size <= 0) return ""
    return when {
        size >= 1_048_576 -> "%.1f МБ".format(size / 1_048_576.0)
        size >= 1024 -> "%.0f КБ".format(size / 1024.0)
        else -> "$size Б"
    }
}

@Composable
fun MailOutboxRow(
    message: MailOutboxMessage,
    onRetry: () -> Unit,
    onDelete: () -> Unit,
    modifier: Modifier = Modifier,
) {
    var menuOpen by remember { mutableStateOf(false) }
    val statusLabel = formatOutboxStatus(message)
    val statusColor = when {
        message.failed -> F7Colors.Error
        message.sendAt != null && message.sendAt * 1000L > System.currentTimeMillis() -> F7Colors.Primary
        else -> F7Colors.TextSecondary
    }
    Row(
        modifier = modifier
            .fillMaxWidth()
            .shadow(
                elevation = 2.dp,
                shape = RoundedCornerShape(12.dp),
                spotColor = Color(0x14000000),
            )
            .clip(RoundedCornerShape(12.dp))
            .background(MailCardSurface)
            .border(1.dp, F7Colors.Border.copy(alpha = 0.45f), RoundedCornerShape(12.dp))
            .padding(horizontal = 14.dp, vertical = 12.dp),
        verticalAlignment = Alignment.Top,
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text(
                    message.subject,
                    modifier = Modifier.weight(1f),
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.SemiBold,
                    color = F7Colors.TextPrimary,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis,
                )
                Text(
                    formatEnvelopeDate(message.updatedAt),
                    style = MaterialTheme.typography.labelSmall,
                    color = F7Colors.TextSecondary,
                )
            }
            if (message.toRecipients.isNotBlank()) {
                Spacer(Modifier.height(4.dp))
                Text(
                    "Кому: ${message.toRecipients}",
                    style = MaterialTheme.typography.bodySmall,
                    color = F7Colors.TextSecondary,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
            if (message.preview.isNotBlank()) {
                Spacer(Modifier.height(4.dp))
                Text(
                    message.preview,
                    style = MaterialTheme.typography.bodySmall,
                    color = F7Colors.TextSecondary,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis,
                )
            }
            Spacer(Modifier.height(6.dp))
            Text(
                statusLabel,
                style = MaterialTheme.typography.labelMedium,
                fontWeight = FontWeight.Medium,
                color = statusColor,
            )
        }
        Box {
            IconButton(onClick = { menuOpen = true }) {
                Text("⋯", color = F7Colors.TextSecondary)
            }
            DropdownMenu(expanded = menuOpen, onDismissRequest = { menuOpen = false }) {
                DropdownMenuItem(
                    text = { Text("Отправить") },
                    onClick = {
                        menuOpen = false
                        onRetry()
                    },
                )
                DropdownMenuItem(
                    text = { Text("Удалить") },
                    onClick = {
                        menuOpen = false
                        onDelete()
                    },
                )
            }
        }
    }
}

fun formatOutboxStatus(message: MailOutboxMessage): String {
    if (message.failed) return "Ошибка отправки"
    val sendAt = message.sendAt
    if (sendAt != null && sendAt * 1000L > System.currentTimeMillis()) {
        return "Отложено: ${formatMessageDate(sendAt)}"
    }
    return "В очереди"
}

@Composable
fun MailSearchParamsSheet(
    visible: Boolean,
    params: MailSearchParams,
    onDismiss: () -> Unit,
    onSearch: (MailSearchParams) -> Unit,
    onClear: () -> Unit,
) {
    if (!visible) return
    val context = LocalContext.current
    var draft by remember(params, visible) { mutableStateOf(params) }
    val dateFormat = remember { SimpleDateFormat("yyyy-MM-dd", Locale.US) }

    fun pickDate(current: String, onPicked: (String) -> Unit) {
        val calendar = Calendar.getInstance()
        if (current.isNotBlank()) {
            runCatching { dateFormat.parse(current) }.getOrNull()?.let { calendar.time = it }
        }
        DatePickerDialog(
            context,
            { _, year, month, day ->
                calendar.set(year, month, day)
                onPicked(dateFormat.format(calendar.time))
            },
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH),
        ).show()
    }

    androidx.compose.ui.window.Dialog(
        onDismissRequest = onDismiss,
        properties = DialogProperties(usePlatformDefaultWidth = false),
    ) {
        Surface(
            modifier = Modifier
                .fillMaxSize()
                .f7SwipeFromRightToDismiss(onDismiss = onDismiss),
            color = F7Colors.Surface,
        ) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(20.dp),
            ) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Text(
                        "Параметры поиска",
                        style = MaterialTheme.typography.titleLarge,
                        fontWeight = FontWeight.SemiBold,
                        color = F7Colors.TextPrimary,
                    )
                    IconButton(onClick = onDismiss) {
                        Text("✕", style = MaterialTheme.typography.titleMedium)
                    }
                }
                Spacer(Modifier.height(12.dp))
                Column(
                    modifier = Modifier
                        .weight(1f)
                        .verticalScroll(rememberScrollState()),
                    verticalArrangement = Arrangement.spacedBy(10.dp),
                ) {
                    MailSearchFieldRow("Тема", "Тема поиска", draft.subject) {
                        draft = draft.copy(subject = it)
                    }
                    MailSearchFieldRow("Тело", "Найти", draft.body) {
                        draft = draft.copy(body = it)
                    }
                    MailSearchDateRow(
                        label = "Дата",
                        startLabel = "Дата начала",
                        endLabel = "Дата окончания",
                        startValue = draft.dateStart,
                        endValue = draft.dateEnd,
                        onStartClick = { pickDate(draft.dateStart) { draft = draft.copy(dateStart = it) } },
                        onEndClick = { pickDate(draft.dateEnd) { draft = draft.copy(dateEnd = it) } },
                    )
                    MailSearchFieldRow("От", "Выберите отправителей", draft.from) {
                        draft = draft.copy(from = it)
                    }
                    MailSearchFieldRow("Кому", "Выберите получателей", draft.to) {
                        draft = draft.copy(to = it)
                    }
                    MailSearchFieldRow("Коп", "Выберите получателей CC", draft.cc) {
                        draft = draft.copy(cc = it)
                    }
                    MailSearchFieldRow("СкрКоп", "Выберите получателей BCC", draft.bcc) {
                        draft = draft.copy(bcc = it)
                    }
                    MailSearchFieldRow("Метки", "Выбор меток", draft.tags) {
                        draft = draft.copy(tags = it)
                    }
                    Spacer(Modifier.height(4.dp))
                    Text(
                        "Отмечено как",
                        style = MaterialTheme.typography.labelLarge,
                        fontWeight = FontWeight.SemiBold,
                    )
                    MailSearchCheckboxRow("Важное", draft.important) {
                        draft = draft.copy(important = it)
                    }
                    MailSearchCheckboxRow("В избранное", draft.starred) {
                        draft = draft.copy(starred = it)
                    }
                    MailSearchCheckboxRow("Непрочитанное", draft.unread) {
                        draft = draft.copy(unread = it)
                    }
                    MailSearchCheckboxRow("Имеет вложения", draft.hasAttachments) {
                        draft = draft.copy(hasAttachments = it)
                    }
                    MailSearchCheckboxRow("Упоминания меня", draft.mentionsMe) {
                        draft = draft.copy(mentionsMe = it)
                    }
                }
                Spacer(Modifier.height(12.dp))
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                ) {
                    F7SecondaryButton(
                        text = "Очистить",
                        onClick = {
                            draft = MailSearchParams()
                            onClear()
                        },
                        modifier = Modifier.weight(1f),
                    )
                    F7PrimaryButton(
                        text = "Поиск",
                        onClick = {
                            onSearch(draft)
                            onDismiss()
                        },
                        modifier = Modifier.weight(1f),
                    )
                }
            }
        }
    }
}

@Composable
private fun MailSearchFieldRow(
    label: String,
    placeholder: String,
    value: String,
    onValueChange: (String) -> Unit,
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(10.dp),
    ) {
        Text(
            label,
            modifier = Modifier.width(64.dp),
            style = MaterialTheme.typography.bodyMedium,
            fontWeight = FontWeight.Medium,
        )
        F7OutlinedField(
            value = value,
            onValueChange = onValueChange,
            label = placeholder,
            modifier = Modifier.weight(1f),
        )
    }
}

@Composable
private fun MailSearchDateRow(
    label: String,
    startLabel: String,
    endLabel: String,
    startValue: String,
    endValue: String,
    onStartClick: () -> Unit,
    onEndClick: () -> Unit,
) {
    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(10.dp),
        ) {
            Text(
                label,
                modifier = Modifier.width(64.dp),
                style = MaterialTheme.typography.bodyMedium,
                fontWeight = FontWeight.Medium,
            )
            MailSearchDateField(
                label = startLabel,
                value = startValue,
                onClick = onStartClick,
                modifier = Modifier.weight(1f),
            )
        }
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(10.dp),
        ) {
            Spacer(Modifier.width(64.dp))
            MailSearchDateField(
                label = endLabel,
                value = endValue,
                onClick = onEndClick,
                modifier = Modifier.weight(1f),
            )
        }
    }
}

@Composable
private fun MailSearchDateField(
    label: String,
    value: String,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    Box(
        modifier = modifier
            .clip(RoundedCornerShape(100.dp))
            .border(1.dp, F7Colors.Border, RoundedCornerShape(100.dp))
            .background(Color(0xFFFDFDFD))
            .clickable(onClick = onClick)
            .padding(horizontal = 16.dp, vertical = 14.dp),
    ) {
        Text(
            value.ifBlank { label },
            style = MaterialTheme.typography.bodyMedium,
            color = if (value.isBlank()) F7Colors.TextSecondary else F7Colors.TextPrimary,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
    }
}

@Composable
private fun MailSearchCheckboxRow(
    label: String,
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { onCheckedChange(!checked) }
            .padding(vertical = 2.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Checkbox(
            checked = checked,
            onCheckedChange = onCheckedChange,
            colors = CheckboxDefaults.colors(
                checkedColor = F7Colors.Primary,
                checkmarkColor = Color.White,
            ),
        )
        Text(label, style = MaterialTheme.typography.bodyMedium)
    }
}
