package com.performancecoachlab.posedetection.custom

import androidx.compose.runtime.Composable
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.internal.SynchronizedObject
import kotlinx.coroutines.internal.synchronized
import kotlin.concurrent.Volatile

data class ModelPath(
    val androidModelPath: String? = null,
    val iosModelPath: String? = null,
)

@Composable
expect fun initialiseObjectModel(modelPath: ModelPath): ObjectModel

@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
expect class ObjectModel {
}

@Composable
fun rememberObjectModel(modelPath: ModelPath): ObjectModel {
    // Android: cache via provider to avoid recreation
    // iOS: do NOT share/cross-cache the model; create once per composition
    return platformRememberObjectModel(modelPath)
}

@Composable
internal expect fun platformRememberObjectModel(modelPath: ModelPath): ObjectModel

object ObjectModelProvider {
    // Cache keyed by ModelPath so switching models works correctly on Android.
    @Volatile
    private var cache: Map<ModelPath, ObjectModel> = emptyMap()

    // Kotlin/Native requires a SynchronizedObject as the lock
    @OptIn(InternalCoroutinesApi::class)
    private val lock = SynchronizedObject()

    @OptIn(InternalCoroutinesApi::class)
    @Composable
    fun get(modelPath: ModelPath): ObjectModel {
        val fast = cache[modelPath]
        if (fast != null) return fast

        return synchronized(lock) {
            cache[modelPath] ?: initialiseObjectModel(modelPath).also { model ->
                cache = cache + (modelPath to model)
            }
        }
    }

    @OptIn(InternalCoroutinesApi::class)
    fun clear() {
        synchronized(lock) { cache = emptyMap() }
    }
}