/**
 * global damage limit
 */
const GLOBAL_DAMAGE_LIMIT = {
    min: 0,
    max: 10000
}

/**
 * element weapons
 * [item_id]: [element](wind|heat|ice|energy|element|fire|water|sand|amongus|pink|morbius|invasion)
 */
const ELEMENT_WEAPONS = {
    'lucky:elewind_lucky_sword': ['wind'],
    'lucky:elewind_lucky_bow': ['wind'],
    'lucky:elefire_lucky_sword': ['heat'],
    'lucky:elefire_lucky_bow': ['heat'],
    'lucky:eleice_lucky_sword': ['ice'],
    'lucky:eleice_lucky_bow': ['ice'],
    'lucky:elergy_lucky_sword': ['energy'],
    'lucky:elergy_lucky_bow': ['energy'],
    'lucky:elemental_lucky_sword': ['element'],
    'lucky:elemental_lucky_bow': ['element'],
    'lucky:fire_lucky_sword': ['fire'],
    'lucky:fire_lucky_bow': ['fire'],
    'lucky:desert_lucky_sword': ['sand'],
    'lucky:desert_lucky_bow': ['sand'],
    'lucky:amongus_lucky_sword': ['amongus'],
    'lucky:amongus_lucky_bow': ['amongus'],
    'lucky:pink_lucky_sword': ['pink'],
    'lucky:pink_lucky_bow': ['pink'],
    'lucky:morbius_lucky_sword': ['morbius'],
    'lucky:morbius_lucky_bow': ['morbius'],
    'lucky:lucky_world_invasion_lucky_sword': ['invasion'],
    'yakurum:water_katana': ['water']
}

/**
 * element mobs
 * [entity_id]: [element](wind|heat|ice|energy|element|fire|water|sand|amongus|pink|morbius|invasion)
 */
const ELEMENT_MOBS = {
    'dummmmmmy:target_dummy': ['demo'],
    'twilightforest:naga': ['wind'],
    'twilightforest:lich': ['energy'],
    'twilightforest:alpha_yeti': ['ice'],
    'twilightforest:yeti': ['ice'],
    'twilightforest:snow_queen': ['ice'],
    'twilightforest:minoshroom': ['heat'],
    'twilightforest:hydra': ['fire', 'fix_boss']
}

/**
 * element bouns
 * element: damage multiplier caused by element weapons
 * damage: damage multiplier caused by damage type
 * 0.5 = +50%
 * sum(element) * damage
 */
