package com.jishisongfu.duobibi.ui.detail

import android.widget.Toast
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Image
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.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.layout.statusBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Balance
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.NotificationsActive
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.material.icons.outlined.IosShare
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.jishisongfu.duobibi.ui.PlatformChip
import com.jishisongfu.duobibi.ui.TagChip
import com.jishisongfu.duobibi.ui.rememberHaptics
import com.jishisongfu.duobibi.ui.discover.DISCOVER_SEED
import com.jishisongfu.duobibi.ui.discover.DiscoverItem
import com.jishisongfu.duobibi.ui.fmtYuan
import com.jishisongfu.duobibi.ui.theme.DbbColors
import com.jishisongfu.duobibi.ui.worth.computeHistoryStats
import com.jishisongfu.duobibi.ui.worth.generate60dPrices
import com.jishisongfu.duobibi.util.PlatformSearch
import com.jishisongfu.duobibi.util.WatchedPrefs

/**
 * 商品详情页 —— Discover/Arena 共用的三级深度枢纽。
 *
 * 进入方式:Discover 瀑布流卡点击 → 这里。
 * 出去方式:返回 / 加入降价雷达 / 跳比价 Tab(跨平台对比) / 跳同类商品(自递归)
 *
 * 内容自上而下:
 *   1) Hero 区(渐变,顶到状态栏 + 返回按钮 + 商品 emoji+ 商品名 + 大价格 + 平台 chip)
 *   2) 多平台对比表(每平台一行,可点击跳搜)
 *   3) 60 天历史价格曲线(迷你)+ 60d 最低/均价/水位分位
 *   4) 行动 CTA(加入降价雷达 / 跨平台对比 / 去最低平台搜)
 *   5) 同类好物推荐(2-4 个同 category 的其它 DiscoverItem)
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProductDetailScreen(
    itemId: String,
    onBack: () -> Unit,
    onOpenArena: (title: String) -> Unit,
    onAddAlert: (title: String, target: Double) -> Unit,
    onOpenDetail: (itemId: String) -> Unit,
) {
    val item = remember(itemId) { DISCOVER_SEED.firstOrNull { it.id == itemId } }

    Scaffold(
        containerColor = DbbColors.Bg,
        contentWindowInsets = WindowInsets(0),
    ) { padding ->
        if (item == null) {
            NotFoundView(onBack = onBack, modifier = Modifier.padding(padding))
            return@Scaffold
        }
        val ctx = LocalContext.current
        val haptics = rememberHaptics()
        LazyColumn(
            modifier = Modifier
                .padding(padding)
                .fillMaxSize(),
            contentPadding = PaddingValues(bottom = 32.dp),
        ) {
            item { DetailHero(item, onBack) }
            item {
                Spacer(Modifier.height(12.dp))
                PriceTableCard(item, ctx)
                Spacer(Modifier.height(10.dp))
            }
            item {
                TrendCard(item)
                Spacer(Modifier.height(10.dp))
            }
            item {
                StatsRow(item)
                Spacer(Modifier.height(12.dp))
            }
            item {
                CtaRow(
                    item = item,
                    onAddAlert = { haptics.confirm(); onAddAlert(item.title, item.minPrice) },
                    onOpenArena = { haptics.confirm(); onOpenArena(item.title) },
                    onSearchLowest = {
                        haptics.confirm()
                        PlatformSearch.copyAndSearch(ctx, item.minPlatform, item.title)
                    },
                )
                Spacer(Modifier.height(12.dp))
            }
            val similar = DISCOVER_SEED.filter { it.category == item.category && it.id != item.id }.take(4)
            if (similar.isNotEmpty()) {
                item {
                    SimilarHeader(category = item.category.title)
                    Spacer(Modifier.height(8.dp))
                }
                items(similar, key = { it.id }) { other ->
                    SimilarRow(other) { onOpenDetail(other.id) }
                    Spacer(Modifier.height(8.dp))
                }
                item { DisclaimerFooter() }
            }
        }
    }
}

// ============== 1) Hero ==============

@Composable
private fun DetailHero(item: DiscoverItem, onBack: () -> Unit) {
    // 用商品类目色当 hero 渐变,让不同品类详情页色感不同(类小红书品类色)。
    val top = item.category.tintFg
    val bottom = blend(item.category.tintFg, Color(0xFF1E293B), 0.35f)
    val ctx = LocalContext.current
    val haptics = rememberHaptics()
    val watchedFlow = remember { WatchedPrefs.watchedFlow(ctx) }
    val watchedIds by watchedFlow.collectAsStateWithLifecycle(initialValue = WatchedPrefs.watchedIds(ctx))
    val isWatched = item.id in watchedIds

    Box(
        Modifier
            .fillMaxWidth()
            .background(Brush.verticalGradient(listOf(top, bottom)))
            .windowInsetsPadding(WindowInsets.statusBars),
    ) {
        Column(
            Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp)
                .padding(top = 6.dp, bottom = 24.dp),
        ) {
            // top bar(返回 + ❤️ + 分享)
            Row(verticalAlignment = Alignment.CenterVertically) {
                IconButton(onClick = onBack, modifier = Modifier.size(40.dp)) {
                    Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "返回", tint = Color.White)
                }
                Spacer(Modifier.weight(1f))
                IconButton(
                    onClick = { haptics.toggle(); WatchedPrefs.toggle(ctx, item.id) },
                    modifier = Modifier.size(40.dp),
                ) {
                    Icon(
                        if (isWatched) Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder,
                        contentDescription = if (isWatched) "取消关注" else "关注",
                        tint = Color.White,
                    )
                }
                IconButton(onClick = { /* TODO 分享卡片 */ }, modifier = Modifier.size(40.dp)) {
                    Icon(Icons.Outlined.IosShare, contentDescription = "分享", tint = Color.White)
                }
            }
            Spacer(Modifier.height(8.dp))
            // 商品圆牌:imageRes 优先(白底圆,跟产品图白底一致),emoji 兜底(半透明白圆,跟 hero 渐变协调)。
            Box(
                Modifier
                    .size(86.dp)
                    .clip(CircleShape)
                    .background(
                        if (item.imageRes != null) Color.White
                        else Color.White.copy(alpha = 0.22f)
                    ),
                contentAlignment = Alignment.Center,
            ) {
                if (item.imageRes != null) {
                    Image(
                        painter = painterResource(item.imageRes),
                        contentDescription = item.title,
                        modifier = Modifier.fillMaxSize().padding(6.dp),
                        contentScale = ContentScale.Fit,
                    )
                } else {
                    Text(item.emoji, fontSize = 44.sp)
                }
            }
            Spacer(Modifier.height(12.dp))
            Row(verticalAlignment = Alignment.CenterVertically) {
                Box(
                    Modifier
                        .clip(RoundedCornerShape(6.dp))
                        .background(Color.White.copy(alpha = 0.22f))
                        .padding(horizontal = 7.dp, vertical = 2.dp),
                ) {
                    Text(item.category.title, color = Color.White, fontSize = 10.sp, fontWeight = FontWeight.Bold)
                }
                if (item.highlight != null) {
                    Spacer(Modifier.width(6.dp))
                    Box(
                        Modifier
                            .clip(RoundedCornerShape(6.dp))
                            .background(Color.White.copy(alpha = 0.85f))
                            .padding(horizontal = 7.dp, vertical = 2.dp),
                    ) {
                        Text(item.highlight, color = item.category.tintFg, fontSize = 10.sp, fontWeight = FontWeight.Bold)
                    }
                }
            }
            Spacer(Modifier.height(8.dp))
            Text(
                item.title,
                color = Color.White,
                fontWeight = FontWeight.ExtraBold,
                fontSize = 18.sp,
                lineHeight = 24.sp,
            )
            Spacer(Modifier.height(16.dp))
            // 大价格 + 节省
            Row(verticalAlignment = Alignment.Bottom) {
                Text(
                    "¥", color = Color.White,
                    fontSize = 18.sp, fontWeight = FontWeight.ExtraBold,
                    letterSpacing = (-0.3).sp,
                )
                Text(
                    fmtYuan(item.minPrice),
                    color = Color.White,
                    fontSize = 42.sp,
                    fontWeight = FontWeight.ExtraBold,
                    letterSpacing = (-1.5).sp,
                )
                Spacer(Modifier.width(8.dp))
                Column {
                    Text(
                        "全网最低 · ${item.minPlatform}",
                        color = Color.White.copy(alpha = 0.92f), fontSize = 11.sp,
                    )
                    if (item.savings > 0) {
                        Text(
                            "较常见价省 ¥${fmtYuan(item.savings)}",
                            color = Color.White, fontSize = 11.sp, fontWeight = FontWeight.SemiBold,
                        )
                    }
                }
            }
        }
        // 底部圆角"咬"出过渡
        Box(
            Modifier
                .fillMaxWidth()
                .height(16.dp)
                .align(Alignment.BottomCenter)
                .clip(RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp))
                .background(DbbColors.Bg),
        )
    }
}

