package com.jishisongfu.duobibi.ui.records

import androidx.compose.foundation.BorderStroke
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.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.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.DeleteOutline
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedButton
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.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.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.jishisongfu.duobibi.data.db.PriceRecord
import com.jishisongfu.duobibi.ui.DbbProgressBar
import com.jishisongfu.duobibi.ui.PlatformAvatar
import com.jishisongfu.duobibi.ui.ProductThumb
import com.jishisongfu.duobibi.ui.TagChip
import com.jishisongfu.duobibi.ui.fmtYuan
import com.jishisongfu.duobibi.ui.theme.DbbColors
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ClusterDetailScreen(
    clusterId: Long,
    onBack: () -> Unit,
    vm: ClusterDetailViewModel = hiltViewModel(),
) {
    LaunchedEffect(clusterId) { vm.load(clusterId) }
    val cluster by vm.cluster.collectAsStateWithLifecycle()
    val records by vm.records.collectAsStateWithLifecycle()

    var menuOpen by rememberSaveable { mutableStateOf(false) }
    var renameOpen by rememberSaveable { mutableStateOf(false) }
    var deleteClusterOpen by rememberSaveable { mutableStateOf(false) }
    var deleteRecordId by rememberSaveable { mutableStateOf<Long?>(null) }

    Scaffold(
        containerColor = DbbColors.Bg,
        topBar = {
            TopAppBar(
                title = {
                    Text(
                        cluster?.title ?: "商品详情",
                        fontWeight = FontWeight.Bold,
                        fontSize = 18.sp,
                        color = DbbColors.Ink,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                    )
                },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, "返回", tint = DbbColors.Ink)
                    }
                },
                actions = {
                    IconButton(onClick = { menuOpen = true }) {
                        Icon(Icons.Filled.MoreVert, "更多", tint = DbbColors.Ink)
                    }
                    DropdownMenu(expanded = menuOpen, onDismissRequest = { menuOpen = false }) {
                        DropdownMenuItem(text = { Text("重命名") }, onClick = { menuOpen = false; renameOpen = true })
                        DropdownMenuItem(
                            text = { Text("删除商品组", color = DbbColors.Up) },
                            onClick = { menuOpen = false; deleteClusterOpen = true },
                        )
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors(containerColor = DbbColors.Card),
            )
        },
    ) { padding ->
        if (records.isEmpty()) {
            Box(
                Modifier.padding(padding).fillMaxSize().background(DbbColors.Bg),
                contentAlignment = Alignment.Center,
            ) {
                Text("该商品组暂无记录", color = DbbColors.InkTer, fontSize = 13.sp)
            }
        } else {
            val minP = records.minOf { it.price }
            val maxP = records.maxOf { it.price }
            val typical = cluster?.typicalPrice
            val sortedAsc = records.sortedBy { it.createdAt }

            Column(
                Modifier
                    .padding(padding)
                    .fillMaxSize()
                    .background(DbbColors.Bg)
                    .verticalScroll(rememberScrollState())
                    .padding(horizontal = 14.dp, vertical = 12.dp),
            ) {
                SummaryCard(records, minP, maxP, typical, sortedAsc)
                Spacer(Modifier.height(10.dp))

                PlatformMinCard(records, minP, maxP)
                Spacer(Modifier.height(10.dp))

                if (records.size >= 2) {
                    TrendCard(records, sortedAsc)
                    Spacer(Modifier.height(10.dp))
                }

                Text("全部记录", fontWeight = FontWeight.Bold, color = DbbColors.Ink, fontSize = 14.sp)
                Spacer(Modifier.height(6.dp))
                RecordsList(records, minP) { deleteRecordId = it }

                Spacer(Modifier.height(14.dp))
                ActionRow()
                Spacer(Modifier.height(8.dp))
            }
        }
    }

    if (renameOpen) {
        var text by remember { mutableStateOf(cluster?.title ?: "") }
        AlertDialog(
            onDismissRequest = { renameOpen = false },
            title = { Text("重命名商品组") },
            text = { OutlinedTextField(value = text, onValueChange = { text = it }, singleLine = true) },
            confirmButton = {
                TextButton(onClick = {
                    if (text.isNotBlank()) vm.rename(text); renameOpen = false
                }) { Text("保存", color = DbbColors.Teal) }
            },
            dismissButton = { TextButton(onClick = { renameOpen = false }) { Text("取消") } },
        )
    }
    if (deleteClusterOpen) {
        AlertDialog(
            onDismissRequest = { deleteClusterOpen = false },
            title = { Text("删除整个商品组?") },
            text = { Text("该商品组及其下全部价格记录都会被删除,不可恢复。") },
            confirmButton = {
                TextButton(onClick = {
                    deleteClusterOpen = false; vm.deleteCluster(onBack)
                }) { Text("删除", color = DbbColors.Up) }
            },
            dismissButton = { TextButton(onClick = { deleteClusterOpen = false }) { Text("取消") } },
        )
    }
    deleteRecordId?.let { rid ->
        AlertDialog(
            onDismissRequest = { deleteRecordId = null },
            title = { Text("删除这条记录?") },
            confirmButton = {
                TextButton(onClick = {
                    deleteRecordId = null; vm.deleteRecord(rid, onBack)
                }) { Text("删除", color = DbbColors.Up) }
            },
            dismissButton = { TextButton(onClick = { deleteRecordId = null }) { Text("取消") } },
        )
    }
}

