import { system, world } from "@minecraft/server"
import { ActionFormData } from "@minecraft/server-ui"
import { sendDebugMessage } from "./JMmcUtils"

function spongeData(entity) {
    function waterContent() {
        const property = "lb_ga:water_count"

        function get() {
            return entity.getProperty(property)
        }

        return {
            get: get()
        }
    }

    function attackData() {
        const initial = {
            enemies:[],
            damage:0
        }
        const property = "lb_ga:sponge_attack_data"
        if (!entity.getDynamicPropertyIds().includes(property)) set(initial)

        function get() {
            return JSON.parse(entity.getDynamicProperty(property))
        }

        function set(data) {
            return entity.setDynamicProperty(property,JSON.stringify(data))
        }

        return {
            enemies: {
                enemyCount: get().enemies.length,
                queryId: function(id) {
                    const data = get()
                    if (!data.enemies.includes(id)) {
                        data.enemies.push(id)
                        set(data)
                    }
                    return data.enemies.length
                }
            },
            damageDealt: {
                total: get().damage,
                increment: function(value = 1) {
                    const data = get()
                    data.damage += value
                    data.damage = Math.round(data.damage * 100)/100
                    set(data)
                    return data.damage
                }
            }

        }
    }

    return {
        shots: waterContent(),
        attack: attackData()
    }
}

function spongeForm(sponge) {
    const form = new ActionFormData()
    form.title({translate:"form.sponge.title"})
    const data = spongeData(sponge)
    const shots = data.shots.get
    const bodyText = {
        rawtext: [
            {text:"\n"},
            {
                translate: "form.sponge.body.saturationPercent",
                with: [
                    `${Math.round((shots / 65) * 100)}`
                ]
            },
            {text:"\n"},
            {
                translate: "form.sponge.body.shotCount",
                with: {
                    rawtext: [
                        {
                            text: `${shots}`
                        },
                        {
                            translate: `form.sponge.body.shots.${shots === 1 ? "singular" : "plural"}`
                        }
                    ]
                }
            },
            {text:"\n\n"},
            {
                translate: "form.sponge.body.damageDealt",
                with: [
                    `${data.attack.enemies.enemyCount}`,
                    `${data.attack.damageDealt.total/2}`
                ]
            }
        ]
    }


    form.body(bodyText)
    form.button({translate:"text.button.ok"})
    return form
}

world.beforeEvents.playerInteractWithEntity.subscribe(event => {
    if (event.target.typeId !== "lb_ga:sponge_golem") return
    if (event.player.getComponent("equippable")?.getEquipment("Mainhand")?.typeId === "minecraft:lead") return
    system.run(() => {
        spongeForm(event.target).show(event.player)
    })
})

const eventData = {
    projectileId: 0,
    damagerId: 0
}

world.afterEvents.projectileHitEntity.subscribe(event => {
    if (!event.source || event.source.typeId !== "lb_ga:sponge_golem") return
    // store event data for later
    eventData.projectileId = event.projectile.id
    eventData.damagerId = event.source.id
})

world.afterEvents.entityHurt.subscribe(event => {
    // if this was a projectile hit and the projectile is the same one we just detected in projectileHitEntity,
    // this must be the corresponding damage event
    if (event.damageSource.damagingProjectile && eventData.projectileId === event.damageSource.damagingProjectile.id) {
        const damager = world.getEntity(eventData.damagerId)
        if (!damager) {
            sendDebugMessage(`§4Unable to get damager`)
            return
        }
        const data = spongeData(damager)
        data.attack.damageDealt.increment(event.damage)
        data.attack.enemies.queryId(event.hurtEntity.id)
    }
})