package com.dowstats.service.datamaps

import com.dowstats.data.dto.controllers.RequirementDto
import com.dowstats.data.dto.controllers.ability.AbilityDto
import com.dowstats.data.entities.ability.Ability
import com.dowstats.data.entities.ability.AbilityEnvironment
import com.dowstats.data.repositories.AbilityEnvironmentRepository
import com.dowstats.data.repositories.AbilityRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class AbilityService @Autowired constructor(
    val abilityRepository: AbilityRepository,
    val abilityEnvironmentRepository: AbilityEnvironmentRepository,
    val requirementsMappingComponent: RequirementsMappingComponent,
) {

    fun getAbilityDto(id: Long, modId: Long): AbilityDto {
        val ability = abilityRepository.findById(id).get()
        val requirements = requirementsMappingComponent
            .getRequirements(ability.abilityRequirements.toList() ,
                modId)

        val allAbilityEnvironments = abilityEnvironmentRepository.findAllByModId(modId)

        val spawnedAbilityEnvironment: AbilityEnvironment? =
            getSpawnedAbilityEnvironment(allAbilityEnvironments, ability.spawnedEntityName)


        if(ability.childAbilityName == null || ability.childAbilityName == "") return ability.toDto(requirements, null, spawnedAbilityEnvironment?.toDto()) else {

            return toDtoWithChild(requirements, modId,allAbilityEnvironments, ability)
        }
    }

    fun toDtoWithChild(requirements: RequirementDto?,
                       modId: Long,
                       allAbilityEnvironments: List<AbilityEnvironment>,
                       ability: Ability): AbilityDto {

        val spawnedAbilityEnvironment: AbilityEnvironment? =
            getSpawnedAbilityEnvironment(allAbilityEnvironments, ability.spawnedEntityName)
        return if (ability.childAbilityName == null || ability.childAbilityName == "")
            ability.toDto(requirements, null, spawnedAbilityEnvironment?.toDto())
        else {
            val searchChild = ability.childAbilityName?.replace(".lua", "")?.replace("abilities\\", "")!!
            ability.toDto(
                requirements,
                toDtoWithChild(
                    requirements, modId, allAbilityEnvironments,
                    abilityRepository.findFirstByModIdAndFilenameIn(modId, listOf(searchChild, searchChild + ".rgd") )),
                spawnedAbilityEnvironment?.toDto()
            )
        }
    }

    private fun getSpawnedAbilityEnvironment(allAbilityEnvironments: List<AbilityEnvironment>, spawnedEntityName: String?): AbilityEnvironment? {

        val spawnedObject = spawnedEntityName?.split("\\")?.last()
            ?.replace(".lua", "")
            ?.replace(".rgd", "")

        return spawnedObject?.let {
            allAbilityEnvironments.firstOrNull {
                it.filename?.split("\\")?.last()
                    ?.replace(".lua", "")
                    ?.replace(".rgd", "") == spawnedObject
            }
        }
    }

}