package com.pixelized.desktop.lwa.ui.composable.character.characteristic

import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio.Characteristic
import com.pixelized.desktop.lwa.ui.composable.checkbox.createLwaCheckBox
import com.pixelized.desktop.lwa.ui.composable.checkbox.createLwaCheckBoxFlow
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character__inventory__add_to_purse__title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
import org.jetbrains.compose.resources.getString

class CharacterSheetCharacteristicDialogFactory(
    private val characterSheetRepository: CharacterSheetRepository,
    private val alterationRepository: AlterationRepository,
    private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
) {
    private val decimalChecker = Regex("""^\s*\d*\s*${'$'}""")

    suspend fun convertToDialogUio(
        scope: CoroutineScope,
        characterSheetId: String?,
        characteristic: Characteristic,
        signFlow: StateFlow<Boolean>,
    ): CharacterSheetCharacteristicDialogUio? {

        if (characterSheetId == null) return null

        val characterSheet: CharacterSheet? = characterSheetRepository.characterDetail(
            characterSheetId = characterSheetId,
        )

        if (characterSheet == null) return null

        val alterations: Map<String, List<FieldAlteration>> =
            alterationRepository.activeFieldAlterations(
                characterSheetId = characterSheetId,
            )
        val alteredCharacterSheet = alteredCharacterSheetFactory.sheet(
            characterSheet = characterSheet,
            alterations = alterations,
        )

        return when (characteristic) {
            Characteristic.Damage -> {
                val valueFlow = createLwaTextFieldFlow(
                    label = null,
                )
                val armor = if (alteredCharacterSheet.armor > 0) {
                    createLwaCheckBoxFlow(
                        checked = true,
                    )
                } else {
                    null
                }
                CharacterSheetCharacteristicDialogUio(
                    characterSheetId = characterSheetId,
                    characteristic = characteristic,
                    label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point).let {
                        "$it : ${alteredCharacterSheet.maxHp - alteredCharacterSheet.damage}/${alteredCharacterSheet.maxHp}"
                    },
                    add = signFlow,
                    value = valueFlow.createLwaTextField {
                        valueFlow.errorFlow.value = check(it)
                        valueFlow.valueFlow.value = it
                    },
                    enableArmor = armor?.createLwaCheckBox(),
                    enableConfirm = valueFlow.errorFlow.map { it.not() }.stateIn(
                        scope = scope,
                        started = SharingStarted.Lazily,
                        initialValue = valueFlow.errorFlow.value.not(),
                    ),
                )
            }

            Characteristic.Fatigue -> {
                val valueFlow = createLwaTextFieldFlow(
                    label = null,
                )
                CharacterSheetCharacteristicDialogUio(
                    characterSheetId = characterSheetId,
                    characteristic = characteristic,
                    label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point).let {
                        "$it : ${alteredCharacterSheet.maxPp - alteredCharacterSheet.fatigue}/${alteredCharacterSheet.maxPp}"
                    },
                    add = signFlow,
                    value = valueFlow.createLwaTextField {
                        valueFlow.errorFlow.value = check(it)
                        valueFlow.valueFlow.value = it
                    },
                    enableArmor = null,
                    enableConfirm = valueFlow.errorFlow.map { it.not() }.stateIn(
                        scope = scope,
                        started = SharingStarted.Lazily,
                        initialValue = valueFlow.errorFlow.value.not(),
                    ),
                )
            }
        }
    }

    private fun check(value: String): Boolean = !decimalChecker.matches(value)
}