import { world } from "mojang-minecraft"
import { ActionFormData, ModalFormData } from "mojang-minecraft-ui"

const pylonNotExist = messageMenu("Target pylon does not exist!")
const notPowered = messageMenu("This pylon is not powered!")
const invalidName = messageMenu("Invalid name!")

function messageMenu(bodyText) {
    return new ActionFormData()
        .title("§l[!]")
        .body(bodyText)
        .button("Ok")
}

function setPylonData(player, tag, newData) {
    player.removeTag(tag)
    player.addTag(`bmePylonData;${JSON.stringify(newData)}`)
}

function newPylon(player, block, tag, data) {
    let posStr = `${block.x} ${block.y} ${block.z}`
    data[posStr] = `Pylon at ${posStr}`
    setPylonData(player, tag, data)
}

function pylonSetName(player, tag, data, block) {
    let posStr = `${block.x} ${block.y} ${block.z}`
    new ModalFormData()
        .title(`Pylon - ${data[posStr]}`)
        .textField("Set Pylon Name", "", data[posStr])
        .show(player).then((response) => {
            let r = response.formValues[0]
            if (r) {
                data[posStr] = r
                setPylonData(player, tag, data)
            } else {
                invalidName.show(player)
            }
        })
}

function pylonInteract(player, block) {
    let posStr = `${block.x} ${block.y} ${block.z}`
    for (const tag of player.getTags()) {
        if (tag.startsWith("bmePylonData;")) {
            let data = JSON.parse(tag.split(";")[1])
            if (!data[posStr]) {
                newPylon(player, block, tag, data)
                pylonInteract(player, block)
                return
            }


            let menu = [new ActionFormData().title(`Pylon - ${data[posStr]}`).button("Change name"), []]

            for (const [position, name] of Object.entries(data)) {
                if (position != posStr) {
                    menu[0].button(name)
                    menu[1].push(position)
                }
            }

            menu[0].show(player).then((response) => {
                if (!response.isCanceled) {
                    if (response.selection == 0) {
                        pylonSetName(player, tag, data, block)
                    } else if (block.id == "bme:pylon_powered") {
                        let targetPos = menu[1][response.selection - 1]

                        try {
                            player.runCommand(`execute @s ~~~ detect ${targetPos} bme:pylon_powered 0 tag @s add bme:pylonExists`)
                        } catch {
                            try { player.runCommand(`execute @s ~~~ detect ${targetPos} bme:pylon_unpowered 0 tag @s add bme:pylonExists`) } catch { }
                        }

                        if (player.hasTag("bme:pylonExists")) {
                            player.removeTag("bme:pylonExists")
                            player.runCommand(`setblock ${posStr} bme:pylon_unpowered`)
                            player.runCommand(`tp @s ${targetPos}`)
                        } else {
                            delete data[menu[1][response.selection - 1]]
                            setPylonData(player, tag, data)
                            pylonNotExist.show(player)
                        }
                    } else {
                        notPowered.show(player)
                    }
                }
            })

            return
        }
    }

    // not using newPylon here because that assumes that pylonData already exists, since this only runs if this is the first pylon the player does not have that tag
    let pylonData = {}
    pylonData[posStr] = `Pylon at ${posStr}`
    player.addTag(`bmePylonData;${JSON.stringify(pylonData)}`)
    //pylonInteract(player, block)
}

function pylonSneakInteract(player, block) {
    for (const tag of player.getTags()) {
        if (tag.startsWith("bmePylonData;")) {
            let data = JSON.parse(tag.split(";")[1])
            let posStr = `${block.x} ${block.y} ${block.z}`
            delete data[posStr]
            setPylonData(player, tag, data)
            player.runCommand(`setblock ${posStr} air`)
            player.runCommand(`give @s bme:pylon_unpowered`)
        }
    }
}

world.events.entityHit.subscribe((event) => {
    if (event.entity.id == "minecraft:player" && event.hitBlock && (event.hitBlock.id == "bme:pylon_unpowered" || event.hitBlock.id == "bme:pylon_powered")) {
        if (event.entity.isSneaking) {
            pylonSneakInteract(event.entity, event.hitBlock)
        } else {
            pylonInteract(event.entity, event.hitBlock)
        }
    }
})