package com.dowstats.data.entities.addon

import com.dowstats.data.dto.controllers.AffectedDataDto
import com.dowstats.data.dto.controllers.EntityCompressDtoObject.compressDto
import com.dowstats.data.dto.controllers.RequirementDto
import com.dowstats.data.dto.controllers.SergeantUnitShortDtoObject.toShortDtoSet
import com.dowstats.data.dto.controllers.WeaponUnitShortDtoObject.toShortDtoSet
import com.dowstats.data.dto.controllers.building.BuildingAddonDto
import com.dowstats.data.dto.controllers.building.BuildingAddonShortDto
import com.dowstats.data.entities.building.Building
import com.dowstats.data.entities.unit.DowUnit
import com.dowstats.data.entities.sergant.Sergeant
import com.dowstats.data.entities.weapon.Weapon
import com.fasterxml.jackson.annotation.JsonIgnore
import jakarta.persistence.*


@Entity
@Table(name = "building_addons")
class BuildingAddon {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @ManyToOne
    @JoinColumn(name = "building_id", nullable = false)
    @JsonIgnore
    var building: Building? = null

    var name: String? = null
    var description: String? = null
    var filename: String? = null
    var addonCostRequisition: Double? = null
    var addonCostPower: Double? = null
    var addonCostPopulation: Double? = null
    var addonCostFaith: Double? = null
    var addonCostSouls: Double? = null
    var addonCostTime: Double? = null

    @OneToMany(mappedBy = "addon", cascade = [CascadeType.ALL])
    var addonModifiers: MutableSet<AddonModifiers> = mutableSetOf()

    @OneToMany(mappedBy = "addon", cascade = [CascadeType.ALL])
    var addonRequirements: MutableSet<AddonRequirements>? = null

    @ManyToMany
    @JoinTable(name = "addon_affected_units",
        joinColumns = [JoinColumn(name = "addon_id")],
        inverseJoinColumns = [JoinColumn(name = "unit_id")])
    var affectedUnits: MutableSet<DowUnit> = mutableSetOf()

    @ManyToMany
    @JoinTable(name = "addon_affected_sergeants",
        joinColumns = [JoinColumn(name = "addon_id")],
        inverseJoinColumns = [JoinColumn(name = "sergeant_id")])
    var affectedSergeants: MutableSet<Sergeant> = mutableSetOf()

    @ManyToMany
    @JoinTable(name = "addon_affected_buildings",
        joinColumns = [JoinColumn(name = "addon_id")],
        inverseJoinColumns = [JoinColumn(name = "building_id")])
    var affectedBuildings: MutableSet<Building> = mutableSetOf()

    @ManyToMany
    @JoinTable(name = "addon_affected_weapons",
        joinColumns = [JoinColumn(name = "addon_id")],
        inverseJoinColumns = [JoinColumn(name = "weapon_id")])
    var affectedWeapons: MutableSet<Weapon> = mutableSetOf()

    var uiIndexHint: Int = 0
    var uiHotkeyName: String? = null
    var icon: String? = null
    var modId: Long? = null

    fun toDto(addonRequirementDto: RequirementDto?): BuildingAddonDto = BuildingAddonDto(
        id = id,
        name = name,
        description = description,
        filename = filename,
        addonCostRequisition = addonCostRequisition,
        addonCostPower = addonCostPower,
        addonCostPopulation = addonCostPopulation,
        addonCostFaith = addonCostFaith,
        addonCostSouls = addonCostSouls,
        addonCostTime = addonCostTime,
        addonModifiers = addonModifiers?.sortedBy { it.reference }?.map { it.toDto() }?.toSet() ?: emptySet(),
        affectedData = AffectedDataDto(
            affectedUnits.map { it.compressDto() }.toSet(),
            affectedSergeants.toShortDtoSet(),
            affectedBuildings.map { it.compressDto() }.toSet(),
            affectedWeapons.toShortDtoSet(),
        ),
        addonRequirement = addonRequirementDto,
        icon = icon,
        hotkey = uiHotkeyName

    )

    fun toShortDto(): BuildingAddonShortDto = BuildingAddonShortDto(
        id = id,
        buildingId = building?.id,
        name = name,
        icon = icon
    )

}
