package com.seven.ikar.kotlin.feature.chatinfo

import android.content.ClipData
import android.widget.Toast
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ClipEntry
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.seven.ikar.kotlin.core.model.ChatInfoDto
import com.seven.ikar.kotlin.core.model.ChatInviteLinkDto
import com.seven.ikar.kotlin.core.model.ChatSummaryDto
import com.seven.ikar.kotlin.core.model.ChatTopicDto
import com.seven.ikar.kotlin.core.model.ChatType
import com.seven.ikar.kotlin.ui.IkarRowDivider
import com.seven.ikar.kotlin.ui.IkarScreenSurface
import com.seven.ikar.kotlin.ui.IkarSearchCard
import com.seven.ikar.kotlin.ui.IkarSectionCard
import com.seven.ikar.kotlin.ui.IkarSectionTitle
import com.seven.ikar.kotlin.ui.IkarSimpleHeader
import com.seven.ikar.kotlin.ui.theme.TelegramBlue
import com.seven.ikar.kotlin.ui.theme.TelegramDanger
import com.seven.ikar.kotlin.ui.theme.TelegramInkMuted
import java.time.OffsetDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import kotlinx.coroutines.launch

@Composable
fun ChatInfoScreen(
    state: ChatInfoUiState,
    onBackClick: () -> Unit,
    onRefreshClick: () -> Unit,
    onMembersClick: () -> Unit,
    onSearchClick: () -> Unit,
    onProfileTitleChanged: (String) -> Unit,
    onProfileDescriptionChanged: (String) -> Unit,
    onProfilePublicUsernameChanged: (String) -> Unit,
    onMaterialsClick: (ChatMaterialFilter) -> Unit,
    onInviteTitleChanged: (String) -> Unit,
    onInviteJoinRequestChanged: (Boolean) -> Unit,
    onInviteExpiresInHoursChanged: (String) -> Unit,
    onInviteMaxUsesChanged: (String) -> Unit,
    onInviteMemberLimitChanged: (String) -> Unit,
    onCreateInviteClick: () -> Unit,
    onRevokeInviteClick: (ChatInviteLinkDto) -> Unit,
    onTopicTitleChanged: (String) -> Unit,
    onCreateTopicClick: () -> Unit,
    onLinkDiscussionClick: (ChatSummaryDto) -> Unit,
    onClearDiscussionClick: () -> Unit
) {
    val info = state.info
    val clipboard = LocalClipboard.current
    val clipboardScope = rememberCoroutineScope()
    val context = LocalContext.current
    IkarScreenSurface(modifier = Modifier.fillMaxSize()) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Vertical))
                .verticalScroll(rememberScrollState())
                .padding(horizontal = 18.dp, vertical = 16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            IkarSimpleHeader(
                title = info?.chat?.title?.ifBlank { "Информация о чате" } ?: "Информация о чате",
                onBackClick = onBackClick
            )

            state.errorMessage?.let {
                Text(it, color = TelegramDanger, style = MaterialTheme.typography.bodySmall)
            }
            if (state.isLoading && info == null) {
                CircularProgressIndicator(color = TelegramBlue)
            }

            if (info != null) {
                IkarSectionCard {
                    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                        IkarSectionTitle("Обзор")
                        Text(info.chat.type.label(), style = MaterialTheme.typography.bodyMedium, color = TelegramInkMuted)
                        Text(info.channelAudienceText(), style = MaterialTheme.typography.titleMedium)
                        if (info.chat.type == ChatType.Channel && info.adminCount > 0) {
                            Text("${info.adminCount} ${russianPlural(info.adminCount, "администратор", "администратора", "администраторов")}", style = MaterialTheme.typography.bodySmall, color = TelegramInkMuted)
                        }
                        val description = info.description ?: info.chat.description
                        if (!description.isNullOrBlank()) {
                            Text(description, style = MaterialTheme.typography.bodyMedium)
                        }
                        if (!info.publicUsername.isNullOrBlank()) {
                            Text("@${info.publicUsername}", color = TelegramBlue)
                        }
                        if (info.chat.type == ChatType.Channel) {
                            ChannelIdRow(
                                chatId = info.chat.id,
                                onCopyClick = {
                                    clipboardScope.launch {
                                        clipboard.setClipEntry(
                                            ClipEntry(ClipData.newPlainText("Ikar channel id", info.chat.id))
                                        )
                                    }
                                    Toast.makeText(context, "UUID канала скопирован", Toast.LENGTH_SHORT).show()
                                }
                            )
                        }
                        OverviewActions(
                            onMembersClick = onMembersClick,
                            onSearchClick = onSearchClick,
                            onRefreshClick = onRefreshClick
                        )
                    }
                }

                if (info.canEditProfile()) {
                    IkarSectionCard {
                        IkarSectionTitle("Профиль", modifier = Modifier.padding(bottom = 8.dp))
                        IkarSearchCard(
                            value = state.profileTitle,
                            onValueChange = onProfileTitleChanged,
                            placeholder = "Название"
                        )
                        IkarSearchCard(
                            value = state.profileDescription,
                            onValueChange = onProfileDescriptionChanged,
                            placeholder = "Описание"
                        )
                        if (info.chat.type == ChatType.Channel) {
                            IkarSearchCard(
                                value = state.profilePublicUsername,
                                onValueChange = onProfilePublicUsernameChanged,
                                placeholder = "Публичное имя канала"
                            )
                        }
                        if (state.isSaving) {
                            Text("Обновление...", style = MaterialTheme.typography.bodySmall, color = TelegramInkMuted)
                        }
                    }
                }

                IkarSectionCard {
                    IkarSectionTitle("Общие материалы", modifier = Modifier.padding(bottom = 8.dp))
                    InfoStatRow("Медиа", info.mediaCount, onClick = { onMaterialsClick(ChatMaterialFilter.Media) })
                    InfoStatRow("Файлы", info.fileCount, onClick = { onMaterialsClick(ChatMaterialFilter.Files) })
                    InfoStatRow("Ссылки", info.linkCount, onClick = { onMaterialsClick(ChatMaterialFilter.Links) })
                    InfoStatRow("Голосовые", info.voiceCount, onClick = { onMaterialsClick(ChatMaterialFilter.Voice) })
                    InfoStatRow("Закреплённые", info.pinnedCount, onClick = { onMaterialsClick(ChatMaterialFilter.Pinned) })
                }

                if (info.chat.type == ChatType.Channel && info.canManageChannel) {
                    IkarSectionCard {
                        IkarSectionTitle("Обсуждение канала", modifier = Modifier.padding(bottom = 8.dp))
                        val linkedDiscussionId = info.linkedDiscussionChatId ?: info.chat.linkedDiscussionChatId
                        val linkedGroup = state.discussionGroups.firstOrNull { it.id == linkedDiscussionId }
                        Text(
                            text = linkedGroup?.let { "Привязана группа: ${it.title}" }
                                ?: linkedDiscussionId?.let { "Привязана группа: $it" }
                                ?: "Группа обсуждения не привязана.",
                            style = MaterialTheme.typography.bodyMedium,
                            color = if (linkedDiscussionId == null) TelegramInkMuted else MaterialTheme.colorScheme.onSurface
                        )
                        if (linkedDiscussionId != null) {
                            TextButton(enabled = !state.isSaving, onClick = onClearDiscussionClick) {
                                Text(if (state.isSaving) "Обновление..." else "Отвязать обсуждение", color = TelegramDanger)
                            }
                        }
                        if (state.discussionGroups.isEmpty()) {
                            Text(
                                "Доступных групп пока нет. Создайте группу и добавьте туда администраторов канала.",
                                style = MaterialTheme.typography.bodySmall,
                                color = TelegramInkMuted
                            )
                        } else {
                            state.discussionGroups.forEachIndexed { index, group ->
                                DiscussionGroupRow(
                                    group = group,
                                    isLinked = group.id == linkedDiscussionId,
                                    isSaving = state.isSaving,
                                    onLinkClick = { onLinkDiscussionClick(group) }
                                )
                                if (index != state.discussionGroups.lastIndex) {
                                    IkarRowDivider()
                                }
                            }
                        }
                    }
                }

                if (info.canInviteUsers) {
                    IkarSectionCard {
                        IkarSectionTitle("Пригласительные ссылки", modifier = Modifier.padding(bottom = 8.dp))
                    IkarSearchCard(
                        value = state.inviteTitle,
                        onValueChange = onInviteTitleChanged,
                        placeholder = "Название ссылки"
                    )
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        IkarSearchCard(
                            value = state.inviteExpiresInHours,
                            onValueChange = onInviteExpiresInHoursChanged,
                            placeholder = "Срок, часов",
                            modifier = Modifier.weight(1f)
                        )
                        IkarSearchCard(
                            value = state.inviteMaxUses,
                            onValueChange = onInviteMaxUsesChanged,
                            placeholder = "Входов",
                            modifier = Modifier.weight(1f)
                        )
                    }
                    IkarSearchCard(
                        value = state.inviteMemberLimit,
                        onValueChange = onInviteMemberLimitChanged,
                        placeholder = "Лимит участников"
                    )
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.spacedBy(8.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Checkbox(
                            checked = state.inviteCreatesJoinRequest,
                            onCheckedChange = onInviteJoinRequestChanged,
                            enabled = !state.isSaving
                        )
                        Column(modifier = Modifier.weight(1f)) {
                            Text("Требовать одобрение администратора", style = MaterialTheme.typography.bodyMedium)
                            Text(
                                "Новые пользователи попадут в заявки на вступление, а не войдут сразу.",
                                style = MaterialTheme.typography.bodySmall,
                                color = TelegramInkMuted
                            )
                        }
                    }
                    TextButton(enabled = !state.isSaving, onClick = onCreateInviteClick) {
                        Text(if (state.isSaving) "Сохранение..." else "Создать ссылку")
                    }
                    if (info.inviteLinks.isEmpty()) {
                        Text("Пригласительных ссылок пока нет.", style = MaterialTheme.typography.bodySmall, color = TelegramInkMuted)
                    }
                    info.inviteLinks.forEachIndexed { index, link ->
                        InviteLinkRow(link = link, onRevokeClick = { onRevokeInviteClick(link) })
                        if (index != info.inviteLinks.lastIndex) {
                            IkarRowDivider()
                        }
                    }
                    }
                }

                IkarSectionCard {
                    IkarSectionTitle("Темы", modifier = Modifier.padding(bottom = 8.dp))
                    IkarSearchCard(
                        value = state.topicTitle,
                        onValueChange = onTopicTitleChanged,
                        placeholder = "Новая тема"
                    )
                    TextButton(enabled = !state.isSaving, onClick = onCreateTopicClick) {
                        Text(if (state.isSaving) "Сохранение..." else "Создать тему")
                    }
                    info.topics.forEachIndexed { index, topic ->
                        TopicRow(topic)
                        if (index != info.topics.lastIndex) {
                            IkarRowDivider()
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun DiscussionGroupRow(
    group: ChatSummaryDto,
    isLinked: Boolean,
    isSaving: Boolean,
    onLinkClick: () -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 10.dp),
        horizontalArrangement = Arrangement.spacedBy(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column(modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp)) {
            Text(group.title, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
            Text(
                group.secondaryText ?: "${group.participants.size} участников",
                style = MaterialTheme.typography.bodySmall,
                color = TelegramInkMuted,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
        TextButton(enabled = !isSaving && !isLinked, onClick = onLinkClick) {
            Text(if (isLinked) "Привязана" else "Привязать", color = if (isLinked) TelegramInkMuted else TelegramBlue)
        }
    }
}

@Composable
private fun ChannelIdRow(
    chatId: String,
    onCopyClick: () -> Unit
) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(14.dp),
        color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f)
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(start = 12.dp, top = 10.dp, end = 8.dp, bottom = 10.dp),
            horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Column(
                modifier = Modifier.weight(1f),
                verticalArrangement = Arrangement.spacedBy(2.dp)
            ) {
                Text("UUID канала", style = MaterialTheme.typography.labelMedium, color = TelegramInkMuted)
                SelectionContainer {
                    Text(
                        text = chatId,
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurface,
                        overflow = TextOverflow.Visible
                    )
                }
            }
            IconButton(onClick = onCopyClick, modifier = Modifier.size(40.dp)) {
                Icon(
                    imageVector = Icons.Outlined.ContentCopy,
                    contentDescription = "Скопировать UUID канала",
                    tint = TelegramBlue,
                    modifier = Modifier.size(20.dp)
                )
            }
        }
    }
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun OverviewActions(
    onMembersClick: () -> Unit,
    onSearchClick: () -> Unit,
    onRefreshClick: () -> Unit
) {
    FlowRow(
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        TextButton(onClick = onMembersClick) { Text("Участники") }
        TextButton(onClick = onSearchClick) { Text("Поиск") }
        TextButton(onClick = onRefreshClick) { Text("Обновить") }
    }
}

@Composable
private fun InfoStatRow(label: String, value: Int, onClick: (() -> Unit)? = null) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .then(if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(label, style = MaterialTheme.typography.bodyMedium)
        Text(value.toString(), style = MaterialTheme.typography.titleMedium, color = TelegramBlue)
    }
}

