package com.a2i.forwarder.ui.screens

import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.BorderStroke
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.RestartAlt
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.SystemUpdateAlt
import androidx.compose.material.icons.filled.Update
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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 androidx.documentfile.provider.DocumentFile
import com.a2i.forwarder.A2iApp
import com.a2i.forwarder.core.BarkClient
import com.a2i.forwarder.core.IconExporter
import com.a2i.forwarder.model.BarkMessage
import com.a2i.forwarder.model.BarkServer
import com.a2i.forwarder.model.OFFICIAL_BARK_SERVER
import com.a2i.forwarder.ui.ClickRow
import com.a2i.forwarder.ui.ScreenTitle
import com.a2i.forwarder.ui.appVersionName
import com.a2i.forwarder.ui.SectionCard
import com.a2i.forwarder.ui.StatusBadge
import kotlinx.coroutines.launch

@Composable
fun SettingsScreen(onOpenLog: () -> Unit) {
    val context = LocalContext.current
    val app = A2iApp.instance
    val servers by app.settings.servers.collectAsState()
    val current by app.settings.currentServer.collectAsState()
    val iconPrefix by app.settings.iconPrefix.collectAsState()
    val prefs = remember { context.getSharedPreferences("a2i_ui", Context.MODE_PRIVATE) }
    var treeUri by remember { mutableStateOf<Uri?>(prefs.getString("icon_tree", null)?.let { runCatching { Uri.parse(it) }.getOrNull() }) }
    var exporting by remember { mutableStateOf(false) }
    var exportResult by remember { mutableStateOf<String?>(null) }
    var testing by remember { mutableStateOf(false) }
    var testMsg by remember { mutableStateOf<String?>(null) }
    var showAdd by remember { mutableStateOf(false) }
    var editing by remember { mutableStateOf<BarkServer?>(null) }

    // 应用更新状态
    val updateAuto by app.settings.updateCheckEnabled.collectAsState()
    val updateInfo by app.updateChecker.updateInfo.collectAsState()
    var checking by remember { mutableStateOf(false) }
    var checkMsg by remember { mutableStateOf<String?>(null) }

    // 短信兜底状态
    val smsFallback by app.settings.smsFallbackEnabled.collectAsState()
    val smsTarget by app.settings.smsTargetNumber.collectAsState()
    val smsCarrier by app.settings.smsCarrier.collectAsState()
    val smsQuota by app.settings.smsManualQuota.collectAsState()
    val smsBalance by app.settings.smsBalance.collectAsState()
    val smsSuspended by app.settings.smsSuspended.collectAsState()
    var smsTargetInput by remember(smsTarget) { mutableStateOf(smsTarget) }
    var smsQuotaInput by remember(smsQuota) { mutableStateOf(if (smsQuota == 0) "" else smsQuota.toString()) }
    val detectedCarrier = remember { com.a2i.forwarder.core.CarrierDetector.detect(context) }

    val smsPermLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { }
    val hasSmsPerm = remember {
        androidx.core.content.ContextCompat.checkSelfPermission(context, android.Manifest.permission.SEND_SMS) ==
            android.content.pm.PackageManager.PERMISSION_GRANTED
    }

    val treeLauncher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
        if (uri != null) {
            runCatching {
                context.contentResolver.takePersistableUriPermission(
                    uri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
                )
            }
            prefs.edit().putString("icon_tree", uri.toString()).apply()
            treeUri = uri
        }
    }

    LazyColumn(
        modifier = Modifier.fillMaxSize().padding(horizontal = 16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        item { ScreenTitle("设置", "管理 Bark 服务、图标资源和维护操作") }

        item {
            SectionCard("Bark 服务器", subtitle = "官方服务和自建服务可以并存，当前服务器用于所有推送") {
                if (servers.isEmpty()) {
                    Text("暂无服务器，请先添加。", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
                } else {
                    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                        servers.forEach { s ->
                            ServerRow(
                                server = s,
                                selected = s.id == current?.id,
                                onSelect = { app.appScope.launch { app.settings.setCurrent(s.id) } },
                                onEdit = { editing = s },
                                onDelete = { app.appScope.launch { app.settings.deleteServer(s.id) } },
                            )
                        }
                    }
                }
                Button(
                    onClick = { showAdd = true },
                    modifier = Modifier.fillMaxWidth().padding(top = 12.dp),
                ) {
                    Icon(Icons.Filled.Add, null, modifier = Modifier.size(18.dp))
                    Spacer(Modifier.width(8.dp))
                    Text("添加服务器")
                }
                FilledTonalButton(
                    onClick = {
                        app.appScope.launch {
                            testing = true
                            testMsg = testPush(app)
                            testing = false
                        }
                    },
                    modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
                    enabled = !testing,
                ) {
                    if (testing) {
                        CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp)
                    } else {
                        Icon(Icons.AutoMirrored.Filled.Send, null, modifier = Modifier.size(18.dp))
                    }
                    Spacer(Modifier.width(8.dp))
                    Text("发送测试推送")
                }
                testMsg?.let {
                    Text(
                        it,
                        style = MaterialTheme.typography.bodySmall,
                        color = if (it.startsWith("已发送")) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.error,
                        modifier = Modifier.padding(top = 8.dp),
                    )
                }
            }
        }

        item {
            SectionCard("应用图标", subtitle = "导出 App 图标后，Bark 通知可按包名显示图标") {
                OutlinedTextField(
                    value = iconPrefix,
                    onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } },
                    label = { Text("图标 URL 前缀") },
                    supportingText = { Text("转发时 icon = 前缀 + 包名 + .png；留空则不显示图标") },
                    modifier = Modifier.fillMaxWidth(),
                    singleLine = true,
                )
                Text(
                    "导出目录：${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    modifier = Modifier.padding(top = 8.dp),
                )
                Row(
                    modifier = Modifier.fillMaxWidth().padding(top = 10.dp),
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") }
                    Button(
                        onClick = {
                            val u = treeUri ?: return@Button
                            app.appScope.launch {
                                exporting = true
                                val r = IconExporter(context).exportAll(u)
                                exporting = false
                                exportResult = "共 ${r.total} 个，成功 ${r.ok}，失败 ${r.fail}"
                            }
                        },
                        enabled = treeUri != null && !exporting,
                        modifier = Modifier.weight(1f),
                    ) {
                        if (exporting) CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp) else Text("导出图标")
                    }
                }
                exportResult?.let {
                    Text(it, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.padding(top = 8.dp))
                }
            }
        }

        item {
            SectionCard("断网短信兜底", subtitle = "无网络时把验证码、来电用短信发到 iPhone（每5分钟1条）") {
                com.a2i.forwarder.ui.SwitchRow(
                    title = "启用短信兜底",
                    subtitle = if (smsFallback) "断网时紧要通知走短信" else "当前关闭",
                    checked = smsFallback,
                ) { v -> app.appScope.launch { app.settings.setSmsFallback(v) } }

                Spacer(Modifier.size(8.dp))
                OutlinedTextField(
                    value = smsTargetInput,
                    onValueChange = { smsTargetInput = it },
                    label = { Text("iPhone 手机号") },
                    supportingText = { Text("短信转发的目标号码") },
                    modifier = Modifier.fillMaxWidth(),
                    singleLine = true,
                )
                Spacer(Modifier.size(4.dp))
                Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    OutlinedButton(onClick = {
                        app.appScope.launch { app.settings.setSmsTargetNumber(smsTargetInput.trim()) }
                    }, modifier = Modifier.weight(1f)) { Text("保存号码") }
                    if (!hasSmsPerm) {
                        OutlinedButton(onClick = {
                            smsPermLauncher.launch(android.Manifest.permission.SEND_SMS)
                        }, modifier = Modifier.weight(1f)) { Text("授予短信权限") }
                    }
                }

                Spacer(Modifier.size(8.dp))
                Text(
                    "检测到运营商：${detectedCarrier.displayName}" +
                        if (detectedCarrier.serviceNumber == null) "（无自动查询，将用手动额度）" else "（${detectedCarrier.serviceNumber}）",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                )
                Spacer(Modifier.size(8.dp))
                OutlinedTextField(
                    value = smsQuotaInput,
                    onValueChange = { smsQuotaInput = it.filter { c -> c.isDigit() } },
                    label = { Text("手动短信额度") },
                    supportingText = { Text("自动查询失败时按此递减；余额≤5自动停用") },
                    modifier = Modifier.fillMaxWidth(),
                    singleLine = true,
                )
                Spacer(Modifier.size(4.dp))
                OutlinedButton(onClick = {
                    val q = smsQuotaInput.trim().toIntOrNull() ?: 0
                    app.appScope.launch {
                        app.settings.setSmsManualQuota(q)
                        app.settings.setSmsBalance(q)
                        if (q > 5) app.settings.setSmsSuspended(false)
                    }
                }) { Text("保存额度并解除挂起") }

                Spacer(Modifier.size(8.dp))
                val balanceText = when {
                    smsSuspended -> "已挂起（余额不足）"
                    smsBalance < 0 -> "余额未知"
                    else -> "剩余约 ${smsBalance} 条"
                }
                Text(
                    "当前状态：$balanceText",
                    style = MaterialTheme.typography.bodySmall,
                    color = if (smsSuspended) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant,
                )
            }
        }

        item {
            SectionCard("关于与更新", subtitle = "版本检查（数据来自 GitHub Releases）") {
                com.a2i.forwarder.ui.SwitchRow(
                    title = "自动检查更新",
                    subtitle = "启动时检查，且距上次满 24 小时再次检查",
                    checked = updateAuto,
                    icon = Icons.Filled.Update,
                ) { v -> app.appScope.launch { app.settings.setUpdateCheckEnabled(v) } }

                ClickRow(
                    title = "检查更新",
                    subtitle = "当前 v${appVersionName(context)}" +
                        (updateInfo?.let { " · 已发现 v${it.latestVersion}" } ?: " · 点击立即检查"),
                    icon = Icons.Filled.SystemUpdateAlt,
                    onClick = {
                        app.appScope.launch {
                            checking = true
                            checkMsg = null
                            val r = app.updateChecker.check(force = true)
                            checking = false
                            checkMsg = when {
                                !r.isSuccess -> "检查失败：${r.exceptionOrNull()?.message}"
                                r.getOrNull() != null -> "发现新版本，请到首页更新"
                                else -> "已是最新版本"
                            }
                        }
                    },
                )

                if (checking) {
                    Row(
                        modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
                        verticalAlignment = Alignment.CenterVertically,
                    ) {
                        CircularProgressIndicator(Modifier.size(16.dp), strokeWidth = 2.dp)
                        Spacer(Modifier.width(8.dp))
                        Text("正在检查…", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
                    }
                }
                checkMsg?.let {
                    Text(
                        it,
                        style = MaterialTheme.typography.bodySmall,
                        color = if (it.startsWith("已是")) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.error,
                        modifier = Modifier.padding(start = 50.dp, top = 2.dp, bottom = 4.dp),
                    )
                }
            }
        }

        item {
            SectionCard("维护", subtitle = "日志查看和本地统计清理") {
                ClickRow("转发日志", "查看 / 清空最近记录", icon = Icons.Filled.History, onClick = onOpenLog)
                ClickRow("重置计数器", "清零转发 / 过滤 / 失败统计", icon = Icons.Filled.RestartAlt, tint = MaterialTheme.colorScheme.error) {
                    app.appScope.launch { app.logStore.resetCounters() }
                }
            }
        }

        item {
            Box(Modifier.fillMaxWidth().padding(top = 4.dp, bottom = 18.dp), contentAlignment = Alignment.Center) {
                Text(
                    "a2i · 安卓通知转发到 iOS Bark\n图标需 iOS 15+；点击通知会打开 iOS 对应 App",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                )
            }
        }
    }

    if (showAdd) {
        ServerDialog(
            onDismiss = { showAdd = false },
            onConfirm = { n, s, k ->
                app.appScope.launch {
                    val ns = app.settings.addServer(n, s, k)
                    app.settings.setCurrent(ns.id)
                }
                showAdd = false
            },
        )
    }
    editing?.let { srv ->
        ServerDialog(
            initial = srv,
            onDismiss = { editing = null },
            onConfirm = { n, s, k ->
                app.appScope.launch { app.settings.updateServer(srv.copy(name = n, server = s, deviceKey = k)) }
                editing = null
            },
        )
    }
}

