package eu.gaudian.translator.ui.theme

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.luminance

@Immutable
data class SemanticColors(
    val success: Color,
    val onSuccess: Color,
    val successContainer: Color,
    val onSuccessContainer: Color,
    // wrong (error) semantic colors to style destructive/negative actions consistently across themes
    val wrong: Color,
    val onWrong: Color,
    val wrongContainer: Color,
    val onWrongContainer: Color,
    // streak (fire) color used to indicate learning streaks consistently across themes
    val streak: Color,
    val onStreak: Color,
    // A 6-step gradient transitioning from theme primary to onPrimary
    val stageGradient1: Color,
    val stageGradient2: Color,
    val stageGradient3: Color,
    val stageGradient4: Color,
    val stageGradient5: Color,
    val stageGradient6: Color,
)

private val LocalSemanticColors = staticCompositionLocalOf {
    // Reasonable fallbacks; will be overridden by ProvideSemanticColors
    SemanticColors(
        success = Color(0xFF2E7D32),
        onSuccess = Color(0xFF64DD17),
        successContainer = Color(0xFFC8E6C9),
        onSuccessContainer = Color(0xFF1B5E20),
        wrong = Color(0xFFB00020),
        onWrong = Color(0xFFFFFFFF),
        wrongContainer = Color(0xFFFCD8DF),
        onWrongContainer = Color(0xFF370B0E),
        streak = Color(0xFFFF6F00),
        onStreak = Color(0xFF000000),

        stageGradient1 = Color(0xFF2E7D32),
        stageGradient2 = Color(0xFF3FA046),
        stageGradient3 = Color(0xFF51C55B),
        stageGradient4 = Color(0xFF7ADD84),
        stageGradient5 = Color(0xFFA4F5AE),
        stageGradient6 = Color(0xFFFFFFFF),
    )
}

@Suppress("UnusedReceiverParameter")
val MaterialTheme.semanticColors: SemanticColors
    @Composable get() = LocalSemanticColors.current

private fun lerpColor(a: Color, b: Color, t: Float): Color {
    return Color(
        red = a.red + (b.red - a.red) * t,
        green = a.green + (b.green - a.green) * t,
        blue = a.blue + (b.blue - a.blue) * t,
        alpha = a.alpha + (b.alpha - a.alpha) * t
    )
}

@Composable
private fun baseSemanticFromTheme(light: Boolean): SemanticColors {
    val cs = MaterialTheme.colorScheme
    val start = cs.primary
    val mid = cs.secondary
    val end = cs.tertiary
    val steps = listOf(0f, 0.18f, 0.38f, 0.6f, 0.82f, 1f)


    fun triLerpColor(a: Color, b: Color, c: Color, t: Float): Color {
        val x = t.coerceIn(0f, 1f)
        return if (x <= 0.5f) {
            lerpColor(a, b, x / 0.5f)
        } else {
            lerpColor(b, c, (x - 0.5f) / 0.5f)
        }
    }

    val g1 = triLerpColor(start, mid, end, steps[0])
    val g2 = triLerpColor(start, mid, end, steps[1])
    val g3 = triLerpColor(start, mid, end, steps[2])
    val g4 = triLerpColor(start, mid, end, steps[3])
    val g5 = triLerpColor(start, mid, end, steps[4])
    val g6 = triLerpColor(start, mid, end, steps[5])


    return if (light) {
        SemanticColors(
            success = Color(0xFF2F8C33),
            onSuccess = Color(0xFFFFFFFF),
            successContainer = Color(0xFFC8E6C9),
            onSuccessContainer = Color(0xFF1B5E20),
            wrong = Color(0xFFB00020),
            onWrong = Color(0xFFFFFFFF),
            wrongContainer = Color(0xFFFFDAD6),
            onWrongContainer = Color(0xFF410002),
            streak = Color(0xFFFF6F00),
            onStreak = Color(0xFF000000),
            stageGradient1 = g1,
            stageGradient2 = g2,
            stageGradient3 = g3,
            stageGradient4 = g4,
            stageGradient5 = g5,
            stageGradient6 = g6,
        )
    } else {
        SemanticColors(
            success = Color(0xFF81C784),
            onSuccess = Color(0xFF003314),
            successContainer = Color(0xFF1B5E20),
            onSuccessContainer = Color(0xFFC8E6C9),
            wrong = Color(0xFFCF6679),
            onWrong = Color(0xFF370B0E),
            wrongContainer = Color(0xFF93000A),
            onWrongContainer = Color(0xFFFFDAD6),
            streak = Color(0xFFFFAB40),
            onStreak = Color(0xFF1A0C00),
            stageGradient1 = g1,
            stageGradient2 = g2,
            stageGradient3 = g3,
            stageGradient4 = g4,
            stageGradient5 = g5,
            stageGradient6 = g6,
        )
    }
}

@Composable
fun ProvideSemanticColors(content: @Composable () -> Unit) {
    // Provide a green-guaranteed semantic palette. We keep it independent from theme hues
    // but adapt for light vs. dark to ensure accessibility and visual fit.
    val isLight = MaterialTheme.colorScheme.background.luminance() > 0.5f

    val derived = if (isLight) {
        // Light mode greens/reds
        baseSemanticFromTheme(light = true)
    } else {
        // Dark mode greens/reds
        baseSemanticFromTheme(light = false)
    }

    CompositionLocalProvider(LocalSemanticColors provides derived) {
        content()
    }
}