package com.dowstats.service.w40k

import com.dowstats.data.entities.ArmorType
import com.dowstats.data.entities.Mod
import com.dowstats.data.entities.ability.Ability
import com.dowstats.data.entities.ability.AbilityEnvironment
import com.dowstats.data.rgd.RgdData
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class AbilityEnvironmentRgdExtractService @Autowired constructor(
    private val commonParseRgdService: CommonParseRgdService,
    private val deathExplosionRgdExtractService: DeathExplosionRgdExtractService,
) {

    val log = LoggerFactory.getLogger(AbilityEnvironmentRgdExtractService::class.java)

    fun extractToAbilityEnvironmentEntity(
        fileName: String,
        abilityEnvironmentData: List<RgdData>,
        mod: Mod,
        modFolderData: String,
        abilities: Set<Ability>,
        armorTypes: Set<ArmorType>,
        modDictionary: Map<Int, String>
    ): AbilityEnvironment? {

        val abilityEnvironment = AbilityEnvironment()
        abilityEnvironment.filename = fileName
        abilityEnvironment.modId = mod.id

        val uiInfo = abilityEnvironmentData.getRgdTableByName("ui_ext")?.getRgdTableByName("ui_info")
        val uiData = uiInfo?.let {
            commonParseRgdService.getUiInfo(
                uiInfo,
                modDictionary,
                modFolderData,
                mod,
                log,
            )
        }

        abilityEnvironment.name = uiData?.name
        abilityEnvironment.description = uiData?.description
        abilityEnvironment.icon = uiData?.iconPath

        val healthExt = abilityEnvironmentData.getRgdTableByName("health_ext")
        abilityEnvironment.health = healthExt?.getDoubleByName("hitpoints")?.toInt()
        abilityEnvironment.armour = healthExt?.getDoubleByName("armour")?.minus(100)
        abilityEnvironment.healthRegeneration = healthExt?.getDoubleByName("regeneration_rate")

        abilityEnvironment.moveSpeed = getSpeed(abilityEnvironmentData)
        abilityEnvironment.sightRadius = getSightRadius(abilityEnvironmentData)
        abilityEnvironment.detectRadius = getDetectRadius(abilityEnvironmentData)

        abilityEnvironment.lifetime = getLifetime(abilityEnvironmentData)

        abilityEnvironment.armorType = commonParseRgdService.getArmorType(abilityEnvironmentData, armorTypes, "type_armour")
        abilityEnvironment.armorType2 = commonParseRgdService.getArmorType(abilityEnvironmentData, armorTypes, "type_armour_2")

        abilityEnvironment.abilities.addAll(commonParseRgdService.getAbilities(abilityEnvironmentData, abilities).toMutableSet())
        abilityEnvironment.deathExplosions.addAll(deathExplosionRgdExtractService.getDeathExplosions(abilityEnvironmentData, armorTypes).toMutableSet())

        return abilityEnvironment
    }

    private fun getSpeed(abilityEnvironmentData: List<RgdData>): Int? = abilityEnvironmentData
        .getRgdTableByName("moving_ext")
        ?.getDoubleByName("speed_max")
        ?.toInt()

    private fun getSightRadius(abilityEnvironmentData: List<RgdData>): Int? = abilityEnvironmentData
        .getRgdTableByName("sight_ext")
        ?.getDoubleByName("sight_radius")
        ?.toInt()

    private fun getDetectRadius(abilityEnvironmentData: List<RgdData>): Int? = abilityEnvironmentData
        .getRgdTableByName("sight_ext")
        ?.getDoubleByName("keen_sight_radius")
        ?.toInt()

    private fun getLifetime(abilityEnvironmentData: List<RgdData>): Double? = abilityEnvironmentData
        .getRgdTableByName("suicide_ext")
        ?.getDoubleByName("lifetime")

}
