package com.pixelized.biblib.ui.composable

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import com.google.accompanist.systemuicontroller.SystemUiController
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.pixelized.biblib.utils.extention.navigationBarsHeight
import com.pixelized.biblib.utils.extention.statusBarsHeight

val LocalStatusTheme = staticCompositionLocalOf<StatusThemeController> {
    error("LocalStatusTheme is not ready yet.")
}

class StatusThemeController(
    private val systemController: SystemUiController,
    private val statusBackground: MutableState<Brush>,
    private var statusDarkIcons: Boolean,
    private val navigationBackground: MutableState<Brush>,
    private var navigationDarkIcons: Boolean,
) {
    init {
        systemController.setStatusBarColor(
            color = Color.Transparent,
            darkIcons = statusDarkIcons,
        )
        systemController.setNavigationBarColor(
            color = Color.Transparent,
            darkIcons = navigationDarkIcons,
            navigationBarContrastEnforced = false,
        )
    }

    fun updateStatusTheme(
        statusBackground: Brush = this.statusBackground.value,
        statusDarkIcons: Boolean = this.statusDarkIcons,
        navigationBackground: Brush = this.navigationBackground.value,
        navigationDarkIcons: Boolean = this.navigationDarkIcons,
    ) {
        if (this.statusDarkIcons != statusDarkIcons) {
            this.statusDarkIcons = statusDarkIcons
            systemController.setStatusBarColor(
                color = Color.Transparent,
                darkIcons = statusDarkIcons,
            )
        }
        if (this.statusBackground.value != statusBackground) {
            this.statusBackground.value = statusBackground
        }
        if (navigationDarkIcons != this.navigationDarkIcons) {
            this.navigationDarkIcons = navigationDarkIcons
            systemController.setNavigationBarColor(
                color = Color.Transparent,
                darkIcons = navigationDarkIcons,
                navigationBarContrastEnforced = false,
            )
        }
        if (this.navigationBackground.value != navigationBackground) {
            this.statusBackground.value = navigationBackground
        }
    }
}

@Composable
fun SystemTheme(
    systemController: SystemUiController = rememberSystemUiController(),
    statusBackground: Color,
    statusDarkIcons: Boolean,
    navigationBackground: Color,
    navigationDarkIcons: Boolean,
    content: @Composable () -> Unit,
) {
    val statusBackgroundState = remember {
        mutableStateOf(
            Brush.verticalGradient(
                colors = listOf(statusBackground, Color.Transparent)
            )
        )
    }
    val navigationBackgroundState = remember {
        mutableStateOf(
            Brush.verticalGradient(
                colors = listOf(Color.Transparent, navigationBackground)
            )
        )
    }
    val statusController = remember(systemController) {
        StatusThemeController(
            systemController = systemController,
            statusBackground = statusBackgroundState,
            statusDarkIcons = statusDarkIcons,
            navigationBackground = navigationBackgroundState,
            navigationDarkIcons = navigationDarkIcons,
        )
    }
    CompositionLocalProvider(
        LocalStatusTheme provides statusController,
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
        ) {
            content()

            Overlay(
                height = statusBarsHeight(),
                brush = statusBackgroundState,
            )

            Overlay(
                modifier = Modifier.align(Alignment.BottomStart),
                height = navigationBarsHeight(),
                brush = navigationBackgroundState,
            )
        }
    }
}

@Composable
private fun Overlay(
    modifier: Modifier = Modifier,
    height: Dp,
    brush: State<Brush>,
) {
    Box(
        modifier = modifier
            .height(height = height)
            .fillMaxWidth()
            .background(brush = brush.value)
    )
}