@Composable
private fun SummaryCard(
    records: List<PriceRecord>,
    minP: Double,
    maxP: Double,
    typical: Double?,
    sortedAsc: List<PriceRecord>,
) {
    val firstAt = sortedAsc.first().createdAt
    val latestAt = sortedAsc.last().createdAt
    val trackedDays = TimeUnit.MILLISECONDS.toDays(latestAt - firstAt).toInt().coerceAtLeast(0)
    val minRec = records.minBy { it.price }
    val savingsVsTypical = typical?.let { (it - minP).coerceAtLeast(0.0) }

    val titleForThumb = records.firstOrNull()?.title ?: ""
    Card(
        Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = DbbColors.TealBg),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column(Modifier.padding(12.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                ProductThumb(title = titleForThumb, size = 54.dp, containerColor = Color.White)
                Spacer(Modifier.width(12.dp))
                Column(Modifier.weight(1f)) {
                    Row(verticalAlignment = Alignment.Bottom) {
                        Text("本机最低 ", color = DbbColors.InkSec, fontSize = 13.sp)
                        Text(
                            "¥${fmtYuan(minP)}",
                            color = DbbColors.TealDark,
                            fontWeight = FontWeight.ExtraBold,
                            fontSize = 24.sp,
                        )
                        Spacer(Modifier.width(6.dp))
                        PlatformAvatar(minRec.sourceApp, small = true)
                        Spacer(Modifier.width(4.dp))
                        Text(
                            minRec.sourceApp, color = DbbColors.TealDark, fontSize = 12.sp,
                            fontWeight = FontWeight.SemiBold,
                        )
                        Spacer(Modifier.weight(1f))
                        if (savingsVsTypical != null && savingsVsTypical > 0) {
                            Box(
                                Modifier
                                    .clip(RoundedCornerShape(6.dp))
                                    .background(Color.White)
                                    .padding(horizontal = 6.dp, vertical = 2.dp),
                            ) {
                                Text(
                                    "省 ¥${fmtYuan(savingsVsTypical)}",
                                    color = DbbColors.Save,
                                    fontWeight = FontWeight.Bold,
                                    fontSize = 10.sp,
                                )
                            }
                        }
                    }
                    Spacer(Modifier.height(4.dp))
                    val typicalPart = if (typical != null) " · 常见 ¥${fmtYuan(typical)}" else ""
                    Text(
                        "最高 ¥${fmtYuan(maxP)} · 价差 ¥${fmtYuan(maxP - minP)} · 共 ${records.size} 条$typicalPart",
                        color = DbbColors.InkSec, fontSize = 12.sp,
                    )
                }
            }
            Spacer(Modifier.height(8.dp))
            val firstStr = dateFmtShort.format(Date(firstAt))
            val latestStr = dateFmtShort.format(Date(latestAt))
            Text(
                "首次记录 $firstStr · 最近更新 $latestStr · 已追踪 $trackedDays 天",
                color = DbbColors.InkTer, fontSize = 11.sp,
            )
        }
    }
}

