package pl.firmatpp.kierowca.ui.theme

import android.app.Activity
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat

object TppColors {
    val Forest = Color(0xFF154212)
    val ContainerGreen = Color(0xFF2D5A27)
    val LogoLeaf = Color(0xFF609830)
    val Navy = Color(0xFF1B365D)
    val Surface = Color(0xFFF7FAF8)
    val Panel = Color(0xFFEBEFED)
    val Ink = Color(0xFF181C1B)
    val Muted = Color(0xFF42493E)
    val Outline = Color(0xFFC2C9BB)
    val Error = Color(0xFFBA1A1A)
}

@Immutable
data class TppColorTokens(
    val forest: Color,
    val containerGreen: Color,
    val logoLeaf: Color,
    val navy: Color,
    val surface: Color,
    val panel: Color,
    val ink: Color,
    val muted: Color,
    val outline: Color,
    val error: Color,
    val card: Color,
    val successContainer: Color,
    val successOutline: Color,
    val warningContainer: Color,
    val warningOutline: Color,
)

object TppTheme {
    val colors: TppColorTokens
        @Composable
        @ReadOnlyComposable
        get() = LocalTppColorTokens.current
}

private val CurrentColorTokens = TppColorTokens(
    forest = TppColors.Forest,
    containerGreen = TppColors.ContainerGreen,
    logoLeaf = TppColors.LogoLeaf,
    navy = TppColors.Navy,
    surface = TppColors.Surface,
    panel = TppColors.Panel,
    ink = TppColors.Ink,
    muted = TppColors.Muted,
    outline = TppColors.Outline,
    error = TppColors.Error,
    card = Color.White,
    successContainer = Color(0xFFEAF7EF),
    successOutline = Color(0xFF9BD1AD),
    warningContainer = Color(0xFFFFF7E6),
    warningOutline = Color(0xFFE6B85C),
)

private val Material3ColorTokens = TppColorTokens(
    forest = Color(0xFF226C2C),
    containerGreen = Color(0xFF2F7D32),
    logoLeaf = Color(0xFF5FA642),
    navy = Color(0xFF225A86),
    surface = Color(0xFFF8FBF6),
    panel = Color(0xFFEAF1E6),
    ink = Color(0xFF172018),
    muted = Color(0xFF566252),
    outline = Color(0xFFBAC8B5),
    error = Color(0xFFBA1A1A),
    card = Color(0xFFFFFFFF),
    successContainer = Color(0xFFDFF4E2),
    successOutline = Color(0xFF8EC69A),
    warningContainer = Color(0xFFFFF1D6),
    warningOutline = Color(0xFFE4B45B),
)

private val LocalTppColorTokens = staticCompositionLocalOf { CurrentColorTokens }

private val CurrentScheme = lightColorScheme(
    primary = TppColors.Forest,
    onPrimary = Color.White,
    primaryContainer = TppColors.ContainerGreen,
    secondary = TppColors.Navy,
    background = TppColors.Surface,
    surface = Color.White,
    surfaceVariant = TppColors.Panel,
    onBackground = TppColors.Ink,
    onSurface = TppColors.Ink,
    onSurfaceVariant = TppColors.Muted,
    outline = TppColors.Outline,
    error = TppColors.Error,
)

private val Material3Scheme = lightColorScheme(
    primary = Material3ColorTokens.forest,
    onPrimary = Color.White,
    primaryContainer = Material3ColorTokens.containerGreen,
    onPrimaryContainer = Color.White,
    secondary = Material3ColorTokens.navy,
    onSecondary = Color.White,
    secondaryContainer = Color(0xFFD2E7F7),
    onSecondaryContainer = Color(0xFF071E30),
    tertiary = Color(0xFF7A5D00),
    onTertiary = Color.White,
    tertiaryContainer = Color(0xFFFFE08A),
    background = Material3ColorTokens.surface,
    onBackground = Material3ColorTokens.ink,
    surface = Material3ColorTokens.surface,
    onSurface = Material3ColorTokens.ink,
    surfaceVariant = Material3ColorTokens.panel,
    onSurfaceVariant = Material3ColorTokens.muted,
    outline = Material3ColorTokens.outline,
    outlineVariant = Color(0xFFD5DED1),
    error = Material3ColorTokens.error,
)

private val CurrentShapes = Shapes(
    extraSmall = androidx.compose.foundation.shape.RoundedCornerShape(2.dp),
    small = androidx.compose.foundation.shape.RoundedCornerShape(4.dp),
    medium = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
    large = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
    extraLarge = androidx.compose.foundation.shape.RoundedCornerShape(12.dp),
)

private val Material3Shapes = Shapes(
    extraSmall = androidx.compose.foundation.shape.RoundedCornerShape(8.dp),
    small = androidx.compose.foundation.shape.RoundedCornerShape(12.dp),
    medium = androidx.compose.foundation.shape.RoundedCornerShape(20.dp),
    large = androidx.compose.foundation.shape.RoundedCornerShape(28.dp),
    extraLarge = androidx.compose.foundation.shape.RoundedCornerShape(32.dp),
)

@Composable
@Suppress("DEPRECATION")
fun TppKierowcaTheme(
    themeMode: AppThemeMode = AppThemeMode.Default,
    content: @Composable () -> Unit,
) {
    val colorTokens = if (themeMode == AppThemeMode.Material3) Material3ColorTokens else CurrentColorTokens
    val colorScheme = if (themeMode == AppThemeMode.Material3) Material3Scheme else CurrentScheme
    val shapes = if (themeMode == AppThemeMode.Material3) Material3Shapes else CurrentShapes
    val view = LocalView.current

    if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as? Activity)?.window ?: return@SideEffect
            window.statusBarColor = colorTokens.surface.toArgb()
            window.navigationBarColor = colorTokens.surface.toArgb()
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = true
            WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = true
        }
    }

    CompositionLocalProvider(LocalTppColorTokens provides colorTokens) {
        MaterialTheme(
            colorScheme = colorScheme,
            shapes = shapes,
            content = content,
        )
    }
}
