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

import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
import com.pixelized.shared.lwa.model.item.Item
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character__inventory__description_empty__label
import lwacharactersheet.composeapp.generated.resources.character__inventory__inventory__dialog__count
import org.jetbrains.compose.resources.getString
import java.text.DecimalFormat

class ItemDetailDialogFactory {

    private val floatChecker = Regex("""^\d*,?\d*${'$'}""")
    private val format = DecimalFormat("#.##")

    suspend fun convertToDialogUio(
        characterSheetId: String?,
        items: Map<String, Item>,
        count: Float,
        equipped: Boolean,
        inventoryId: String?,
        itemId: String?,
    ): ItemDetailDialogUio? {
        if (characterSheetId == null) return null
        val item = itemId.let(items::get) ?: return null

        return ItemDetailDialogUio(
            characterSheetId = characterSheetId,
            inventoryId = inventoryId,
            itemId = item.id,
            label = item.metadata.label,
            description = item.metadata.description.ifBlank {
                getString(Res.string.character__inventory__description_empty__label)
            },
            image = item.metadata.image,
            count = count,
            countable = takeIf { item.options.stackable }
                ?.let {
                    val flow = createLwaTextFieldFlow(
                        label = getString(Res.string.character__inventory__inventory__dialog__count),
                        value = format.format(count),
                    )
                    flow.createLwaTextField {
                        flow.errorFlow.value = isError(inventoryId = inventoryId, value = it)
                        flow.valueFlow.value = it
                    }
                },
            consumable = item.options.consumable,
            equipped = equipped,
            equipable = item.options.equipable,
        )
    }


    fun parse(
        quantity: String,
    ): Float? = try {
        format.parse(quantity).toFloat()
    } catch (_: Exception) {
        null
    }

    private fun isError(
        inventoryId: String?,
        value: String,
    ): Boolean {
        return value.isBlank() || floatChecker.matches(value).not() || (inventoryId == null && value.toFloat() < 1f)
    }
}