@Composable
private fun PlatformMinCard(records: List<PriceRecord>, minP: Double, maxP: Double) {
    // 取每个平台的最低价
    val perPlatform = records.groupBy { it.sourceApp }
        .map { (app, recs) -> app to recs.minOf { it.price } }
        .sortedBy { it.second }
    val range = (maxP - minP).coerceAtLeast(0.01)

    Card(
        Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column(Modifier.padding(horizontal = 14.dp, vertical = 12.dp)) {
            Text("各平台最低价", fontWeight = FontWeight.Bold, color = DbbColors.Ink, fontSize = 13.sp)
            Spacer(Modifier.height(8.dp))
            perPlatform.forEachIndexed { i, (app, price) ->
                if (i > 0) Spacer(Modifier.height(4.dp))
                Row(
                    Modifier.padding(vertical = 4.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    PlatformAvatar(app, small = true)
                    Spacer(Modifier.width(8.dp))
                    Text(
                        app, color = DbbColors.Ink, fontSize = 13.sp,
                        modifier = Modifier.width(56.dp),
                    )
                    val isMin = price == minP
                    val isMax = price == maxP && perPlatform.size > 1
                    // 反向映射:价格越低,bar 越长(满刻度)
                    val frac = (1f - ((price - minP) / range).toFloat()).coerceIn(0.04f, 1f)
                    DbbProgressBar(
                        fraction = frac,
                        color = if (isMax) DbbColors.InkTer else DbbColors.Teal,
                        modifier = Modifier.weight(1f),
                    )
                    Spacer(Modifier.width(8.dp))
                    Text(
                        "¥${fmtYuan(price)}",
                        fontWeight = FontWeight.ExtraBold,
                        fontSize = 14.sp,
                        color = if (isMin) DbbColors.Teal else DbbColors.Ink,
                        modifier = Modifier.width(58.dp),
                        textAlign = TextAlign.End,
                    )
                    Spacer(Modifier.width(6.dp))
                    when {
                        isMin -> TagChip("最低", bg = DbbColors.Teal, fg = Color.White)
                        isMax -> TagChip("最高", bg = DbbColors.UpBg, fg = DbbColors.Up)
                        else -> Spacer(Modifier.width(28.dp))
                    }
                }
            }
        }
    }
}

@Composable
private fun TrendCard(records: List<PriceRecord>, sortedAsc: List<PriceRecord>) {
    val firstStr = dateFmtShort.format(Date(sortedAsc.first().createdAt))
    val latestStr = dateFmtShort.format(Date(sortedAsc.last().createdAt))
    val days = TimeUnit.MILLISECONDS.toDays(sortedAsc.last().createdAt - sortedAsc.first().createdAt)
    Card(
        Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column(Modifier.padding(12.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("价格趋势", fontWeight = FontWeight.Bold, color = DbbColors.Ink, fontSize = 13.sp)
                Spacer(Modifier.weight(1f))
                val rangeLabel = if (days > 0) "$firstStr → $latestStr" else "近期"
                Text(rangeLabel, color = DbbColors.InkTer, fontSize = 11.sp)
            }
            Spacer(Modifier.height(4.dp))
            PriceTrendChart(records)
        }
    }
}

@Composable
private fun RecordsList(records: List<PriceRecord>, minP: Double, onDelete: (Long) -> Unit) {
    val byTime = records.sortedByDescending { it.createdAt }
    // 把每条与"它之前那次"的价差算出来,用于 ↑/↓ 显示
    val firstAt = byTime.minOf { it.createdAt }
    Column {
        byTime.forEachIndexed { i, r ->
            val prev = byTime.getOrNull(i + 1)
            val diff = prev?.let { r.price - it.price }
            RecordRow(
                r = r,
                isMin = r.price == minP,
                diffFromPrev = diff,
                isFirst = r.createdAt == firstAt && prev == null,
                onDelete = { onDelete(r.id) },
            )
            if (i < byTime.lastIndex) {
                Box(Modifier.fillMaxWidth().height(1.dp).background(DbbColors.Border))
            }
        }
    }
}

@Composable
private fun RecordRow(
    r: PriceRecord,
    isMin: Boolean,
    diffFromPrev: Double?,
    isFirst: Boolean,
    onDelete: () -> Unit,
) {
    Row(
        Modifier.fillMaxWidth().padding(vertical = 8.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        PlatformAvatar(r.sourceApp, small = true)
        Spacer(Modifier.width(10.dp))
        Column(Modifier.weight(1f)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text(
                    "¥${fmtYuan(r.price)}",
                    fontWeight = FontWeight.Bold,
                    fontSize = 16.sp,
                    color = if (isMin) DbbColors.Teal else DbbColors.Ink,
                )
                if (isMin) {
                    Spacer(Modifier.width(6.dp))
                    Text(
                        "最低",
                        color = DbbColors.Teal, fontSize = 10.sp,
                        fontWeight = FontWeight.Bold,
                    )
                }
                if (diffFromPrev != null) {
                    Spacer(Modifier.width(6.dp))
                    val arrow = if (diffFromPrev < 0) "↓比上次 ¥${fmtYuan(-diffFromPrev)}" else "↑比上次 ¥${fmtYuan(diffFromPrev)}"
                    val color = if (diffFromPrev < 0) DbbColors.Save else DbbColors.Up
                    Text(arrow, color = color, fontSize = 11.sp)
                }
            }
            val datePart = dateFmt.format(Date(r.createdAt))
            val sub = if (isFirst) "${r.sourceApp} · $datePart · 首次记录" else "${r.sourceApp} · $datePart"
            Text(sub, color = DbbColors.InkTer, fontSize = 11.sp)
        }
        IconButton(onClick = onDelete) {
            Icon(Icons.Filled.DeleteOutline, "删除", tint = DbbColors.InkTer, modifier = Modifier.size(20.dp))
        }
    }
}

@Composable
private fun ActionRow() {
    Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
        OutlinedButton(
            onClick = { /* TODO 加入降价雷达 */ },
            modifier = Modifier.weight(1f).height(44.dp),
            shape = RoundedCornerShape(14.dp),
            border = BorderStroke(1.5.dp, DbbColors.Teal),
        ) {
            Text("加入降价雷达", color = DbbColors.TealDark, fontWeight = FontWeight.SemiBold, fontSize = 15.sp)
        }
        Button(
            onClick = { /* TODO 去擂台比全网 */ },
            modifier = Modifier.weight(1f).height(44.dp),
            shape = RoundedCornerShape(14.dp),
            colors = ButtonDefaults.buttonColors(containerColor = DbbColors.Teal),
        ) {
            Text("去擂台比全网", fontWeight = FontWeight.SemiBold, fontSize = 15.sp)
        }
    }
}

private val dateFmt = SimpleDateFormat("MM-dd HH:mm", Locale.getDefault())
private val dateFmtShort = SimpleDateFormat("MM-dd", Locale.getDefault())
