package com.jishisongfu.duobibi.ui.mine

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
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.WindowInsets
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.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.jishisongfu.duobibi.auth.BindPhoneState
import com.jishisongfu.duobibi.auth.PhoneBindViewModel
import com.jishisongfu.duobibi.ui.HeroBanner
import com.jishisongfu.duobibi.ui.fmtYuan
import com.jishisongfu.duobibi.ui.theme.DbbColors
import com.jishisongfu.duobibi.ui.theme.DbbGradients
import com.jishisongfu.duobibi.util.AuthPrefs
import com.jishisongfu.duobibi.util.FloatingServiceLauncher
import com.jishisongfu.duobibi.util.PermissionUtil
import com.jishisongfu.duobibi.util.SettingsPrefs
import com.jishisongfu.duobibi.util.VendorAutoStart

private tailrec fun Context.findActivity(): Activity? = when (this) {
    is Activity -> this
    is ContextWrapper -> baseContext.findActivity()
    else -> null
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MineScreen(
    onOpenUnitPrice: () -> Unit,
    onOpenBundle: () -> Unit,
    onOpenInstallment: () -> Unit,
    onOpenDiagnostics: () -> Unit,
    onOpenAbout: () -> Unit,
    onOpenPrivacy: () -> Unit,
    onOpenRecords: () -> Unit,
    bindVm: PhoneBindViewModel = hiltViewModel(),
    mineVm: MineViewModel = hiltViewModel(),
) {
    val ctx = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current
    val bindState by bindVm.state.collectAsStateWithLifecycle()
    val mineStats by mineVm.stats.collectAsStateWithLifecycle()

    // 权限/绑定状态:source-of-truth 在系统/Prefs,旋转后必须重读最新值 — 保持 remember。
    var a11yOn by remember { mutableStateOf(PermissionUtil.accessibilityGranted(ctx)) }
    var overlayOn by remember { mutableStateOf(PermissionUtil.overlayGranted(ctx)) }
    var floatingOn by remember { mutableStateOf(SettingsPrefs.floatingEnabled(ctx)) }
    var boundPhone by remember { mutableStateOf(AuthPrefs.phone(ctx)) }
    // 弹窗打开态:用户主观状态,旋转期间不应突然关闭 — 用 Saveable。
    var unbindOpen by rememberSaveable { mutableStateOf(false) }
    var clearAllOpen by rememberSaveable { mutableStateOf(false) }
    var clearDemoOpen by rememberSaveable { mutableStateOf(false) }

    DisposableEffect(lifecycleOwner) {
        val obs = LifecycleEventObserver { _, e ->
            if (e == Lifecycle.Event.ON_RESUME) {
                a11yOn = PermissionUtil.accessibilityGranted(ctx)
                overlayOn = PermissionUtil.overlayGranted(ctx)
                FloatingServiceLauncher.startIfReady(ctx)
            }
        }
        lifecycleOwner.lifecycle.addObserver(obs)
        onDispose { lifecycleOwner.lifecycle.removeObserver(obs) }
    }
    LaunchedEffect(bindState) {
        if (bindState is BindPhoneState.Success) boundPhone = AuthPrefs.phone(ctx)
    }

    Scaffold(
        containerColor = DbbColors.Bg,
        contentWindowInsets = WindowInsets(0),
    ) { padding ->
        Column(
            Modifier
                .padding(padding)
                .fillMaxSize()
                .background(DbbColors.Bg)
                .verticalScroll(rememberScrollState()),
        ) {
            HeroBanner(
                title = "我的",
                subtitle = "账号 · 权限 · 算价工具 · 自检",
                icon = Icons.Filled.Person,
                gradient = DbbGradients.Mine,
            )
            Column(Modifier.padding(horizontal = 14.dp, vertical = 12.dp)) {
            // 顶部 hero 个人卡(teal-dark → teal 渐变,统计取本机 Room 实时计算)
            PersonHeroCard(
                phone = boundPhone,
                stats = mineStats,
                onBind = { ctx.findActivity()?.let { bindVm.bind(it) } },
                onUnbind = { unbindOpen = true },
            )
            Spacer(Modifier.height(14.dp))

            // 权限
            SectionLabel("权限")
            SectionCard {
                StatusRow("无障碍服务", if (a11yOn) "已开启 ✓" else "去开启", a11yOn) {
                    runCatching { ctx.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)) }
                }
                ThinDivider()
                StatusRow("悬浮窗权限", if (overlayOn) "已开启 ✓" else "去开启", overlayOn) {
                    runCatching {
                        ctx.startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:${ctx.packageName}")))
                    }
                }
                ThinDivider()
                ClickRow("自启动管理", "保证浮窗与提醒不被系统杀") { VendorAutoStart.openAutoStartSettings(ctx) }
                ThinDivider()
                Row(
                    Modifier.fillMaxWidth().padding(horizontal = 14.dp, vertical = 12.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Column(Modifier.weight(1f)) {
                        Text("比价浮窗", fontWeight = FontWeight.Medium, color = DbbColors.Ink)
                        Text("在购物 App 内显示比价按钮", color = DbbColors.InkTer, fontSize = 11.sp)
                    }
                    Switch(
                        checked = floatingOn,
                        onCheckedChange = {
                            floatingOn = it
                            SettingsPrefs.setFloatingEnabled(ctx, it)
                            if (it) FloatingServiceLauncher.startIfReady(ctx)
                        },
                        colors = SwitchDefaults.colors(checkedTrackColor = DbbColors.Teal),
                    )
                }
            }
            Spacer(Modifier.height(14.dp))

            // 算价工具
            SectionLabel("算价工具")
            SectionCard {
                EmojiRow("📏", "单价对比", "不同规格,谁更划算", onOpenUnitPrice)
                ThinDivider()
                EmojiRow("🛒", "凑单计算器", "看怎么凑满减最省", onOpenBundle)
                ThinDivider()
                EmojiRow("📉", "分期真实利率", "揭穿「免息分期」真实年化", onOpenInstallment)
            }
            Spacer(Modifier.height(14.dp))

            // 数据与通用
            SectionLabel("数据与通用")
            SectionCard {
                EmojiRow("📋", "我的记录", "全部价格记录与商品组", onOpenRecords)
                ThinDivider()
                ClickRow("清除示例数据", "仅删内置示例") { clearDemoOpen = true }
                ThinDivider()
                ClickRow("运行自检", "全部正常") { onOpenDiagnostics() }
                ThinDivider()
                ClickRow("隐私政策", null) { onOpenPrivacy() }
                ThinDivider()
                ClickRow("关于多比比", null) { onOpenAbout() }
                ThinDivider()
                ClickRow("清空全部数据", "删除全部记录 / 商品组 / 监控", danger = true) { clearAllOpen = true }
            }
            Spacer(Modifier.height(20.dp))
            }
        }
    }

    // 绑定状态弹窗
    when (val s = bindState) {
        is BindPhoneState.Working -> AlertDialog(
            onDismissRequest = {}, confirmButton = {},
            title = { Text("绑定中") },
            text = {
                Row(verticalAlignment = Alignment.CenterVertically) {
                    CircularProgressIndicator(Modifier.padding(end = 12.dp))
                    Text(s.step)
                }
            },
        )
        is BindPhoneState.Failed -> AlertDialog(
            onDismissRequest = bindVm::reset,
            confirmButton = { TextButton(onClick = bindVm::reset) { Text("知道了") } },
            title = { Text("绑定失败") }, text = { Text(s.reason) },
        )
        is BindPhoneState.Success -> AlertDialog(
            onDismissRequest = bindVm::reset,
            confirmButton = { TextButton(onClick = bindVm::reset) { Text("好的") } },
            title = { Text("绑定成功") }, text = { Text("已绑定 ${AuthPrefs.maskedPhone(s.phone)}") },
        )
        else -> {}
    }
    if (unbindOpen) AlertDialog(
        onDismissRequest = { unbindOpen = false },
        title = { Text("解绑手机号?") }, text = { Text("解绑后本机数据保留,可随时重新绑定。") },
        confirmButton = {
            TextButton(onClick = {
                AuthPrefs.clear(ctx); boundPhone = null; unbindOpen = false
            }) { Text("解绑", color = DbbColors.Up) }
        },
        dismissButton = { TextButton(onClick = { unbindOpen = false }) { Text("取消") } },
    )
    if (clearDemoOpen) AlertDialog(
        onDismissRequest = { clearDemoOpen = false },
        title = { Text("清除示例数据?") }, text = { Text("仅删除内置示例,你自己记的真实数据不受影响。") },
        confirmButton = {
            TextButton(onClick = {
                clearDemoOpen = false; mineVm.clearDemo {}
            }) { Text("清除", color = DbbColors.Up) }
        },
        dismissButton = { TextButton(onClick = { clearDemoOpen = false }) { Text("取消") } },
    )
    if (clearAllOpen) AlertDialog(
        onDismissRequest = { clearAllOpen = false },
        title = { Text("清空全部数据?") }, text = { Text("将删除全部价格记录、商品组与降价监控,不可恢复。") },
        confirmButton = {
            TextButton(onClick = {
                clearAllOpen = false; mineVm.clearAll {}
            }) { Text("清空", color = DbbColors.Up) }
        },
        dismissButton = { TextButton(onClick = { clearAllOpen = false }) { Text("取消") } },
    )
}