@Composable
private fun InviteLinkRow(
    link: ChatInviteLinkDto,
    onRevokeClick: () -> Unit
) {
    Column(
        modifier = Modifier.padding(vertical = 10.dp),
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Text(link.title ?: "Пригласительная ссылка", style = MaterialTheme.typography.titleMedium)
        Text(
            text = link.link,
            style = MaterialTheme.typography.bodySmall,
            color = if (link.isRevoked) TelegramInkMuted else TelegramBlue,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
        Text(
            text = when {
                link.isRevoked -> "Отозвана"
                link.createsJoinRequest -> "Требует одобрения"
                else -> "Мгновенный вход"
            },
            style = MaterialTheme.typography.bodySmall,
            color = if (link.isRevoked) TelegramDanger else TelegramInkMuted
        )
        inviteLinkLimitsText(link)?.let { limits ->
            Text(
                text = limits,
                style = MaterialTheme.typography.bodySmall,
                color = TelegramInkMuted
            )
        }
        if (!link.isRevoked) {
            TextButton(onClick = onRevokeClick) { Text("Отозвать") }
        }
    }
}

@Composable
private fun TopicRow(topic: ChatTopicDto) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 10.dp),
        horizontalArrangement = Arrangement.spacedBy(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Text(topic.icon, style = MaterialTheme.typography.titleLarge)
        Column(modifier = Modifier.weight(1f)) {
            Text(topic.title, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
            Text("${topic.messageCount} сообщений", style = MaterialTheme.typography.bodySmall, color = TelegramInkMuted)
        }
    }
}

