package com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon

import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common.CharacterRibbonAlterationUio
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common.CharacterRibbonPortraitUio
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common.CharacterRibbonStats
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common.CharacterRibbonStatsUio
import com.pixelized.desktop.lwa.ui.screen.campaign.player.ribbon.common.CharacterRibbonUio
import com.pixelized.desktop.lwa.utils.extention.foldInto
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
import com.pixelized.shared.lwa.model.alteration.Alteration
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet

private const val DEFAULT_ICON = "https://bg3.wiki/w/images/a/af/Arcana_Icon.png"

class CharacterRibbonFactory(
    private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
) {
    fun convertToPlayerPortraitUio(
        characterSheet: CharacterSheet?,
        alterations: List<Alteration>,
        fieldAlterations: Map<String, List<FieldAlteration>>,
        hideOverruled: Boolean,
        enableCharacterSheet: Boolean,
        enableCharacterStats: Boolean,
        enableCharacterStatus: Boolean,
    ): CharacterRibbonUio? {
        if (characterSheet == null) return null

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

        return CharacterRibbonUio(
            characterSheetId = characterSheet.id,
            hideOverruled = hideOverruled,
            enableDetail = enableCharacterSheet,
            levelUp = alteredCharacterSheet.shouldLevelUp,
            portrait = CharacterRibbonPortraitUio(
                portrait = alteredCharacterSheet.thumbnail,
                name = alteredCharacterSheet.name,
                damagePercent = takeIf { enableCharacterStats }?.let {
                    val maxHp = alteredCharacterSheet.maxHp.toFloat()
                    val damage = alteredCharacterSheet.damage.toFloat()
                    1f - ((maxHp - damage) / maxHp).coerceIn(0f, 1f)
                },
            ),
            status = takeIf { enableCharacterStats }?.let {
                CharacterRibbonStatsUio(
                    hp = alteredCharacterSheet.maxHp - alteredCharacterSheet.damage,
                    maxHp = alteredCharacterSheet.maxHp,
                    pp = alteredCharacterSheet.maxPp - alteredCharacterSheet.fatigue,
                    maxPp = alteredCharacterSheet.maxPp,
                )
            },
            alterations = takeIf { enableCharacterStatus }?.let {
                alterations.map { alteration ->
                    CharacterRibbonAlterationUio(
                        icon = alteration.metadata.icon ?: DEFAULT_ICON,
                        tooltips = BasicTooltipUio(
                            title = alteration.metadata.name,
                            description = alteration.metadata.description,
                        ),
                    )
                }.foldInto(
                    size = 4,
                )
            } ?: emptyList(),
        )
    }
}