package com.jishisongfu.duobibi.ui.discover

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
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.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Explore
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.LocalFireDepartment
import androidx.compose.material.icons.filled.NewReleases
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
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.graphics.vector.ImageVector
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.compose.collectAsStateWithLifecycle
import com.jishisongfu.duobibi.ui.HeroBanner
import com.jishisongfu.duobibi.ui.arena.ArenaCategory
import com.jishisongfu.duobibi.ui.rememberHaptics
import com.jishisongfu.duobibi.ui.theme.DbbColors
import com.jishisongfu.duobibi.ui.theme.DbbGradients
import com.jishisongfu.duobibi.util.WatchedPrefs

/**
 * 发现页:双列瀑布流"比价好物"。
 *
 * 跟傻瓜比价 CommunityScreen 的差异(避免套壳):
 * - 双列瀑布流 vs 单列大图笔记
 * - 卡片重心是"价格对比"而不是图文笔记
 * - 命名"发现"不是"社区","比价好物"不是"好价帖"
 *
 * 点击卡片 -> [onOpenDetail],进入 ProductDetailScreen(三级深度起点)。
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DiscoverScreen(
    onOpenDetail: (itemId: String) -> Unit,
    onOpenWatched: () -> Unit,
    vm: DiscoverViewModel = hiltViewModel(),
) {
    val items by vm.items.collectAsStateWithLifecycle()
    val selected by vm.selectedCategory.collectAsStateWithLifecycle()
    val query by vm.query.collectAsStateWithLifecycle()
    val ctx = LocalContext.current
    val watchedFlow = remember { WatchedPrefs.watchedFlow(ctx) }
    val watchedIds by watchedFlow.collectAsStateWithLifecycle(initialValue = WatchedPrefs.watchedIds(ctx))
    // 今日新品过滤态在 UI 层维护(纯展示开关,不污染 VM)。开启时取 SEED 后 12 条作为"新增"。
    // 跟 selectedCategory 互斥:开"今日新品"时清品类筛选,选品类时关"今日新品"。
    // 用 rememberSaveable:旋转 / 跨配置变化 / 从详情页返回时保留开关态。
    var todayOnly by rememberSaveable { mutableStateOf(false) }
    val displayedItems = remember(items, todayOnly) {
        if (todayOnly) items.takeLast(12) else items
    }

    Scaffold(
        containerColor = DbbColors.Bg,
        contentWindowInsets = WindowInsets(0),
    ) { padding ->
        Column(
            Modifier.padding(padding).fillMaxSize().background(MaterialTheme.colorScheme.background),
        ) {
            HeroBanner(
                title = "发现",
                subtitle = "精选比价好物 · 一眼看全网",
                icon = Icons.Filled.Explore,
                gradient = DbbGradients.Discover,
                trailing = {
                    WatchedHeroAction(count = watchedIds.size, onClick = onOpenWatched)
                },
            )
            SearchPill(
                query = query,
                onQueryChange = {
                    // 输入搜索时关闭"今日新品"过滤,搜索意图比 toggle 更具体
                    if (it.isNotBlank() && todayOnly) todayOnly = false
                    vm.setQuery(it)
                },
            )
            QuickStrip(
                watchedCount = watchedIds.size,
                todayOnly = todayOnly,
                hotSelected = selected == ArenaCategory.Digital,
                onWatched = onOpenWatched,
                onTodayToggle = {
                    todayOnly = !todayOnly
                    if (todayOnly) vm.selectCategory(null)  // 两个 filter 互斥
                },
                onHotCategory = {
                    todayOnly = false
                    vm.selectCategory(
                        if (selected == ArenaCategory.Digital) null else ArenaCategory.Digital
                    )
                },
            )
            CategoryChipsRow(
                selected = selected,
                onSelect = {
                    todayOnly = false  // 选品类时关"今日新品"
                    vm.selectCategory(it)
                },
            )
            Spacer(Modifier.height(2.dp))
            if (displayedItems.isEmpty()) {
                Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text(
                        // 搜索无结果 vs 品类无种子 vs 今日新品截空,文案各不相同
                        when {
                            query.isNotBlank() -> "没找到「$query」相关商品\n换个关键词或换个品类试试"
                            todayOnly -> "今日新品暂空,稍后再来看看"
                            else -> "该品类暂无种子,换一个看看"
                        },
                        color = DbbColors.InkTer, fontSize = 13.sp,
                        textAlign = androidx.compose.ui.text.style.TextAlign.Center,
                    )
                }
            } else {
                LazyVerticalStaggeredGrid(
                    columns = StaggeredGridCells.Fixed(2),
                    modifier = Modifier.fillMaxSize(),
                    contentPadding = PaddingValues(10.dp, 4.dp, 10.dp, 16.dp),
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                    verticalItemSpacing = 8.dp,
                ) {
                    items(displayedItems, key = { it.id }) { item ->
                        PriceCompareCard(
                            item = item,
                            isWatched = item.id in watchedIds,
                            onClick = { onOpenDetail(item.id) },
                            onToggleWatch = { WatchedPrefs.toggle(ctx, item.id) },
                        )
                    }
                }
            }
        }
    }
}

/**
 * Hero 下方"搜索胶囊" —— 解决"列表 30 条用户找不到目标商品"的核心痛点。
 *
 * 设计:
 *  - 圆角 24dp 胶囊,白底 + 浅边框,不抢 hero 视觉
 *  - 左 🔍 用 Teal 强化"可点输入"暗示
 *  - 右 × 仅 query 非空时显示,一键清空
 *  - IME 显示 "Search" action,但实际过滤是逐字触发(不需要按确认),
 *    搜索动作走 VM.setQuery → combine StateFlow 立即更新列表
 *  - placeholder 同时提示"商品名 / 品类",对应 VM 里的双字段匹配逻辑
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun SearchPill(query: String, onQueryChange: (String) -> Unit) {
    TextField(
        value = query,
        onValueChange = onQueryChange,
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 12.dp, vertical = 8.dp),
        placeholder = {
            Text(
                "搜商品名或品类,如 iPhone / 数码",
                fontSize = 13.sp, color = DbbColors.InkTer,
            )
        },
        leadingIcon = { Icon(Icons.Filled.Search, contentDescription = null, tint = DbbColors.Teal) },
        trailingIcon = {
            if (query.isNotBlank()) {
                IconButton(onClick = { onQueryChange("") }) {
                    Icon(Icons.Filled.Close, contentDescription = "清空", tint = DbbColors.InkTer)
                }
            }
        },
        singleLine = true,
        shape = RoundedCornerShape(24.dp),
        // 关键:把 4 条 indicator(下划线)全干掉,容器底色用 Card 白 — 一眼是个胶囊不是文本框
        colors = TextFieldDefaults.colors(
            focusedContainerColor = DbbColors.Card,
            unfocusedContainerColor = DbbColors.Card,
            focusedIndicatorColor = Color.Transparent,
            unfocusedIndicatorColor = Color.Transparent,
            disabledIndicatorColor = Color.Transparent,
            errorIndicatorColor = Color.Transparent,
        ),
    )
}

/**
 * Hero 右上 ❤️ 入口 + 数量徽章。
 * count=0 时只显示白色空心心,>0 时叠红圆点 + 白字计数(微信小红点风格)。
 */