private fun ChatType.label(): String = when (this) {
    ChatType.Direct -> "Личный чат"
    ChatType.Group -> "Группа"
    ChatType.Channel -> "Канал"
}

private fun inviteLinkLimitsText(link: ChatInviteLinkDto): String? {
    val parts = buildList {
        link.maxUses?.let { maxUses ->
            add("${link.usesCount}/$maxUses использований")
        }
        link.memberLimit?.let { memberLimit ->
            add("до $memberLimit участников")
        }
        link.expiresAt?.let { expiresAt ->
            add("до ${formatInviteDate(expiresAt)}")
        }
    }
    return parts.takeIf { it.isNotEmpty() }?.joinToString(" · ")
}

private fun formatInviteDate(value: String): String =
    runCatching {
        OffsetDateTime.parse(value)
            .atZoneSameInstant(ZoneId.systemDefault())
            .format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))
    }.getOrElse { value }

private fun ChatInfoDto.canEditProfile(): Boolean =
    chat.type != ChatType.Direct && (canManageChannel || chat.currentUserPermissions?.canManageMembers == true)

private fun ChatInfoDto.channelAudienceText(): String {
    if (chat.type != ChatType.Channel) {
        return "${chat.participants.size} участников"
    }

    val count = when {
        subscriberCount > 0 -> subscriberCount
        chat.subscriberCount > 0 -> chat.subscriberCount
        else -> chat.participants.size
    }
    return "$count ${russianPlural(count, "подписчик", "подписчика", "подписчиков")}"
}

private fun russianPlural(count: Int, one: String, few: String, many: String): String {
    val value = kotlin.math.abs(count) % 100
    val lastDigit = value % 10
    if (value in 11..14) {
        return many
    }

    return when (lastDigit) {
        1 -> one
        in 2..4 -> few
        else -> many
    }
}
