package com.tsmobile.app.ui.components

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.tsmobile.app.ui.theme.UiTokens
import com.tsmobile.app.ui.theme.semanticColors
import com.tsmobile.app.viewmodel.ChannelViewModel
import com.tsmobile.app.viewmodel.VoiceViewModel

/**
 * 语音卡：在频道成员列表中直接展示发言状态和成员操作。
 *
 * 对应 docs/UI架构设计.md 3.3 语音卡
 *
 * 注意：PTT / 静音控制由底部 VoiceControlBar 全局常驻，语音卡内不重复。
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun VoiceCard(
    voiceViewModel: VoiceViewModel,
    channelViewModel: ChannelViewModel,
    onDismiss: () -> Unit,
    onPokeClient: (clientId: Int, message: String) -> Unit = { _, _ -> },
) {
    val speakingClients by voiceViewModel.speakingClients.collectAsState()
    val isTransmitting by voiceViewModel.isTransmitting.collectAsState()
    val currentChannelId by channelViewModel.currentChannelId.collectAsState()
    val channelClients by channelViewModel.channelClients.collectAsState()
    val remoteAudioSettings by voiceViewModel.remoteAudioSettings.collectAsState()
    val outputVolume by voiceViewModel.outputVolume.collectAsState()
    val members = channelClients[currentChannelId] ?: emptyList()

    var menuTarget by remember { mutableStateOf<com.tsmobile.app.data.ClientInfo?>(null) }
    var pokeTarget by remember { mutableStateOf<Pair<Int, String>?>(null) }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(UiTokens.Spacing.Large),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(
                text = "频道成员",
                style = MaterialTheme.typography.titleMedium,
                fontWeight = FontWeight.Bold,
            )
            IconButton(onClick = onDismiss) {
                Icon(Icons.Default.Close, contentDescription = "关闭")
            }
        }

        Spacer(Modifier.height(UiTokens.Spacing.Small))
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = UiTokens.Spacing.ExtraSmall),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(
                text = "频道内人员 (${members.size})",
                style = MaterialTheme.typography.labelLarge,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
            )
            val speakingCount = members.count { member ->
                if (member.isSelf) isTransmitting else speakingClients.containsKey(member.id)
            }
            if (speakingCount > 0) {
                Text(
                    text = "$speakingCount 人正在发言",
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.semanticColors.success,
                )
            }
        }

        Spacer(Modifier.height(UiTokens.Spacing.Small))
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text("接收音量", style = MaterialTheme.typography.labelLarge)
            Text("${(outputVolume * 100).toInt()}%", style = MaterialTheme.typography.labelMedium)
        }
        Slider(
            value = outputVolume,
            onValueChange = voiceViewModel::setOutputVolume,
            valueRange = 0f..1f,
            modifier = Modifier
                .fillMaxWidth()
                .semantics {
                    contentDescription = "接收音量 ${(outputVolume * 100).toInt()}%"
                },
        )
        LazyColumn(
            modifier = Modifier
                .fillMaxWidth()
                .heightIn(min = 280.dp, max = 560.dp),
            verticalArrangement = Arrangement.spacedBy(UiTokens.Spacing.ExtraSmall),
        ) {
            items(members.distinctBy { it.id }, key = { it.id }) { member ->
                MemberRow(
                    name = member.nickname,
                    isSelf = member.isSelf,
                    isSpeaking = if (member.isSelf) {
                        isTransmitting
                    } else {
                        speakingClients.containsKey(member.id)
                    },
                    isMuted = remoteAudioSettings[member.id]?.muted == true,
                    onLongClick = { menuTarget = member },
                )
            }
        }
    }

    menuTarget?.let { member ->
        val settings = remoteAudioSettings[member.id] ?: VoiceViewModel.RemoteAudioSettings()
        MemberActionDialog(
            nickname = member.nickname,
            audioSettings = if (member.isSelf) null else settings,
            onToggleMuted = { voiceViewModel.toggleRemoteClientMuted(member.id) },
            onPoke = {
                pokeTarget = member.id to member.nickname
                menuTarget = null
            },
            onDismiss = { menuTarget = null },
        )
    }

    pokeTarget?.let { (clientId, nickname) ->
        PokeDialog(
            targetName = nickname,
            onConfirm = { message ->
                onPokeClient(clientId, message)
                pokeTarget = null
            },
            onDismiss = { pokeTarget = null },
        )
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun MemberRow(
    name: String,
    isSelf: Boolean,
    isSpeaking: Boolean,
    isMuted: Boolean,
    onLongClick: () -> Unit,
) {
    val colors = MaterialTheme.colorScheme
    val semanticColors = MaterialTheme.semanticColors
    val containerColor = if (isSpeaking) semanticColors.successContainer else colors.surfaceContainerLow
    val contentColor = if (isSpeaking) semanticColors.onSuccessContainer else colors.onSurface

    Row(
        modifier = Modifier
            .fillMaxWidth()
            .heightIn(min = 64.dp)
            .background(containerColor, RoundedCornerShape(UiTokens.Spacing.Medium))
            .combinedClickable(onClick = {}, onLongClick = onLongClick)
            .padding(horizontal = 14.dp, vertical = UiTokens.Spacing.Medium),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Icon(
            imageVector = if (isSpeaking) Icons.Default.RecordVoiceOver else Icons.Default.Person,
            contentDescription = if (isSpeaking) "正在发言" else null,
            tint = if (isSpeaking) semanticColors.success else contentColor,
            modifier = Modifier.size(UiTokens.Size.IconLarge),
        )
        Spacer(Modifier.width(UiTokens.Spacing.Medium))
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = name,
                style = MaterialTheme.typography.bodyLarge,
                fontWeight = if (isSpeaking) FontWeight.SemiBold else FontWeight.Normal,
                color = contentColor,
            )
            Text(
                text = when {
                    isSpeaking -> "正在发言"
                    isSelf -> "我"
                    else -> "在线"
                },
                style = MaterialTheme.typography.labelMedium,
                color = if (isSpeaking) semanticColors.success else colors.onSurfaceVariant,
            )
        }
        if (!isSelf && isMuted) {
            Icon(
                imageVector = Icons.Default.VolumeOff,
                contentDescription = "已静音",
                tint = colors.error,
                modifier = Modifier.size(UiTokens.Size.IconMedium),
            )
        }
    }
}

/**
 * 长按成员弹出的操作菜单。
 * 文档 4.3：Poke + 复制昵称
 */