const ELEMENT_BONUS = {
    demo: {
        element: {
            wind: 0,
            heat: 0,
            ice: 0,
            energy: 0,
            element: 0,
            fire: 0,
            water: 0,
            sand: 0,
            amongus: 0,
            pink: 0,
            morbius: 0,
            invasion: 0
        },
        damage: {
            player: 0,
            mob: 0,
            arrow: 0,
            thrown: 0,
            trident: 0,
            'tacz.bullet': 0,
            magic: 0,
            indirectMagic: 0,
            explosion: 0,
            'explosion.player': 0,
            fireworks: 0,
            'yakurum:fantasia_damage': 0,
            lightningBolt: 0,
            'attributeslib:current_hp_damage': 0,
            'attributeslib:cold_damage': 0,
            freeze: 0,
            'attributeslib:fire_damage': 0,
            inFire: 0,
            lava: 0,
            inWall: 0,
            drown: 0,
            fall: 0
        }
    },
    fix_boss: {
        element: {},
        damage: {
            'tacz.bullet': -1,
            magic: -1,
            indirectMagic: -1,
            explosion: -1,
            'explosion.player': -1
        }
    },
    wind: {
        element: {
            wind: 1,
            energy: 0.1,
            element: 0.2,
            sand: -0.5,
            invasion: 1.0
        },
        damage: {
            arrow: -0.9,
            thrown: -0.9,
            'tacz.bullet': -0.9,
            indirectMagic: -0.8,
            fireworks: 5,
            'yakurum:fantasia_damage': 9,
            'attributeslib:current_hp_damage': -1,
            inWall: -1,
            drown: -1,
            fall: -1
        }
    },
    heat: {
        element: {
            wind: 0.5,
            heat: -0.5,
            ice: 2,
            element: 0.2,
            fire: -1,
            water: 0.9,
            invasion: 1
        },
        damage: {
            explosion: -0.5,
            'explosion.player': -0.5,
            fireworks: -0.2,
            'attributeslib:cold_damage': 1,
            freeze: 2,
            'attributeslib:fire_damage': -1,
            inFire: -1,
            lava: -1
        }
    },
    ice: {
        element: {
            heat: 1,
            element: 0.2,
            fire: 1,
            water: -0.8,
            invasion: 1
        },
        damage: {
            'tacz.bullet': 0.2,
            explosion: 0.6,
            'explosion.player': 0.6,
            fireworks: 0.1,
            'attributeslib:cold_damage': -1,
            freeze: -1,
            'attributeslib:fire_damage': 1,
            inFire: 1,
            lava: 2
        }
    },
    energy: {
        element: {
            element: 0.2,
            water: -1,
            invasion: 1
        },
        damage: {
            trident: 0.3,
            'tacz.bullet': -0.9,
            magic: -0.8,
            indirectMagic: -0.8,
            'yakurum:fantasia_damage': 3,
            lightningBolt: -0.8,
            'attributeslib:current_hp_damage': -0.5
        }
    },
    element: {
        element: {
            wind: 0.2,
            heat: 0.2,
            ice: 0.2,
            energy: 0.2,
            element: 0.2,
            fire: 0.2,
            water: 0.2,
            sand: 0.2,
            amongus: 0.2,
            pink: 0.2,
            morbius: 0.2,
            invasion: 1
        },
        damage: {
            'tacz.bullet': -0.9,
            magic: -1,
            indirectMagic: -1,
            'yakurum:fantasia_damage': -1,
            'attributeslib:current_hp_damage': -0.8
        }
    },
    fire: {
        element: {
            wind: -0.2,
            heat: -1,
            ice: 1,
            element: 0.2,
            fire: -1,
            water: 2,
            sand: 0.4,
            invasion: 1
        },
        damage: {
            'tacz.bullet': -0.9,
            magic: -0.8,
            indirectMagic: -0.8,
            explosion: -0.5,
            'explosion.player': -0.5,
            fireworks: -0.5,
            'attributeslib:current_hp_damage': -1,
            'attributeslib:cold_damage': 1,
            freeze: 2,
            'attributeslib:fire_damage': -1,
            inFire: -1,
            lava: -1,
            drown: 0.2,
            fall: -1
        }
    },
    water: {
        element: {
            heat: -0.2,
            ice: 0.3,
            energy: 1,
            element: 0.2,
            fire: -1,
            sand: 0.8,
            invasion: 1
        },
        damage: {
            arrow: -0.1,
            thrown: -0.1,
            trident: 2,
            'tacz.bullet': -0.9,
            magic: -0.8,
            indirectMagic: -0.8,
            explosion: -0.8,
            'explosion.player': -0.8,
            fireworks: -0.8,
            lightningBolt: 1,
            'attributeslib:current_hp_damage': -1,
            'attributeslib:cold_damage': 0.6,
            freeze: 0.6,
            'attributeslib:fire_damage': -1,
            inFire: -1,
            lava: -1,
            drown: -1
        }
    },
    sand: {
        element: {
            wind: 0.2,
            element: 0.2,
            water: -0.8,
            invasion: 1
        },
        damage: {
            'tacz.bullet': -0.6,
            explosion: 0.5,
            'explosion.player': 0.5,
            inWall: -1,
            drown: 1,
            fall: -0.3
        }
    },
    amongus: {
        element: {
            element: 0.2,
            amongus: 1,
            pink: -0.8,
            morbius: 3,
            invasion: 1
        },
        damage: {}
    },
    pink: {
        element: {
            element: 0.2,
            amongus: 3,
            pink: 1,
            morbius: -0.8,
            invasion: 1
        },
        damage: {}
    },
    morbius: {
        element: {
            element: 0.2,
            amongus: -0.8,
            pink: 3,
            morbius: 1,
            invasion: 1
        },
        damage: {}
    },
    invasion: {
        element: {
            wind: -1,
            heat: -1,
            ice: -1,
            energy: -1,
            element: 0.2,
            fire: -1,
            water: -1,
            sand: -1,
            amongus: -1,
            pink: -1,
            morbius: -1,
            invasion: 10
        },
        damage: {
            'tacz.bullet': 1,
            'attributeslib:current_hp_damage': -1
        }
    }
}



/**
 * LivingHurtEvent
 * 
 * @param {Internal.LivingHurtEvent} event 
 */