@Composable
private fun ServerRow(
    server: BarkServer,
    selected: Boolean,
    onSelect: () -> Unit,
    onEdit: () -> Unit,
    onDelete: () -> Unit,
) {
    Surface(
        modifier = Modifier.fillMaxWidth(),
        shape = RoundedCornerShape(8.dp),
        color = if (selected) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.55f) else MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.36f),
        border = BorderStroke(1.dp, if (selected) MaterialTheme.colorScheme.primary.copy(alpha = 0.32f) else MaterialTheme.colorScheme.outlineVariant),
    ) {
        Row(Modifier.fillMaxWidth().padding(8.dp), verticalAlignment = Alignment.CenterVertically) {
            RadioButton(selected = selected, onClick = onSelect)
            Column(Modifier.weight(1f)) {
                Row(verticalAlignment = Alignment.CenterVertically) {
                    Text(
                        server.name.ifBlank { "未命名" },
                        style = MaterialTheme.typography.bodyLarge,
                        fontWeight = FontWeight.Medium,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier.weight(1f),
                    )
                    if (selected) StatusBadge("当前", MaterialTheme.colorScheme.primary)
                }
                Text(
                    "${server.server} · key: ${if (server.deviceKey.isBlank()) "未填" else "已填"}",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
            IconButton(onClick = onEdit) { Icon(Icons.Filled.Edit, "编辑") }
            IconButton(onClick = onDelete) { Icon(Icons.Filled.Delete, "删除") }
        }
    }
}

@Composable
private fun ServerDialog(
    initial: BarkServer? = null,
    onDismiss: () -> Unit,
    onConfirm: (name: String, server: String, key: String) -> Unit,
) {
    var name by remember { mutableStateOf(initial?.name ?: "") }
    var server by remember { mutableStateOf(initial?.server ?: OFFICIAL_BARK_SERVER) }
    var key by remember { mutableStateOf(initial?.deviceKey ?: "") }
    AlertDialog(
        onDismissRequest = onDismiss,
        icon = { Icon(Icons.Filled.Settings, null) },
        title = { Text(if (initial == null) "添加服务器" else "编辑服务器") },
        text = {
            Column {
                OutlinedTextField(name, { name = it }, label = { Text("名称") }, singleLine = true, modifier = Modifier.fillMaxWidth())
                Spacer(Modifier.size(8.dp))
                OutlinedTextField(server, { server = it }, label = { Text("服务器地址") }, singleLine = true, modifier = Modifier.fillMaxWidth(), supportingText = { Text("官方：$OFFICIAL_BARK_SERVER") })
                Spacer(Modifier.size(8.dp))
                OutlinedTextField(key, { key = it }, label = { Text("Device Key") }, singleLine = true, modifier = Modifier.fillMaxWidth())
            }
        },
        confirmButton = { TextButton(onClick = { onConfirm(name.trim(), server.trim(), key.trim()) }) { Text("保存") } },
        dismissButton = { TextButton(onClick = onDismiss) { Text("取消") } },
    )
}

private suspend fun testPush(app: A2iApp): String {
    val s = app.settings.currentServer.value ?: return "未选择服务器"
    if (s.deviceKey.isBlank()) return "未填写 device key"
    val msg = BarkMessage(
        deviceKey = s.deviceKey,
        title = "a2i 测试",
        body = "如果你在 iOS 看到这条推送，说明配置成功",
        level = "active",
    )
    val r = BarkClient(s).push(msg)
    return if (r.isSuccess) "已发送，请查看 iOS 端" else "发送失败：${r.exceptionOrNull()?.message}"
}