/**
 * Hero 渐变个人卡 + 4 栏 stat。统计全部来自 [MineStats] 的本机 Room 计算,空库时为 0。
 * 渐变改成 teal-dark→teal,去掉 sky 色,与新设计语言"3 色为主"对齐。
 */
@Composable
private fun PersonHeroCard(
    phone: String?,
    stats: MineStats,
    onBind: () -> Unit,
    onUnbind: () -> Unit,
) {
    val gradient = Brush.linearGradient(listOf(DbbColors.TealDark, DbbColors.Teal))
    val masked = phone?.let { AuthPrefs.maskedPhone(it) } ?: "未绑定手机号"
    val sub = if (phone != null) "已绑定 · 多端同步已开启" else "点击绑定开启多端同步"
    Column(
        Modifier
            .fillMaxWidth()
            .clip(RoundedCornerShape(18.dp))
            .background(gradient)
            .padding(15.dp),
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Box(
                Modifier
                    .size(50.dp)
                    .clip(CircleShape)
                    .background(Color.White.copy(alpha = 0.22f)),
                contentAlignment = Alignment.Center,
            ) {
                Icon(Icons.Filled.Person, contentDescription = null, tint = Color.White, modifier = Modifier.size(30.dp))
            }
            Spacer(Modifier.width(13.dp))
            Column(
                modifier = Modifier
                    .weight(1f)
                    .clickable { if (phone == null) onBind() else onUnbind() },
            ) {
                Text(masked, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 17.sp)
                Text(sub, color = Color.White.copy(alpha = 0.9f), fontSize = 12.sp)
            }
            IconButton(onClick = { /* TODO 设置 */ }) {
                Icon(Icons.Filled.Settings, contentDescription = "设置", tint = Color.White)
            }
        }
        Spacer(Modifier.height(12.dp))
        Row {
            StatColumn(stats.totalProducts.toString(), "已比价", Modifier.weight(1f))
            VerticalLine()
            StatColumn(stats.totalRecords.toString(), "价格记录", Modifier.weight(1f))
            VerticalLine()
            StatColumn(stats.activeAlerts.toString(), "监控中", Modifier.weight(1f))
            VerticalLine()
            StatColumn("¥${fmtYuan(stats.totalSaved)}", "累计省", Modifier.weight(1f))
        }
    }
}

