package com.pixelized.desktop.lwa.repository.characterSheet

import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheetPreview
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn

class CharacterSheetRepository(
    private val store: CharacterSheetStore,
) {
    private val scope = CoroutineScope(Dispatchers.IO + Job())

    fun characterSheetPreviewFlow(): StateFlow<List<CharacterSheetPreview>> {
        return store.previewFlow
    }

    suspend fun updateCharacterPreviews() {
        store.updateCharactersPreviewFlow()
    }

    suspend fun updateCharacterSheet(characterSheetId: String) {
        store.updateCharacterSheetDetailFlow(characterSheetId = characterSheetId)
    }

    fun characterPreview(characterSheetId: String?): CharacterSheetPreview? {
        return store.previewFlow.value.firstOrNull { it.characterSheetId == characterSheetId }
    }

    fun characterDetail(
        characterSheetId: String?,
    ): CharacterSheet? {
        return store.detailFlow.value[characterSheetId]
    }

    fun characterDetailFlow(
        characterSheetId: String?,
    ): StateFlow<CharacterSheet?> {
        return store.detailFlow
            .map { sheets ->
                sheets[characterSheetId]
            }
            .stateIn(
                scope = scope,
                started = SharingStarted.Eagerly,
                initialValue = store.detailFlow.value[characterSheetId],
            )
    }

    @Throws
    suspend fun updateCharacter(
        sheet: CharacterSheet,
        create: Boolean,
    ) {
        store.updateCharacterSheet(sheet = sheet, create = create)
    }

    @Throws
    suspend fun deleteCharacter(
        characterSheetId: String,
    ) {
        store.deleteCharacterSheet(characterSheetId = characterSheetId)
    }

    @Throws
    suspend fun updateAlteration(
        characterSheetId: String,
        alterationId: String,
        active: Boolean,
    ) {
        store.putCharacterAlteration(
            characterSheetId = characterSheetId,
            alterationId = alterationId,
            active = active,
        )
    }

    fun checkCharacterSheetIdValidity(
        characterSheetId: String,
    ): Boolean {
        return store.previewFlow.value.none { it.characterSheetId == characterSheetId }
    }
}