package com.example.iot_controlhost.ui.compose

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.compose.animation.core.EaseInOutCubic
import androidx.compose.animation.core.tween
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.unit.dp
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.sp
import com.example.iot_controlhost.utils.MyUtil
import com.lt.compose_views.text_field.GoodTextField
import ir.ehsannarmani.compose_charts.LineChart
import ir.ehsannarmani.compose_charts.models.AnimationMode
import ir.ehsannarmani.compose_charts.models.DrawStyle
import ir.ehsannarmani.compose_charts.models.Line
import java.util.Date

@Preview(showBackground = true, widthDp = 1280, heightDp = 800)
@Composable
fun PIDScreenPV() {
    PIDScreen()
}

@Composable
fun PIDScreen(
    pidViewModel: PIDViewModel = viewModel()
) {
    // 获取状态
    var kp by remember { mutableStateOf(pidViewModel.Kp.toString()) }
    var ki by remember { mutableStateOf(pidViewModel.Ki.toString()) }
    var kd by remember { mutableStateOf(pidViewModel.Kd.toString()) }
    var dtInput by remember { mutableStateOf(pidViewModel.dt.toString()) }
    var tt by remember { mutableStateOf(pidViewModel.targetTemperature.toString()) }
    var tp by remember { mutableStateOf(pidViewModel.tp.toString()) }

    val currentTemp = pidViewModel.currentTemperature
    val output = pidViewModel.output
    val isTuning = pidViewModel.isTuning
    val isControl = pidViewModel.isControl

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "BBIT-PID控制测试系统",
            fontSize = 30.sp,
            modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
        )
        Spacer(modifier = Modifier.height(10.dp))
        Row(modifier = Modifier.fillMaxWidth()) {
            Column(
                modifier = Modifier.weight(1f),
                verticalArrangement = Arrangement.spacedBy(10.dp)
            ) {
                Title("状态图表")
                LineChart(
                    modifier = Modifier
                        .weight(5f)
                        .padding(horizontal = 22.dp),
                    data =
                        listOf(
                            Line(
                                label = "当前温度",
                                values = pidViewModel.tempList,
                                color = SolidColor(Color(0xFF23af92)),
                                firstGradientFillColor = Color(0xFF2BC0A1).copy(alpha = .5f),
                                secondGradientFillColor = Color.Transparent,
                                strokeAnimationSpec = tween(2000, easing = EaseInOutCubic),
                                gradientAnimationDelay = 1000,
                                drawStyle = DrawStyle.Stroke(width = 2.dp),
                            )
                        ),
                    animationMode = AnimationMode.Together(delayBuilder = {
                        it * 500L
                    }),
                )
                Row(
                    modifier = Modifier
                        .weight(2f)
                        .padding(horizontal = 22.dp)
                ) {
                    LineChart(
                        labelHelperPadding = 0.dp,
                        modifier = Modifier.weight(1f), data = listOf(
                            Line(
                                label = "比例增益 Kp",
                                values = pidViewModel.kpList,
                                color = SolidColor(Color(0xFF23af92)),
                            )
                        )
                    )
                    LineChart(
                        labelHelperPadding = 0.dp,
                        modifier = Modifier.weight(1f), data = listOf(
                            Line(
                                label = "积分增益 Ki",
                                values = pidViewModel.kiList,
                                color = SolidColor(Color(0xFF23af92)),
                            )
                        )
                    )
                    LineChart(
                        labelHelperPadding = 0.dp,
                        modifier = Modifier.weight(1f), data = listOf(
                            Line(
                                label = "微分增益 Kd",
                                values = pidViewModel.kdList,
                                color = SolidColor(Color(0xFF23af92)),
                            )
                        )
                    )
                }
                Title("实时参数")
                LazyVerticalGrid(modifier = Modifier, columns = GridCells.Fixed(3)) {
                    item {
                        InfoText("比例增益 Kp", pidViewModel.Kp)
                    }
                    item {
                        InfoText("积分增益 Ki", pidViewModel.Ki)
                    }
                    item {
                        InfoText("微分增益 Kd", pidViewModel.Kd)
                    }
                    item {
                        InfoText("目标温度", pidViewModel.targetTemperature)
                    }
                    item {
                        InfoText("当前温度", currentTemp)
                    }
                    item {
                        InfoText(
                            "温度类型",
                            if (pidViewModel.isVirtualTemp) "虚拟温度" else "真实温度"
                        )
                    }
                    item {
                        InfoText("PID输出", output)
                    }
                    item {
                        InfoText("采样时间间隔dt", pidViewModel.dt)
                    }
                    item {
                        InfoText("积分项累加值", pidViewModel.integral)
                    }
                    item {
                        InfoText("上个误差值", pidViewModel.prevError)
                    }
                    item {
                        InfoText("上次温度变化斜率", pidViewModel.prevSlope)
                    }
                    item {
                        InfoText("上次温度值", pidViewModel.lastTemp)
                    }
                    item {
                        InfoText("临界比例增益ku", pidViewModel.ku)
                    }
                    item {
                        InfoText("临界振荡周期tu", pidViewModel.tu)
                    }
                    item {
                        InfoText("自整定步骤计数", pidViewModel.stepCounter)
                    }
                    item {
                        InfoText("PID控制", if (isControl) "开启中" else "尚未控制")
                    }
                    item {
                        InfoText("自整定状态", if (isTuning) "正在自整定" else "尚未开始")
                    }
                    item {
                        InfoText("使用虚拟地暖", if (pidViewModel.isVirtualFloor) "是" else "否")
                    }
                    item {
                        InfoText("温度采集时间间隔(s)", pidViewModel.tp)
                    }
                }
                InfoText(
                    "最后峰值时间",
                    MyUtil.getFormatDateTime(Date(pidViewModel.lastPeakTime))
                )
            }
            VerticalDivider(modifier = Modifier.padding(horizontal = 10.dp))
            Column(
                modifier = Modifier.weight(1f),
                verticalArrangement = Arrangement.spacedBy(7.dp)
            ) {
                Row {
                    Column(modifier = Modifier.weight(1f)) {
                        val logs by pidViewModel.logs.collectAsState()
                        // 显示当前温度和PID输出
                        Title("系统日志")
                        Box(
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(150.dp)
                                .border(1.dp, Color.LightGray)
                                .verticalScroll(rememberScrollState())
                                .padding(8.dp)
                        ) {
                            Column {
                                logs.forEach { logLine ->
                                    Text(logLine, fontSize = 12.sp)
                                }
                            }
                        }
                    }
                    Column(modifier = Modifier.weight(1f)) {
                        Title("设备状态")
                        InfoText("空调1", pidViewModel.air1State)
                        InfoText("空调2", pidViewModel.air2State)
                        InfoText("地暖", pidViewModel.floorTState)
                        InfoText("虚拟地暖", pidViewModel.vFloorTState)
                    }
                }
                Title("参数设置")
                // 输入框：Kp, Ki, Kd, 目标温度
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(10.dp)
                ) {
                    ParamInputField(
                        isControl,
                        modifier = Modifier.weight(1f),
                        "比例增益 Kp",
                        kp
                    ) { value ->
                        kp = value
                        pidViewModel.Kp = value.toDoubleOrNull() ?: 0.0
                    }
                    ParamInputField(
                        isControl,
                        modifier = Modifier.weight(1f),
                        "积分增益 Ki",
                        ki
                    ) { value ->
                        ki = value
                        pidViewModel.Ki = value.toDoubleOrNull() ?: 0.0
                    }
                    ParamInputField(
                        isControl,
                        modifier = Modifier.weight(1f),
                        "微分增益 Kd",
                        kd
                    ) { value ->
                        kd = value
                        pidViewModel.Kd = value.toDoubleOrNull() ?: 0.0
                    }
                }
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(10.dp)
                ) {
                    ParamInputField(
                        isControl,
                        modifier = Modifier.weight(1f),
                        "采样时间间隔 dt 单位s",
                        dtInput
                    ) { value ->
                        dtInput = value
                        pidViewModel.dt = value.toDoubleOrNull() ?: 0.0
                    }
                    ParamInputField(
                        false,
                        modifier = Modifier.weight(1f),
                        "温度采集间隔 单位s",
                        tp
                    ) { value ->
                        tp = value
                        pidViewModel.tp = value.toLongOrNull() ?: 0
                    }
                    ParamInputField(
                        false,
                        modifier = Modifier.weight(1f),
                        "目标温度",
                        tt
                    ) { value ->
                        tt = value
                        pidViewModel.targetTemperature = value.toDoubleOrNull() ?: 0.0
                    }
                }
                Title("控制")
                LazyColumn {
                    item {

                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.switchVirtualFloor() }) {
                                Text("${if (pidViewModel.isVirtualFloor) "停用" else "启动"}虚拟地暖")
                            }
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.targetTemperature += 0.5 }) {
                                Text("增加目标温度0.5℃")
                            }
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.targetTemperature -= 0.5 }) {
                                Text("降低目标温度0.5℃")
                            }
                        }
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.switchVirtualTemp() }) {
                                Text("${if (pidViewModel.isVirtualTemp) "停用" else "启动"}虚拟温度数据")
                            }
                            Button(
                                enabled = pidViewModel.isVirtualTemp,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.addVirtualTemp() }) {
                                Text("增加虚拟当前温度0.5℃")
                            }
                            Button(
                                enabled = pidViewModel.isVirtualTemp,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.reduceVirtualTemp() }) {
                                Text("降低虚拟当前温度0.5℃")
                            }
                        }
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            // 按钮：启动自整定，停止自整定
                            Button(
                                enabled = !isControl,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.startControl() }) {
                                Text("开始控制")
                            }
                            Button(
                                enabled = isControl,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.stopControl() }) {
                                Text("停止控制")
                            }
                        }
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            // 按钮：启动自整定，停止自整定
                            Button(
                                enabled = !isTuning && isControl,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.startAutoTune() }) {
                                Text("启动自整定")
                            }
                            Button(
                                enabled = isTuning && isControl,
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.stopAutoTune() }) {
                                Text("停止自整定并重置参数")
                            }
                        }
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.saveParams() }) {
                                Text("保存当前PID参数")
                            }
                            Button(
                                modifier = Modifier.weight(1f),
                                onClick = { pidViewModel.loadParams() }) {
                                Text("读取PID参数")
                            }
                        }
                    }
                }
            }
        }
    }
}