@Composable
private fun MemberActionDialog(
    nickname: String,
    audioSettings: VoiceViewModel.RemoteAudioSettings?,
    onToggleMuted: () -> Unit,
    onPoke: () -> Unit,
    onDismiss: () -> Unit,
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        title = {
            Column {
                Text(text = "👤 $nickname", style = MaterialTheme.typography.titleMedium)
            }
        },
        text = {
            Column {
                audioSettings?.let { settings ->
                    TextButton(onClick = onToggleMuted, modifier = Modifier.fillMaxWidth()) {
                        Icon(if (settings.muted) Icons.Default.VolumeUp else Icons.Default.VolumeOff, null)
                        Spacer(Modifier.width(UiTokens.Spacing.Small))
                        Text(if (settings.muted) "取消静音" else "静音")
                    }
                    HorizontalDivider()
                    Spacer(Modifier.height(UiTokens.Spacing.Small))
                }
                TextButton(onClick = onPoke, modifier = Modifier.fillMaxWidth()) {
                    Icon(Icons.Default.TouchApp, contentDescription = null)
                    Spacer(Modifier.width(UiTokens.Spacing.Small))
                    Text("Poke")
                }
                TextButton(
                    onClick = { onDismiss() },
                    modifier = Modifier.fillMaxWidth(),
                ) {
                    Icon(Icons.Default.ContentCopy, contentDescription = null)
                    Spacer(Modifier.width(UiTokens.Spacing.Small))
                    Text("复制昵称")
                }
            }
        },
        confirmButton = {},
    )
}