@Composable
private fun WatchedHeroAction(count: Int, onClick: () -> Unit) {
    val haptics = rememberHaptics()
    Box(contentAlignment = Alignment.TopEnd) {
        IconButton(onClick = { haptics.toggle(); onClick() }) {
            Icon(Icons.Filled.Favorite, contentDescription = "我的关注", tint = Color.White)
        }
        if (count > 0) {
            Box(
                Modifier
                    .padding(top = 4.dp, end = 4.dp)
                    .clip(CircleShape)
                    .background(DbbColors.Rose)
                    .padding(horizontal = 5.dp, vertical = 1.dp),
            ) {
                Text(
                    if (count > 99) "99+" else count.toString(),
                    color = Color.White,
                    fontSize = 9.sp,
                    fontWeight = FontWeight.ExtraBold,
                )
            }
        }
    }
}

/**
 * Hero 与品类 chip 之间的快捷条 —— 3 个 tile(我的关注 / 今日新品 / 热门品类)。
 *
 * 设计要点:
 *  - 3 列等宽 (weight=1f),value 文字必须 ≤ 4 个中文 (12sp Bold) 才不溢出折行
 *  - selected 态用 tintBg 实底反馈"我正激活",未选 = 白卡
 *  - 三个 tile 都可点:关注=跳页,今日=toggle 过滤,热门=toggle 数码品类
 */