global.LivingHurtEvent = event => {
    const { source, entity, amount } = event
    const { player } = source

    const damageType = typeof source.type === 'function' ? source.type() : source.type
    const msgId = typeof damageType.msgId === 'function' ? damageType.msgId() : damageType.msgId

    let fixAmount = amount

    // console.log(source.actual)
    // console.log(msgId)
    if (source.actual && source.actual.isPlayer()) {
        if ('player' == msgId) {
            if ('lucky:lucky_world_invasion_lucky_sword' == player.handSlots[0].getId()) {
                fixAmount = fixAmount + source.actual.block.light
            }
        }
    } else if (source.actual && 'touhou_little_maid:maid' == source.actual.getType()) {
        // console.log(source.actual.getNbt().HandItems[0])
        // console.log(source.actual.getNbt().ArmorItems)
        // console.log(msgId)
        if (source.actual.getNbt().MaidFavorability) {
            fixAmount = fixAmount + fixAmount * source.actual.getNbt().MaidFavorability / 384
        }
    }

    if (ELEMENT_MOBS[entity.getType()]) {
        let totalDamageRate = 0
        let totalDamageCount = 0
        ELEMENT_MOBS[entity.getType()].forEach(ele1 => {
            let damageRate = 1
            if (source.actual) {
                if (source.actual.isPlayer()) {
                    if (typeof ELEMENT_WEAPONS[player.handSlots[0].getId()] == 'object') {
                        ELEMENT_WEAPONS[player.handSlots[0].getId()].forEach(ele2 => {
                            if (typeof ELEMENT_BONUS[ele1].element[ele2] == 'number') {
                                damageRate = damageRate + ELEMENT_BONUS[ele1].element[ele2]
                            }
                        })
                    }
                } else {
                    if (typeof ELEMENT_WEAPONS[source.actual.getNbt()?.HandItems[0].getId()] == 'object') {
                        ELEMENT_WEAPONS[source.actual.getNbt().HandItems[0].getId()].forEach(ele2 => {
                            if (typeof ELEMENT_BONUS[ele1].element[ele2] == 'number') {
                                damageRate = damageRate + ELEMENT_BONUS[ele1].element[ele2]
                            }
                        })
                    }
                }
            }

            if (damageRate >= 1 && typeof ELEMENT_BONUS[ele1].damage[msgId] == 'number') {
                damageRate = damageRate * (1 + ELEMENT_BONUS[ele1].damage[msgId])
            }

            totalDamageRate = totalDamageRate + damageRate
            totalDamageCount++
        })

        fixAmount = fixAmount * totalDamageRate / totalDamageCount
    }

    // console.log(fixAmount)
    if (typeof fixAmount == 'number') {
        event.setAmount(Math.min(GLOBAL_DAMAGE_LIMIT.max, Math.max(GLOBAL_DAMAGE_LIMIT.min, fixAmount.toFixed(2))))
    }
}

EntityEvents.spawned((event) => {
    const { server, entity } = event
    if (!entity || !entity.isLiving() || !entity.isMonster()) {
        return
    }

    // console.log(entity.type)
    if ('minecraft:ender_dragon' == entity.type && 'minecraft:the_end' == entity.level.dimension) {
        let playerList = entity
            .getLevel()
            .getEntitiesWithin(AABB.of(-5, 60, -5, 5, 65, 5))
            .filter((e) => e.isPlayer())
            .filter((p) => global.getPlayerDifficulty(p) > 200)
            .filter((p) => p.getStats().getKilled('ender_dragon') > 0)
            .filter((p) => p.inventory.countItem('kubejs:challenge_badge') > 0)

        if (playerList.length) {
            playerList.sort(
                (a, b) =>
                    b.inventory.countItem('kubejs:challenge_badge') -
                    a.inventory.countItem('kubejs:challenge_badge')
            )
            /**
             * @type {Internal.ServerPlayer}
             */
            let maxBadgePlayer = playerList[0]
            let slotIndex = maxBadgePlayer.inventory.findSlotMatchingItem('kubejs:challenge_badge')
            if (slotIndex > -1) {
                let eventItem = maxBadgePlayer.inventory.getItem(slotIndex)
                eventItem.setCount(eventItem.count - 1)
                server.tell(Text.red(Text.translate('message.kubejs.summon.final_boss', maxBadgePlayer.getName().getString())))
                entity.tags.add('final_boss')
                entity.mergeNbt({
                    ForgeCaps: {
                        'champions:champion': {
                            affixes: [
                                { data: {}, identifier: 'adaptable' },
                                { data: {}, identifier: 'dampening' },
                                { data: {}, identifier: 'lively' },
                                { data: {}, identifier: 'arctic' },
                                { data: {}, identifier: 'enkindling' },
                                // { data: {}, identifier: 'paralyzing' },
                                { data: {}, identifier: 'molten' },
                                { data: {}, identifier: 'reflective' },
                                { data: {}, identifier: 'wounding' },
                                { data: {}, identifier: 'shielding' }
                            ],
                            tier: 9
                        }
                    },
                    Attributes: [
                        { Base: global.getPlayerDifficulty(maxBadgePlayer) * 1000.0, Name: 'minecraft:generic.max_health' }
                    ]
                })
            }
        }
    }
})

// Item.of('champions:champion_egg', '{Champion:{Affix:[],Tier:8},EntityTag:{Id:'yakurum:triton'}}')
// Item.of('champions:champion_egg', '{Champion:{Affix:[],Tier:7},EntityTag:{Id:'yakurum:poseidon'}}')

// EntityEvents.hurt((event) => {
//     const { source, entity, damage } = event
//     const { player } = source

//     const damageType = typeof source.type === 'function' ? source.type() : source.type
//     const msgId = typeof damageType.msgId === 'function' ? damageType.msgId() : damageType.msgId

//     if (msgId === 'player') {
//         if (source.actual && source.actual.isPlayer()) {
//             if (player.handSlots[0] === 'lucky:lucky_world_invasion_lucky_sword') {
//                 if (entity.persistentData.getBoolean('fix_damage')) {
//                     entity.persistentData.remove('fix_damage')
//                 } else if (source.actual.block.light > 0) {
//                     entity.persistentData.putBoolean('fix_damage', true)
//                     entity.attack(source, damage + source.actual.block.light)

//                     event.cancel()
//                 }
//             }
//         }
//     }
// })