package com.laseroptek.raman.utils.ext

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.SnapshotStateList
import kotlinx.coroutines.flow.MutableStateFlow
import timber.log.Timber


fun <T> List<T>.convertListToMutableStateListBasedOnBoolean(
    condition: Boolean
): SnapshotStateList<T> {
    return derivedStateOf {
        Timber.d("condition: ${condition}")
        if (condition) {
            mutableStateListOf<T>().also { mutableStateListOf ->
                mutableStateListOf.addAll(this)
            }
        } else {
            mutableStateListOf()
        }
    }.value
}

fun <T> List<T>.convertListToMutableStateList(
): SnapshotStateList<T> {
    return derivedStateOf {
        mutableStateListOf<T>().also { mutableStateListOf ->
            mutableStateListOf.addAll(this)
        }
    }.value
}

/* toMutableStateMap
val originalMap = mapOf(
        Pair(1.0f, 2) to 10,
        Pair(3.0f, 4) to 20
    )

    val convertedMap = originalMap.toMutableStateMap()

    // Modifying the convertedMap
    convertedMap[Pair(1.0f, 2)] = mutableStateOf(15)
    convertedMap[Pair(5.0f, 6)] = mutableStateOf(25) // Adding a new entry

    println(convertedMap)
    // Output: {Pair(1.0, 2)=MutableState(value=15), Pair(3.0, 4)=MutableState(value=20), Pair(5.0, 6)=MutableState(value=25)}
*/

/*
fun <K1, K2, V> Map<Pair<K1, K2>, V>.toMutableStateMap(): MutableMap<Pair<K1, K2>, MutableStateFlow<V>> {
    return this.mapValues { (_, value) -> MutableStateFlow(value) }.toMutableMap()
}
*/

fun List<Float>.toMutableStateFlow(): MutableStateFlow<List<Float>> {
    return MutableStateFlow(this)
}

fun <K1, K2, V> Map<Pair<K1, K2>, V>.getKey2ListForKey1(key1: K1): List<K2> {
    return this.filterKeys { it.first == key1 }.keys.map { it.second }
}

fun <K1, K2, V> Map<Pair<K1, K2>, V>.toFluenceMutableStateFlowMap(): MutableStateFlow<MutableMap<Pair<K1, K2>, V>> {
    val mutableMap = this.mapValues { (_, value) -> value }.toMutableMap()
    return MutableStateFlow(mutableMap)
}

fun <K1, K2, V> Map<Pair<K1, K2>, V>.toVoltageMutableStateFlowMap(): MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>> {
    val mutableMap = this.mapValues { (_, value) -> MutableStateFlow(value) }.toMutableMap()
    return MutableStateFlow(mutableMap)
}

fun <K1, K2, V> Map<Pair<K1, K2>, V>.getValue(key1: K1, key2: K2): V? {
    return this[Pair(key1, key2)]
}

fun <K1, K2, V> MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>>.toRegularMap(): Map<Pair<K1, K2>, V> {
    return this.value.mapValues { (_, valueFlow) -> valueFlow.value }
}

fun <K1, K2, V> MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>>.setVoltageTable(
    key: Pair<K1, K2>,
    newValue: V
) {
    val currentMap = this.value.toMutableMap() // Create a mutable copy
    currentMap[key] = MutableStateFlow(newValue) // Update the value for the key
    this.value = currentMap // Update the StateFlow with the modified map
}

fun <K1, K2, V> MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>>.getValueFromVoltageTable(
    key: Pair<K1, K2>
): V? {
    return this.value[key]?.value
}

fun <K1, K2, V> MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>>.increaseVoltageTableValue(
    key: Pair<K1, K2>,
    increment: V
) where V : Number {
    val currentMap = this.value.toMutableMap()
    val currentValue = currentMap[key]?.value?.toDouble() ?: 0.0 // Get current value or 0 if null
    @Suppress("UNCHECKED_CAST")
    val newValue = (currentValue + increment.toDouble()).let {
        when (increment) {
            is Int -> it.toInt()
            is Float -> it.toFloat()
            is Double -> it
            else -> throw IllegalArgumentException("Unsupported number type: ${increment::class.simpleName}")
        }
    } as V // Add increment and cast back to original type

    currentMap[key] = MutableStateFlow(newValue)
    this.value = currentMap
}

fun <K1, K2, V> MutableStateFlow<MutableMap<Pair<K1, K2>, MutableStateFlow<V>>>.decreaseVoltageTableValue(
    key: Pair<K1, K2>,
    increment: V
) where V : Number {
    val currentMap = this.value.toMutableMap()
    val currentValue = currentMap[key]?.value?.toDouble() ?: 0.0 // Get current value or 0 if null
    @Suppress("UNCHECKED_CAST")
    val newValue = (currentValue - increment.toDouble()).let {
        when (increment) {
            is Int -> it.toInt()
            is Float -> it.toFloat()
            is Double -> it
            else -> throw IllegalArgumentException("Unsupported number type: ${increment::class.simpleName}")
        }
    } as V // Add increment and cast back to original type

    currentMap[key] = MutableStateFlow(newValue)
    this.value = currentMap
}

