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

import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
import com.pixelized.desktop.lwa.ui.screen.admin.common.tag.GMTagFactory
import com.pixelized.desktop.lwa.ui.screen.admin.common.tag.GMTagUio
import com.pixelized.desktop.lwa.utils.extention.unAccent
import com.pixelized.shared.lwa.model.alteration.Alteration
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
import com.pixelized.shared.lwa.model.tag.Tag
import kotlinx.coroutines.flow.StateFlow

class CharacterSheetAlterationDialogFactory(
    private val tagFactory: GMTagFactory,
) {

    fun filterAlteration(
        alterations: Collection<Alteration>,
        unAccentFilter: String,
        selectedTagId: String?,
    ): List<Alteration> {
        return alterations.filter {
            val matchName = it.metadata.name.unAccent().contains(
                other = unAccentFilter,
                ignoreCase = true
            )
            val matchTag = selectedTagId == null || it.tags.contains(
                element = selectedTagId
            )
            matchName && matchTag
        }
    }

    fun convertToDialogUio(
        characterSheet: CharacterSheet?,
        alterations: List<Alteration>,
        activeAlterations: List<Alteration>,
        tagMap: Map<String, Tag>,
        filter: LwaTextFieldUio,
        tags: StateFlow<List<GMTagUio>>,
        selectedTagId: String?,
    ): CharacterSheetAlterationDialogUio? {
        if (characterSheet == null) return null

        return CharacterSheetAlterationDialogUio(
            characterSheetId = characterSheet.id,
            characterName = characterSheet.name,
            filter = filter,
            tags = tags,
            alterations = alterations.map { alteration ->
                val isActive = activeAlterations.contains(alteration)
                val isPersonal = characterSheet.alterations.contains(alteration.id)
                AlterationToggleItemUio(
                    id = alteration.id,
                    label = alteration.metadata.name,
                    tags = tagFactory.convertToGMTagItemUio(
                        tags = alteration.tags.mapNotNull { tagMap[it] },
                        selectedTagId = selectedTagId
                    ),
                    enable = isPersonal || isActive.not(), // disable alteration coming from equipment
                    active = isActive,
                )
            },
        )
    }
}