package wang.yaojia.webterm.designsystem

import android.provider.Settings
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.platform.LocalContext

/**
 * Whether the OS "remove animations" accessibility setting is on. Motion tokens
 * are ALWAYS routed through this (the analogue of iOS `DS.Motion.gated`): when
 * true, callers collapse animations to instant. Provided by [WebTermTheme].
 */
public val LocalReduceMotion: androidx.compose.runtime.ProvidableCompositionLocal<Boolean> =
    staticCompositionLocalOf { false }

/**
 * # WebTermTheme — the app's Material 3 theme (mirrors the iOS `DS` appearance).
 *
 * Dark-appearance-first: the [darkColorScheme] carries the real design intent;
 * the [lightColorScheme] is a faithful light counterpart. The amber-gold accent
 * maps to `primary` (with dark `onPrimary` ink — gold needs dark text). Surface
 * and text colors come from [WebTermColors]. The terminal canvas colors are NOT
 * part of the scheme — they are fixed and read directly from [WebTermColors] by
 * the terminal view, independent of app appearance.
 */
@Composable
public fun WebTermTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit,
) {
    val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
    val reduceMotion = rememberReduceMotion()

    CompositionLocalProvider(LocalReduceMotion provides reduceMotion) {
        MaterialTheme(
            colorScheme = colorScheme,
            typography = WebTermType.ramp,
            content = content,
        )
    }
}

/** Reads the OS animator-duration-scale; 0 means "remove animations" is on. */
@Composable
private fun rememberReduceMotion(): Boolean {
    val context = LocalContext.current
    return remember(context) {
        val scale = Settings.Global.getFloat(
            context.contentResolver,
            Settings.Global.ANIMATOR_DURATION_SCALE,
            1f,
        )
        scale == 0f
    }
}

// The scheme-independent status/accent colors stay in WebTermColors; the scheme
// here only maps surfaces/text/accent into Material 3's slots.
private val DarkColorScheme: ColorScheme = darkColorScheme(
    primary = WebTermColors.dark.accent,
    onPrimary = WebTermColors.onAccent,
    secondary = WebTermColors.dark.accent,
    onSecondary = WebTermColors.onAccent,
    background = WebTermColors.dark.background,
    onBackground = WebTermColors.dark.textPrimary,
    surface = WebTermColors.dark.surface,
    onSurface = WebTermColors.dark.textPrimary,
    surfaceVariant = WebTermColors.dark.card,
    onSurfaceVariant = WebTermColors.dark.textSecondary,
    outline = WebTermColors.dark.hairline,
    error = WebTermColors.statusStuck,
)

private val LightColorScheme: ColorScheme = lightColorScheme(
    primary = WebTermColors.light.accent,
    onPrimary = WebTermColors.onAccent,
    secondary = WebTermColors.light.accent,
    onSecondary = WebTermColors.onAccent,
    background = WebTermColors.light.background,
    onBackground = WebTermColors.light.textPrimary,
    surface = WebTermColors.light.surface,
    onSurface = WebTermColors.light.textPrimary,
    surfaceVariant = WebTermColors.light.card,
    onSurfaceVariant = WebTermColors.light.textSecondary,
    outline = WebTermColors.light.hairline,
    error = WebTermColors.statusStuck,
)