/* getMutableState
val myMap = mutableMapOf<Pair<Float, Float>, MutableState<Int>>()
myMap[Pair(1.0f, 2.0f)] = mutableStateOf(10)

val mutableState = getMutableState(myMap, 1.0f, 2.0f)

if (mutableState != null) {
    println(mutableState.value) // Output: 10
    mutableState.value = 15
    println(mutableState.value) // Output: 15
} else {
    println("Key not found in the map")
}
*/
fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableState<V>>.getMutableState(k1: K1, k2: K2): MutableState<V>? {
    return this[Pair(k1, k2)]
}

/* getCMemberListWithAValue
val myMap = mutableMapOf<Pair<String, Int>, MutableState<Float>>()
myMap[Pair("apple", 1)] = mutableStateOf(1.0f)
myMap[Pair("apple", 2)] = mutableStateOf(2.0f)
myMap[Pair("banana", 1)] = mutableStateOf(3.0f)

val appleStates = myMap.getCMemberListWithAValue("apple")

// appleStates now contains: [MutableState(value=1.0), MutableState(value=2.0)]
*/
fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableState<V>>.getCMemberListWithAValue(k1: K1): List<MutableState<V>> {
    return this.filter { (key, _) -> key.first == k1 }
        .map { (_, value) -> value }
}


/*
val originalMap = mutableMapOf<Pair<Float, Float>, MutableState<Int>>()
originalMap[Pair(1.0f, 2.0f)] = mutableStateOf(10)
originalMap[Pair(3.0f, 4.0f)] = mutableStateOf(20)

val convertedMap = originalMap.toMutableIntMap()

// convertedMap is now a MutableMap<Pair<Float, Float>, Int>
println(convertedMap) // Output: {Pair(1.0, 2.0)=10, Pair(3.0, 4.0)=20}
*/
fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableState<V>>.toMutableIntMap(): MutableMap<Pair<K1, K2>, V> {
    return this.mapValues { it.value.value }.toMutableMap()
}



/* deepCopy()
val originalMap = mutableMapOf<Pair<Float, Float>, MutableState<Int>>()
originalMap[Pair(1.0f, 2.0f)] = mutableStateOf(10)
originalMap[Pair(3.0f, 4.0f)] = mutableStateOf(20)

val clonedMap = originalMap.deepCopy()

// Modify the original map
originalMap[Pair(1.0f, 2.0f)]?.value = 15

// The cloned map remains unchanged
println(clonedMap[Pair(1.0f, 2.0f)]?.value) // Output: 10
println(originalMap[Pair(1.0f, 2.0f)]?.value) // Output: 15
*/
fun <K, V> MutableMap<K, MutableState<V>>.deepCopy(): MutableMap<K, MutableState<V>> {
    val newMap = mutableMapOf<K, MutableState<V>>()
    for ((key, value) in this) {
        newMap[key] = mutableStateOf(value.value)
    }
    return newMap
}


fun <K1, K2, V> Map<Pair<K1, K2>, V>.toVoltageMutableMap(): MutableMap<Pair<K1, K2>, MutableStateFlow<V>> {
    return this.mapValues { (_, value) -> MutableStateFlow(value) }.toMutableMap()
}


fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableStateFlow<V>>.setVoltageTable(
    key: Pair<K1, K2>,
    newValue: V
) {
    this[key]?.value = newValue // Update the value for the key
}

fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableStateFlow<V>>.getValueFromVoltageTable(
    key: Pair<K1, K2>
): V? {
    return this[key]?.value
}

fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableStateFlow<V>>.setVoltageTableValue(
    key: Pair<K1, K2>,
    value: V
) where V : Number {
    this[key]?.value = value
}

fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableStateFlow<V>>.increaseVoltageTableValue(
    key: Pair<K1, K2>,
    increment: V
) where V : Number {
    val currentValue = this[key]?.value?.toDouble() ?: 0.0 // Get current value or 0 if null
    @Suppress("UNCHECKED_CAST")
    val newValue = (currentValue + increment.toDouble()).let {
        when (increment) {
            is Int -> it.toInt()
            is Float -> it.toFloat()
            is Double -> it
            else -> throw IllegalArgumentException("Unsupported number type: ${increment::class.simpleName}")
        }
    } as V // Add increment and cast back to original type

    this[key]?.value = newValue
}

fun <K1, K2, V> MutableMap<Pair<K1, K2>, MutableStateFlow<V>>.decreaseVoltageTableValue(
    key: Pair<K1, K2>,
    decrement: V
) where V : Number {
    val currentValue = this[key]?.value?.toDouble() ?: 0.0 // Get current value or 0 if null
    @Suppress("UNCHECKED_CAST")
    val newValue = (currentValue - decrement.toDouble()).let {
        when (decrement) { // Use "decrement" here as well
            is Int -> it.toInt()
            is Float -> it.toFloat()
            is Double -> it
            else -> throw IllegalArgumentException("Unsupported number type: ${decrement::class.simpleName}") // And here
        }
    } as V // Cast back to original type

    this[key]?.value = newValue // Update the MutableStateFlow's value
}
