package com.example.m20_gamepad.ui.components

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.m20_gamepad.network.models.BatteryStatus
import com.example.m20_gamepad.network.models.DeviceTemperature
import com.example.m20_gamepad.network.models.ErrorCodes
import com.example.m20_gamepad.network.models.ErrorInfo
import com.example.m20_gamepad.network.models.MotionStatus

private val PanelBg = Color(0xF0111111)
private val PanelText = Color.White
private val LabelColor = Color(0xFFB0B0B0)
private val ErrorColor = Color(0xFFFF5252)
private val WarnColor = Color(0xFFFFC107)
private val OkColor = Color(0xFF4CAF50)

/**
 * 状态上报面板：异常列表 + 运控详情 + 设备温度 + 电池。
 * 覆盖在主界面之上，[visible] 控制显隐，点击背景或关闭按钮可 [onDismiss]。
 */
@Composable
fun StatusPanel(
    visible: Boolean,
    errorList: List<ErrorInfo>?,
    motionStatus: MotionStatus?,
    deviceTemperature: DeviceTemperature?,
    batteryStatus: BatteryStatus?,
    lastUpdate: String?,
    onDismiss: () -> Unit,
    modifier: Modifier = Modifier
) {
    AnimatedVisibility(
        visible = visible,
        enter = fadeIn() + slideInVertically(initialOffsetY = { it / 4 }),
        exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 4 }),
        modifier = modifier
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color(0x88000000))
        ) {
            Surface(
                color = PanelBg,
                shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .fillMaxWidth()
                    .fillMaxHeight(0.55f)
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(horizontal = 16.dp, vertical = 8.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    PanelHeader(lastUpdate, onDismiss)
                    Spacer(Modifier.height(8.dp))

                    ErrorListSection(errorList)
                    Spacer(Modifier.height(12.dp))

                    MotionStatusSection(motionStatus)
                    Spacer(Modifier.height(12.dp))

                    TemperatureSection(deviceTemperature)
                    Spacer(Modifier.height(12.dp))

                    BatterySection(batteryStatus)
                    Spacer(Modifier.height(16.dp))
                }
            }
        }
    }
}

@Composable
private fun PanelHeader(lastUpdate: String?, onDismiss: () -> Unit) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(
            "机器人状态",
            color = PanelText,
            fontSize = 18.sp,
            fontWeight = FontWeight.Bold
        )
        Row(verticalAlignment = Alignment.CenterVertically) {
            lastUpdate?.let {
                Text(
                    it,
                    color = LabelColor,
                    fontSize = 11.sp
                )
                Spacer(Modifier.width(8.dp))
            }
            IconButton(onClick = onDismiss) {
                Icon(Icons.Default.Close, contentDescription = "关闭", tint = PanelText)
            }
        }
    }
}

@Composable
private fun SectionTitle(title: String, accent: Color = LabelColor) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        Box(
            modifier = Modifier
                .width(3.dp)
                .height(14.dp)
                .background(accent)
        )
        Spacer(Modifier.width(8.dp))
        Text(
            title,
            color = PanelText,
            fontSize = 14.sp,
            fontWeight = FontWeight.SemiBold
        )
    }
}

// ==================== 异常状态 ====================

@Composable
private fun ErrorListSection(errorList: List<ErrorInfo>?) {
    SectionTitle("异常状态", if (errorList.isNullOrEmpty()) OkColor else ErrorColor)
    Spacer(Modifier.height(6.dp))
    when {
        errorList == null -> InfoRow("暂无上报")
        errorList.isEmpty() -> InfoRow("无异常", valueColor = OkColor)
        else -> errorList.forEach { err ->
            val components = ErrorCodes.componentNames(err.component)
            val compText = if (components.isEmpty()) "无" else components.joinToString("、")
            ErrorItem(
                code = err.errorCode,
                desc = ErrorCodes.describe(err.errorCode),
                component = compText
            )
        }
    }
}

@Composable
private fun ErrorItem(code: Int, desc: String, component: String) {
    Surface(
        color = Color(0x33FF5252),
        shape = RoundedCornerShape(8.dp),
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 3.dp)
    ) {
        Column(modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text(
                    "0x${code.toString(16).uppercase()}",
                    color = ErrorColor,
                    fontSize = 13.sp,
                    fontWeight = FontWeight.Bold
                )
                Spacer(Modifier.width(8.dp))
                Text(desc, color = PanelText, fontSize = 13.sp)
            }
            if (component.isNotEmpty()) {
                Text("部件: $component", color = LabelColor, fontSize = 11.sp)
            }
        }
    }
}