@Composable
fun InfoText(title: String, content: Any) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        Text(
            text = title,
            modifier = Modifier
                .padding(8.dp)
                .weight(1f),
            fontSize = 16.sp
        )

        Text(
            text = if (content is Double) {
                String.format("%.2f", content)
            } else content.toString(),
            modifier = Modifier.padding(8.dp),
            fontSize = 16.sp,
            fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
        )
    }
}

@Composable
fun Title(text: String) {
    Text(
        text = text,
        fontSize = 20.sp,
        modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)
    )
}

@Composable
fun ParamInputField(
    isControl: Boolean = true,
    modifier: Modifier,
    label: String,
    value: String,
    onValueChange: (String) -> Unit
) {
    Column(modifier = modifier.fillMaxWidth()) {
        Text(
            text = label,
            color = if (isControl) Color.Red else Color.Black,
            modifier = Modifier.padding(start = 8.dp, top = 4.dp)
        )
        GoodTextField(
            enabled = !isControl,
            value = value,
            onValueChange = { newText -> onValueChange(newText) },
            keyboardOptions = KeyboardOptions.Default.copy(
                keyboardType = KeyboardType.Number
            ),
            modifier = Modifier
                .fillMaxWidth()
                .height(50.dp)
                .padding(8.dp)
        )
    }
}