package com.example.m20_gamepad.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.example.m20_gamepad.data.AppSettings
import com.example.m20_gamepad.data.SettingsRepository
import com.example.m20_gamepad.data.VideoResizeMode
import com.example.m20_gamepad.video.VideoCodec
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

/**
 * 设置界面：配置机器人 IP/端口、RTSP 地址、视频编码器。
 *
 * 表单本地持有草稿值，点击保存时一次性写入仓库并回调 [onSaved]。
 * 返回按钮直接回调 [onBack]，未保存的改动丢弃。
 *
 * @param repository 应用级设置仓库（由 M20App 提供）
 * @param onBack 返回主界面
 * @param onSaved 保存成功后回调（主界面据此断开旧连接并使用新参数）
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
    repository: SettingsRepository,
    onBack: () -> Unit,
    onSaved: () -> Unit
) {
    val scope = rememberCoroutineScope()

    // 表单草稿：先用默认值占位，避免空值触发校验报错；DataStore 读取后覆盖为真实存储值
    var host by remember { mutableStateOf(AppSettings.DEFAULT_ROBOT_HOST) }
    var portText by remember { mutableStateOf(AppSettings.DEFAULT_ROBOT_PORT.toString()) }
    var rtspUrl by remember { mutableStateOf(AppSettings.DEFAULT_RTSP_URL) }
    var codec by remember { mutableStateOf(VideoCodec.AUTO) }
    var resizeMode by remember { mutableStateOf(VideoResizeMode.ZOOM) }
    var hostError by remember { mutableStateOf<String?>(null) }
    var portError by remember { mutableStateOf<String?>(null) }
    var initialized by remember { mutableStateOf(false) }

    LaunchedEffect(repository) {
        if (!initialized) {
            val s = repository.settings.first()
            host = s.robotHost
            portText = s.robotPort.toString()
            rtspUrl = s.rtspUrl
            codec = s.videoCodec
            resizeMode = s.videoResizeMode
            initialized = true
        }
    }

    val saveEnabled = initialized &&
        AppSettings.isValidHost(host) &&
        (portText.toIntOrNull()?.let { AppSettings.isValidPort(it) } == true)

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("设置") },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(
                            Icons.AutoMirrored.Filled.ArrowBack,
                            contentDescription = "返回"
                        )
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors()
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
                .verticalScroll(rememberScrollState())
                .padding(horizontal = 16.dp, vertical = 12.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            // ---- 连接配置 ----
            SectionLabel("机器人连接")

            OutlinedTextField(
                value = host,
                onValueChange = {
                    host = it
                    hostError = if (AppSettings.isValidHost(it)) null else "地址不能含空格"
                },
                label = { Text("机器人 IP 地址") },
                isError = hostError != null,
                supportingText = hostError?.let { { Text(it) } },
                singleLine = true,
                modifier = Modifier.fillMaxWidth()
            )

            OutlinedTextField(
                value = portText,
                onValueChange = {
                    // 仅允许数字
                    portText = it.filter { ch -> ch.isDigit() }.take(5)
                    val n = portText.toIntOrNull()
                    portError = when {
                        n == null -> "请输入数字"
                        !AppSettings.isValidPort(n) -> "端口范围 1-65535"
                        else -> null
                    }
                },
                label = { Text("UDP 端口") },
                isError = portError != null,
                supportingText = portError?.let { { Text(it) } },
                singleLine = true,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                modifier = Modifier.fillMaxWidth()
            )

            // ---- 视频流配置 ----
            SectionLabel("RTSP 视频流")

            OutlinedTextField(
                value = rtspUrl,
                onValueChange = { rtspUrl = it },
                label = { Text("RTSP 地址") },
                singleLine = true,
                modifier = Modifier.fillMaxWidth()
            )

            CodecDropdown(
                selected = codec,
                onSelect = { codec = it },
                modifier = Modifier.fillMaxWidth()
            )

            ResizeModeDropdown(
                selected = resizeMode,
                onSelect = { resizeMode = it },
                modifier = Modifier.fillMaxWidth()
            )

            Spacer(Modifier.padding(top = 8.dp))

            // ---- 操作按钮 ----
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(12.dp)
            ) {
                TextButton(
                    onClick = onBack,
                    modifier = Modifier.weight(1f)
                ) {
                    Text("取消")
                }
                Button(
                    onClick = {
                        val port = portText.toIntOrNull() ?: AppSettings.DEFAULT_ROBOT_PORT
                        scope.launch {
                            repository.setAll(
                                AppSettings(
                                    robotHost = host,
                                    robotPort = port,
                                    rtspUrl = rtspUrl,
                                    videoCodec = codec,
                                    videoResizeMode = resizeMode
                                )
                            )
                            onSaved()
                        }
                    },
                    enabled = saveEnabled,
                    modifier = Modifier.weight(1f)
                ) {
                    Text("保存")
                }
            }
        }
    }
}

@Composable
private fun SectionLabel(text: String) {
    Text(
        text = text,
        style = androidx.compose.material3.MaterialTheme.typography.titleSmall,
        color = androidx.compose.material3.MaterialTheme.colorScheme.primary
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun CodecDropdown(
    selected: VideoCodec,
    onSelect: (VideoCodec) -> Unit,
    modifier: Modifier = Modifier
) {
    var expanded by remember { mutableStateOf(false) }
    val options = VideoCodec.entries
    val labels = mapOf(
        VideoCodec.AUTO to "自动（优先硬件）",
        VideoCodec.FORCE_HW to "强制硬件解码（低延迟）",
        VideoCodec.FORCE_SW_H264 to "强制软解 H.264",
        VideoCodec.FORCE_SW_H265 to "强制软解 H.265"
    )

    Column(modifier = modifier) {
        Text(
            text = "视频解码器",
            style = androidx.compose.material3.MaterialTheme.typography.titleSmall,
            color = androidx.compose.material3.MaterialTheme.colorScheme.primary
        )
        Spacer(Modifier.padding(top = 4.dp))
        ExposedDropdownMenuBox(
            expanded = expanded,
            onExpandedChange = { expanded = it }
        ) {
            OutlinedTextField(
                value = labels[selected] ?: selected.name,
                onValueChange = {},
                readOnly = true,
                singleLine = true,
                trailingIcon = {
                    ExposedDropdownMenuDefaults.TrailingIcon(expanded)
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .menuAnchor()
            )
            ExposedDropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                options.forEach { c ->
                    DropdownMenuItem(
                        text = { Text(labels[c] ?: c.name) },
                        onClick = {
                            onSelect(c)
                            expanded = false
                        }
                    )
                }
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ResizeModeDropdown(
    selected: VideoResizeMode,
    onSelect: (VideoResizeMode) -> Unit,
    modifier: Modifier = Modifier
) {
    var expanded by remember { mutableStateOf(false) }
    val options = VideoResizeMode.entries
    val labels = mapOf(
        VideoResizeMode.FIT to "等比缩放（留黑边）",
        VideoResizeMode.ZOOM to "等比缩放（填充全屏）",
        VideoResizeMode.FILL to "拉伸填充"
    )

    Column(modifier = modifier) {
        Text(
            text = "视频缩放模式",
            style = androidx.compose.material3.MaterialTheme.typography.titleSmall,
            color = androidx.compose.material3.MaterialTheme.colorScheme.primary
        )
        Spacer(Modifier.padding(top = 4.dp))
        ExposedDropdownMenuBox(
            expanded = expanded,
            onExpandedChange = { expanded = it }
        ) {
            OutlinedTextField(
                value = labels[selected] ?: selected.name,
                onValueChange = {},
                readOnly = true,
                singleLine = true,
                trailingIcon = {
                    ExposedDropdownMenuDefaults.TrailingIcon(expanded)
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .menuAnchor()
            )
            ExposedDropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                options.forEach { m ->
                    DropdownMenuItem(
                        text = { Text(labels[m] ?: m.name) },
                        onClick = {
                            onSelect(m)
                            expanded = false
                        }
                    )
                }
            }
        }
    }
}