@Composable
private fun QuickStrip(
    watchedCount: Int,
    todayOnly: Boolean,
    hotSelected: Boolean,
    onWatched: () -> Unit,
    onTodayToggle: () -> Unit,
    onHotCategory: () -> Unit,
) {
    Row(
        Modifier
            .fillMaxWidth()
            .padding(horizontal = 12.dp, vertical = 10.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        QuickTile(
            icon = Icons.Filled.Favorite,
            tint = DbbColors.Rose,
            tintBg = DbbColors.RoseBg,
            title = "我的关注",
            value = if (watchedCount > 0) "$watchedCount 件" else "去收藏",
            selected = false,  // 关注是"跳页"动作,不存在选中态
            onClick = onWatched,
            modifier = Modifier.weight(1f),
        )
        QuickTile(
            icon = Icons.Filled.NewReleases,
            tint = DbbColors.Teal,
            tintBg = DbbColors.TealBg,
            title = "今日新品",
            value = if (todayOnly) "已筛" else "看新品",
            selected = todayOnly,
            onClick = onTodayToggle,
            modifier = Modifier.weight(1f),
        )
        QuickTile(
            icon = Icons.Filled.LocalFireDepartment,
            tint = DbbColors.Up,
            tintBg = DbbColors.UpBg,
            title = "热门品类",
            value = "数码",        // 缩短到 2 字防 3 列均分下折行
            selected = hotSelected,
            onClick = onHotCategory,
            modifier = Modifier.weight(1f),
        )
    }
}

@Composable
private fun QuickTile(
    icon: ImageVector,
    tint: Color,
    tintBg: Color,
    title: String,
    value: String,
    selected: Boolean,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val haptics = rememberHaptics()
    Row(
        modifier
            .clip(RoundedCornerShape(12.dp))
            .background(if (selected) tintBg else DbbColors.Card)
            .clickable { haptics.toggle(); onClick() }
            .padding(horizontal = 10.dp, vertical = 9.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Box(
            Modifier
                .size(28.dp)
                .clip(CircleShape)
                .background(if (selected) Color.White else tintBg),
            contentAlignment = Alignment.Center,
        ) {
            Icon(icon, contentDescription = null, tint = tint, modifier = Modifier.size(15.dp))
        }
        Spacer(Modifier.size(7.dp))
        Column {
            Text(
                title,
                color = if (selected) tint else DbbColors.InkSec,
                fontSize = 10.sp,
                maxLines = 1,
            )
            Text(
                value,
                color = if (selected) tint else DbbColors.Ink,
                fontSize = 12.sp,
                fontWeight = FontWeight.Bold,
                maxLines = 1,
            )
        }
    }
}

@Composable
private fun CategoryChipsRow(selected: ArenaCategory?, onSelect: (ArenaCategory?) -> Unit) {
    Row(
        Modifier
            .fillMaxWidth()
            .horizontalScroll(rememberScrollState())
            // 顶 padding 调小到 2dp,跟 QuickStrip 之间的视觉间距从 20dp 降到 12dp,贴得更紧。
            .padding(start = 12.dp, end = 12.dp, top = 2.dp, bottom = 10.dp),
        horizontalArrangement = Arrangement.spacedBy(6.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        FilterChip(
            selected = selected == null,
            onClick = { onSelect(null) },
            label = { Text("全部") },
            colors = FilterChipDefaults.filterChipColors(
                selectedContainerColor = DbbColors.Teal,
                selectedLabelColor = Color.White,
            ),
        )
        ArenaCategory.entries.forEach { c ->
            FilterChip(
                selected = selected == c,
                onClick = { onSelect(c) },
                label = { Text(c.title) },
                colors = FilterChipDefaults.filterChipColors(
                    selectedContainerColor = DbbColors.Teal,
                    selectedLabelColor = Color.White,
                ),
            )
        }
    }
}