// ============== 2) 多平台对比表 ==============

@Composable
private fun PriceTableCard(item: DiscoverItem, ctx: android.content.Context) {
    val sorted = item.platformPrices.entries.sortedBy { it.value }
    Card(
        Modifier.fillMaxWidth().padding(horizontal = 14.dp),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(2.dp),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column {
            Row(
                Modifier.padding(horizontal = 14.dp, vertical = 12.dp),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text(
                    "多平台到手价",
                    fontWeight = FontWeight.Bold, color = DbbColors.Ink, fontSize = 14.sp,
                )
                Spacer(Modifier.weight(1f))
                Text("点行去搜", color = DbbColors.InkTer, fontSize = 10.sp)
            }
            sorted.forEachIndexed { i, (plat, price) ->
                val isLowest = i == 0
                Row(
                    Modifier
                        .fillMaxWidth()
                        .clickable { PlatformSearch.copyAndSearch(ctx, plat, item.title) }
                        .background(if (isLowest) DbbColors.TealBg else Color.Transparent)
                        .padding(horizontal = 14.dp, vertical = 11.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    // 最低 chip 在前(主流比价 App 套路)+ 平台名胶囊;不再单字+全名重复
                    if (isLowest) {
                        TagChip("最低", bg = DbbColors.Teal, fg = Color.White)
                        Spacer(Modifier.width(6.dp))
                    }
                    PlatformChip(name = plat)
                    Spacer(Modifier.weight(1f))
                    Text(
                        "¥${fmtYuan(price)}",
                        fontWeight = FontWeight.ExtraBold, fontSize = 18.sp,
                        letterSpacing = (-0.5).sp,
                        color = if (isLowest) DbbColors.Teal else DbbColors.Ink,
                    )
                }
                if (i < sorted.lastIndex) {
                    Box(
                        Modifier
                            .padding(horizontal = 14.dp)
                            .fillMaxWidth()
                            .height(1.dp)
                            .background(DbbColors.Border),
                    )
                }
            }
        }
    }
}

// ============== 3) 60 天历史曲线 + 统计 ==============

@Composable
private fun TrendCard(item: DiscoverItem) {
    val prices = remember(item.id) { generate60dPrices(item.title, item.typicalPrice, item.minPrice) }
    val minIdx = prices.indexOf(prices.min())
    Card(
        Modifier.fillMaxWidth().padding(horizontal = 14.dp),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(2.dp),
        shape = RoundedCornerShape(16.dp),
    ) {
        Column(Modifier.padding(14.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("📉", fontSize = 16.sp)
                Spacer(Modifier.width(6.dp))
                Text("60 天价格走势", fontWeight = FontWeight.Bold, color = DbbColors.Ink, fontSize = 14.sp)
                Spacer(Modifier.weight(1f))
                Text("60d 低 ¥${fmtYuan(prices.min())}", color = DbbColors.Up, fontSize = 11.sp, fontWeight = FontWeight.SemiBold)
            }
            Spacer(Modifier.height(8.dp))
            MiniTrendCanvas(prices, minIdx)
            Spacer(Modifier.height(6.dp))
            Row {
                Text("60 天前", color = DbbColors.InkTer, fontSize = 10.sp)
                Spacer(Modifier.weight(1f))
                Text("今天", color = DbbColors.InkTer, fontSize = 10.sp)
            }
        }
    }
}

@Composable
private fun MiniTrendCanvas(prices: List<Double>, minIdx: Int) {
    val minP = prices.min()
    val maxP = prices.max()
    val span = (maxP - minP).coerceAtLeast(0.01)
    val lineColor = DbbColors.Teal
    val areaColor = DbbColors.TealBg
    val gridColor = DbbColors.Border
    Box(Modifier.fillMaxWidth().height(110.dp)) {
        Canvas(Modifier.fillMaxWidth().height(110.dp)) {
            val padL = 4.dp.toPx()
            val padR = 4.dp.toPx()
            val padT = 8.dp.toPx()
            val padB = 8.dp.toPx()
            val w = size.width - padL - padR
            val h = size.height - padT - padB
            for (i in 0..2) {
                val y = padT + h * (i / 2f)
                drawLine(gridColor, Offset(padL, y), Offset(padL + w, y), 1f)
            }
            val points = prices.mapIndexed { idx, p ->
                val x = padL + (idx.toFloat() / prices.lastIndex.toFloat()) * w
                val y = padT + h - (((p - minP) / span).toFloat() * h)
                Offset(x, y)
            }
            val area = Path().apply {
                moveTo(points.first().x, padT + h)
                points.forEach { lineTo(it.x, it.y) }
                lineTo(points.last().x, padT + h)
                close()
            }
            drawPath(area, areaColor)
            val path = Path().apply {
                points.forEachIndexed { i, p -> if (i == 0) moveTo(p.x, p.y) else lineTo(p.x, p.y) }
            }
            drawPath(path, lineColor, style = Stroke(width = 3.5f))
            val minPt = points[minIdx]
            drawCircle(DbbColors.Up, 7f, minPt)
            drawCircle(Color.White, 3f, minPt)
            val nowPt = points.last()
            drawCircle(lineColor, 8f, nowPt)
            drawCircle(Color.White, 3.5f, nowPt)
        }
    }
}

@Composable
private fun StatsRow(item: DiscoverItem) {
    val prices = remember(item.id) { generate60dPrices(item.title, item.typicalPrice, item.minPrice) }
    val stats = remember(prices) { computeHistoryStats(prices, item.minPrice) }
    val pctColor = when {
        stats.percentile < 25 -> DbbColors.Save
        stats.percentile > 75 -> DbbColors.Up
        else -> DbbColors.Teal
    }
    val pctBg = when {
        stats.percentile < 25 -> DbbColors.SaveBg
        stats.percentile > 75 -> DbbColors.UpBg
        else -> DbbColors.TealBg
    }
    Row(
        Modifier.fillMaxWidth().padding(horizontal = 14.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        StatBox("60 天最低", "¥${fmtYuan(stats.min)}", DbbColors.SaveBg, DbbColors.Save, Modifier.weight(1f))
        StatBox("60 天均价", "¥${fmtYuan(stats.avg)}", DbbColors.Fill, DbbColors.InkSec, Modifier.weight(1f))
        StatBox("当前水位", "${stats.percentile}%", pctBg, pctColor, Modifier.weight(1f))
    }
}

@Composable
private fun StatBox(label: String, value: String, bg: Color, fg: Color, modifier: Modifier = Modifier) {
    Box(
        modifier
            .clip(RoundedCornerShape(10.dp))
            .background(bg)
            .padding(vertical = 10.dp),
        contentAlignment = Alignment.Center,
    ) {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            Text(value, fontWeight = FontWeight.ExtraBold, fontSize = 15.sp, color = fg)
            Text(label, fontSize = 10.sp, color = fg)
        }
    }
}

// ============== 4) CTA 行 ==============

@Composable
private fun CtaRow(
    item: DiscoverItem,
    onAddAlert: () -> Unit,
    onOpenArena: () -> Unit,
    onSearchLowest: () -> Unit,
) {
    val ctx = LocalContext.current
    Column(Modifier.padding(horizontal = 14.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
        // 主 CTA — 大,渐变,最低价跳搜
        Button(
            onClick = onSearchLowest,
            modifier = Modifier.fillMaxWidth().height(50.dp),
            shape = RoundedCornerShape(14.dp),
            colors = ButtonDefaults.buttonColors(containerColor = DbbColors.Teal),
        ) {
            Icon(Icons.Filled.Search, contentDescription = null, modifier = Modifier.size(18.dp))
            Spacer(Modifier.width(6.dp))
            Text("去最低价平台「${item.minPlatform}」搜", fontWeight = FontWeight.SemiBold, fontSize = 15.sp)
        }
        // 副 CTA 行 — 加雷达 + 跨平台对比
        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            OutlinedButton(
                onClick = {
                    onAddAlert()
                    Toast.makeText(
                        ctx,
                        "已加入降价雷达 · 心理价 ¥${fmtYuan(item.minPrice)}",
                        Toast.LENGTH_SHORT,
                    ).show()
                },
                modifier = Modifier.weight(1f).height(44.dp),
                shape = RoundedCornerShape(12.dp),
                border = BorderStroke(1.5.dp, DbbColors.Teal),
            ) {
                Icon(Icons.Filled.NotificationsActive, contentDescription = null, tint = DbbColors.Teal, modifier = Modifier.size(15.dp))
                Spacer(Modifier.width(4.dp))
                Text("加雷达", color = DbbColors.TealDark, fontWeight = FontWeight.SemiBold, fontSize = 13.sp)
            }
            OutlinedButton(
                onClick = onOpenArena,
                modifier = Modifier.weight(1f).height(44.dp),
                shape = RoundedCornerShape(12.dp),
                border = BorderStroke(1.5.dp, DbbColors.Sky),
            ) {
                Icon(Icons.Filled.Balance, contentDescription = null, tint = DbbColors.Sky, modifier = Modifier.size(15.dp))
                Spacer(Modifier.width(4.dp))
                Text("跨平台比", color = DbbColors.Sky, fontWeight = FontWeight.SemiBold, fontSize = 13.sp)
            }
        }
    }
}

// ============== 5) 同类好物推荐 ==============

@Composable
private fun SimilarHeader(category: String) {
    Row(
        Modifier.fillMaxWidth().padding(horizontal = 14.dp, vertical = 10.dp),
        verticalAlignment = Alignment.Bottom,
    ) {
        Text("🔁", fontSize = 16.sp)
        Spacer(Modifier.width(6.dp))
        Text(
            "同品类「$category」其他好物",
            fontWeight = FontWeight.ExtraBold, color = DbbColors.Ink, fontSize = 15.sp,
        )
    }
}

@Composable
private fun SimilarRow(item: DiscoverItem, onClick: () -> Unit) {
    Card(
        Modifier
            .fillMaxWidth()
            .padding(horizontal = 14.dp)
            .clickable(onClick = onClick),
        colors = CardDefaults.cardColors(containerColor = DbbColors.Card),
        elevation = CardDefaults.cardElevation(1.dp),
        shape = RoundedCornerShape(12.dp),
    ) {
        Row(
            Modifier.padding(horizontal = 12.dp, vertical = 11.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Box(
                Modifier
                    .size(42.dp)
                    .clip(RoundedCornerShape(10.dp))
                    .background(item.category.tintBg),
                contentAlignment = Alignment.Center,
            ) {
                Text(item.emoji, fontSize = 22.sp)
            }
            Spacer(Modifier.width(11.dp))
            Column(Modifier.weight(1f)) {
                Text(
                    item.title,
                    fontWeight = FontWeight.Medium, color = DbbColors.Ink, fontSize = 13.sp,
                    maxLines = 1,
                )
                Spacer(Modifier.height(2.dp))
                Text(
                    "${item.minPlatform} ¥${fmtYuan(item.minPrice)} · 全网最低",
                    color = DbbColors.InkSec, fontSize = 11.sp,
                )
            }
            Text("›", color = DbbColors.InkTer, fontSize = 18.sp)
        }
    }
}

@Composable
private fun DisclaimerFooter() {
    Spacer(Modifier.height(18.dp))
    Text(
        "价格为各平台日常到手价估算(不含大促),仅供参考,以平台实际为准。",
        color = DbbColors.InkTer, fontSize = 10.sp,
        modifier = Modifier.fillMaxWidth().padding(horizontal = 18.dp),
    )
}

@Composable
private fun NotFoundView(onBack: () -> Unit, modifier: Modifier = Modifier) {
    Column(
        modifier.fillMaxSize().padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
    ) {
        Text("商品不存在或已下架", color = DbbColors.InkSec, fontSize = 14.sp)
        Spacer(Modifier.height(16.dp))
        Button(
            onClick = onBack,
            colors = ButtonDefaults.buttonColors(containerColor = DbbColors.Teal),
        ) { Text("返回") }
    }
}

/** 颜色线性混合 — 用于 hero 渐变端点(类目色 → 偏深 ink 色)。 */
private fun blend(a: Color, b: Color, t: Float): Color {
    val k = t.coerceIn(0f, 1f)
    return Color(
        red = a.red * (1 - k) + b.red * k,
        green = a.green * (1 - k) + b.green * k,
        blue = a.blue * (1 - k) + b.blue * k,
        alpha = a.alpha * (1 - k) + b.alpha * k,
    )
}