@Composable
private fun StatColumn(value: String, label: String, modifier: Modifier = Modifier) {
    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Text(value, color = Color.White, fontWeight = FontWeight.Bold, fontSize = 17.sp)
        Text(label, color = Color.White.copy(alpha = 0.85f), fontSize = 11.sp)
    }
}

@Composable
private fun VerticalLine() {
    Box(
        Modifier
            .width(1.dp)
            .height(28.dp)
            .background(Color.White.copy(alpha = 0.25f)),
    )
}

@Composable
private fun SectionLabel(title: String) {
    Text(
        title,
        color = DbbColors.InkSec,
        fontSize = 12.sp,
        fontWeight = FontWeight.Medium,
        modifier = Modifier.padding(start = 4.dp, bottom = 6.dp),
    )
}

@Composable
private fun SectionCard(content: @Composable () -> Unit) {
    Card(
        Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
        shape = RoundedCornerShape(16.dp),
    ) { Column { content() } }
}

@Composable
private fun ThinDivider() {
    Divider(color = DbbColors.Border, thickness = 1.dp, modifier = Modifier.padding(horizontal = 14.dp))
}

@Composable
private fun ClickRow(title: String, subtitle: String?, danger: Boolean = false, onClick: () -> Unit) {
    Row(
        Modifier.fillMaxWidth().clickable(onClick = onClick).padding(horizontal = 14.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Column(Modifier.weight(1f)) {
            Text(title, fontWeight = FontWeight.Medium, color = if (danger) DbbColors.Up else DbbColors.Ink)
            subtitle?.let { Text(it, color = DbbColors.InkTer, fontSize = 11.sp) }
        }
        Text("›", color = DbbColors.InkTer, fontSize = 18.sp)
    }
}

@Composable
private fun StatusRow(title: String, status: String, ok: Boolean, onClick: () -> Unit) {
    Row(
        Modifier.fillMaxWidth().clickable(onClick = onClick).padding(horizontal = 14.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Text(title, fontWeight = FontWeight.Medium, color = DbbColors.Ink, modifier = Modifier.weight(1f))
        Text(status, color = if (ok) DbbColors.Save else DbbColors.Teal, fontSize = 13.sp, fontWeight = FontWeight.SemiBold)
    }
}

@Composable
private fun EmojiRow(emoji: String, title: String, subtitle: String, onClick: () -> Unit) {
    Row(
        Modifier.fillMaxWidth().clickable(onClick = onClick).padding(horizontal = 14.dp, vertical = 12.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Text(emoji, fontSize = 18.sp, modifier = Modifier.width(28.dp))
        Column(Modifier.weight(1f)) {
            Text(title, fontWeight = FontWeight.Medium, color = DbbColors.Ink)
            Text(subtitle, color = DbbColors.InkTer, fontSize = 11.sp)
        }
        Text("›", color = DbbColors.InkTer, fontSize = 18.sp)
    }
}
