package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header

import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import com.pixelized.desktop.lwa.repository.settings.model.Settings
import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.DetailPanelUio
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.combine
import kotlinx.coroutines.flow.stateIn
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__armor
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__damage_bonus
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hit_point
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hp_grow
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__initiative
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__learning
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__movement
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__power_point
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__reflex
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hp_grow
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__initiative
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__learning
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__movement
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__power_point
import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__reflex
import org.jetbrains.compose.resources.getString

class CharacterDetailHeaderFactory(
    private val characterSheetRepository: CharacterSheetRepository,
    private val alterationRepository: AlterationRepository,
    private val settingRepository: SettingsRepository,
    private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
) {
    fun convertToCharacterDetailHeaderUioFlow(
        characterSheetId: String,
        panel: DetailPanelUio,
        scope: CoroutineScope,
        started: SharingStarted = SharingStarted.Eagerly,
        initialValue: () -> CharacterDetailHeaderUio?,
    ): StateFlow<CharacterDetailHeaderUio?> {
        return combine(
            characterSheetRepository.characterDetailFlow(characterSheetId = characterSheetId),
            alterationRepository.activeFieldAlterationsFlow(characterSheetId = characterSheetId),
            settingRepository.settingsFlow()
        ) { characterSheet, alterations, settings ->
            convertToCharacterDetailHeaderUio(
                characterSheetId = characterSheetId,
                panel = panel,
                characterSheet = characterSheet,
                settings = settings,
                alterations = alterations,
            )
        }.stateIn(
            scope = scope,
            started = started,
            initialValue = initialValue(),
        )
    }

    private suspend fun convertToCharacterDetailHeaderUio(
        characterSheetId: String,
        characterSheet: CharacterSheet?,
        panel: DetailPanelUio,
        settings: Settings,
        alterations: Map<String, List<FieldAlteration>>,
    ): CharacterDetailHeaderUio? {
        if (characterSheet == null) return null

        val alteredCharacterSheet = alteredCharacterSheetFactory.sheet(
            characterSheet = characterSheet,
            alterations = alterations,
        )

        val maxHp = alteredCharacterSheet.maxHp
        val maxPp = alteredCharacterSheet.maxPp

        return CharacterDetailHeaderUio(
            characterSheetId = characterSheetId,
            panel = panel,
            portrait = alteredCharacterSheet.portrait,
            diminished = alteredCharacterSheet.diminished,
            alteration = settings.isAdmin ?: false,
            levelUp = alteredCharacterSheet.shouldLevelUp,
            name = alteredCharacterSheet.name,
            level = alteredCharacterSheet.level,
            hp = "${maxHp - alteredCharacterSheet.damage}",
            hpTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__hit_point),
                description = getString(Res.string.tooltip__sub_characteristics__hit_point)
            ),
            maxHp = "$maxHp",
            pp = "${maxPp - alteredCharacterSheet.fatigue}",
            ppTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__power_point),
                description = getString(Res.string.tooltip__sub_characteristics__power_point)
            ),
            maxPp = "$maxPp",
            mov = "${alteredCharacterSheet.movement}",
            movTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__movement),
                description = getString(Res.string.tooltip__sub_characteristics__movement)
            ),
            armor = "${alteredCharacterSheet.armor}",
            armorTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__armor),
                description = getString(Res.string.tooltip__sub_characteristics__armor)
            ),
            bonus = alteredCharacterSheet.damageBonus,
            bonusTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
                description = getString(Res.string.tooltip__sub_characteristics__bonus_damage)
            ),
            grow = "${alteredCharacterSheet.hpGrow}",
            growTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__hp_grow),
                description = getString(Res.string.tooltip__sub_characteristics__hp_grow)
            ),
            learn = "${alteredCharacterSheet.learning}",
            learnTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__learning),
                description = getString(Res.string.tooltip__sub_characteristics__learning)
            ),
            reflex = "${alteredCharacterSheet.reflex}",
            reflexTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__reflex),
                description = getString(Res.string.tooltip__sub_characteristics__reflex)
            ),
            reflexRoll = RollAction.Uio.BoundedRollActionUio(
                characterSheetId = characterSheetId,
                label = getString(Res.string.character_sheet__sub_characteristics__reflex),
                rollAction = "1d100",
                rollSuccessValue = alteredCharacterSheet.reflex * 5,
            ),
            initiative = "${alteredCharacterSheet.initiative}",
            initiativeTooltip = BasicTooltipUio(
                title = getString(Res.string.character_sheet__sub_characteristics__initiative),
                description = getString(Res.string.tooltip__sub_characteristics__initiative)
            ),
        )
    }
}