// ==================== 运控状态 ====================

@Composable
private fun MotionStatusSection(motionStatus: MotionStatus?) {
    SectionTitle("运控状态")
    Spacer(Modifier.height(6.dp))
    if (motionStatus == null) {
        InfoRow("暂无上报")
        return
    }
    // 姿态角
    MetricRow("Roll", "%.2f rad".format(motionStatus.roll))
    MetricRow("Pitch", "%.2f rad".format(motionStatus.pitch))
    MetricRow("Yaw", "%.2f rad".format(motionStatus.yaw))
    // 速度
    MetricRow("OmegaZ", "%.2f rad/s".format(motionStatus.omegaZ))
    MetricRow("LinearX", "%.2f m/s".format(motionStatus.linearX))
    MetricRow("LinearY", "%.2f m/s".format(motionStatus.linearY))
    // 其他
    MetricRow("机身高度", "%.2f m".format(motionStatus.height))
    MetricRow("剩余续航", "%.1f km".format(motionStatus.remainMile))
}

// ==================== 设备温度 ====================

@Composable
private fun TemperatureSection(deviceTemperature: DeviceTemperature?) {
    SectionTitle("设备温度")
    Spacer(Modifier.height(6.dp))
    if (deviceTemperature == null) {
        InfoRow("暂无上报")
        return
    }
    val motorMax = deviceTemperature.motor.maxOrNull() ?: 0.0
    val driverMax = deviceTemperature.driver.maxOrNull() ?: 0.0
    val motorColor = tempColor(motorMax)
    val driverColor = tempColor(driverMax)
    MetricRow("电机最高温", "%.1f ℃".format(motorMax), valueColor = motorColor)
    MetricRow("驱动器最高温", "%.1f ℃".format(driverMax), valueColor = driverColor)
    // 全部电机温度（紧凑）
    if (deviceTemperature.motor.isNotEmpty()) {
        Text(
            "电机: " + deviceTemperature.motor.joinToString(" ") { "%.0f".format(it) },
            color = LabelColor,
            fontSize = 11.sp,
            modifier = Modifier.padding(top = 4.dp)
        )
    }
    if (deviceTemperature.driver.isNotEmpty()) {
        Text(
            "驱动: " + deviceTemperature.driver.joinToString(" ") { "%.0f".format(it) },
            color = LabelColor,
            fontSize = 11.sp,
            modifier = Modifier.padding(top = 2.dp)
        )
    }
}

private fun tempColor(temp: Double): Color = when {
    temp >= 75.0 -> ErrorColor
    temp >= 60.0 -> WarnColor
    else -> PanelText
}

// ==================== 电池 ====================

@Composable
private fun BatterySection(batteryStatus: BatteryStatus?) {
    SectionTitle("电池")
    Spacer(Modifier.height(6.dp))
    if (batteryStatus == null) {
        InfoRow("暂无上报")
        return
    }
    MetricRow("左电池", "%.1f V / %.0f%%".format(
        batteryStatus.voltageLeft, batteryStatus.batteryLevelLeft))
    MetricRow("右电池", "%.1f V / %.0f%%".format(
        batteryStatus.voltageRight, batteryStatus.batteryLevelRight))
    MetricRow(
        "左电池温度", "%.1f ℃".format(batteryStatus.batteryTemperatureLeft),
        valueColor = tempColor(batteryStatus.batteryTemperatureLeft)
    )
    MetricRow(
        "右电池温度", "%.1f ℃".format(batteryStatus.batteryTemperatureRight),
        valueColor = tempColor(batteryStatus.batteryTemperatureRight)
    )
    MetricRow("左充电", if (batteryStatus.chargeLeft) "是" else "否")
    MetricRow("右充电", if (batteryStatus.chargeRight) "是" else "否")
}

// ==================== 通用行 ====================

@Composable
private fun MetricRow(label: String, value: String, valueColor: Color = PanelText) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 2.dp),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(label, color = LabelColor, fontSize = 13.sp)
        Text(value, color = valueColor, fontSize = 13.sp)
    }
}

@Composable
private fun InfoRow(text: String, valueColor: Color = LabelColor) {
    Text(text, color = valueColor, fontSize = 13.sp, modifier = Modifier.padding(vertical = 2.dp))
}
