import {ItemStack,system} from '@minecraft/server';



/*
    finally some decent code somewhere
*/
const vanillaSmeltableOreDict =
[
    
    {id:'minecraft:iron_ore',drop:'minecraft:raw_iron', dropSmelt:'minecraft:iron_ingot'},
    {id:'minecraft:deepslate_iron_ore', drop:'minecraft:raw_iron', dropSmelt:'minecraft:iron_ingot'},
    {id:'minecraft:gold_ore', drop:'minecraft:raw_gold', dropSmelt:'minecraft:gold_ingot'},
    {id:'minecraft:deepslate_gold_ore', drop:'minecraft:raw_gold', dropSmelt:'minecraft:gold_ingot'},
    {id:'minecraft:copper_ore', drop:'minecraft:raw_copper', dropSmelt:'minecraft:copper_ingot'},
    {id:'minecraft:deepslate_copper_ore', drop:'minecraft:raw_copper', dropSmelt:'minecraft:copper_ingot'},
    {id:'minecraft:ancient_debris',  drop:'minecraft:ancient_debris', dropSmelt:'minecraft:netherite_scrap'},
]


const tiers =[
    {id:'wood_tier',value:1,name:'Wooden Pickaxe'},
    {id:'stone_tier',value:2,name:'Stone Pickaxe'},
    {id:'copper_tier',value:3,name:'Copper Pickaxe'},
    {id:'tin_tier',value:4,name:'Tin Pickaxe'},
    {id:'iron_tier',value:5,name:'Iron Pickaxe'},
    {id:'platinum_tier',value:6,name:'Platinum Pickaxe'},
    {id:'nickel_tier',value:7,name:'Nickel Pickaxe'},
    {id:'netherite_tier',value:8,name:'Netherite Pickaxe'},
    {id:'infused_tier',value:9,name:'Light/Void Pickaxe'}
]

const oreDict = [
    {id:'minecraft:coal_ore', tier:1},
    {id:'minecraft:deepslate_coal_ore', tier:1},
    {id:'minecraft:copper_ore', tier:2},
    {id:'minecraft:deepslate_copper_ore', tier:2},
    {id:'minecraft:iron_ore', tier:3},
    {id:'minecraft:deepslate_iron_ore', tier:3},
    {id:'minecraft:lapis_ore', tier:2},
    {id:'minecraft:deepslate_lapis_ore', tier:2},
    {id:'minecraft:redstone_ore', tier:5},
    {id:'minecraft:deepslate_redstone_ore', tier:5},
    {id:'minecraft:diamond_ore', tier:5},
    {id:'minecraft:deepslate_diamond_ore', tier:5},
    {id:'minecraft:gold_ore', tier:5},
    {id:'minecraft:deepslate_gold_ore', tier:5},
    {id:'edx:coal_frozen', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:1, minXp:0, maxXP:2, drop:'minecraft:coal'},
    {id:'edx:coal_red', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:1, minXp:0, maxXP:2, drop:'minecraft:coal'},
    {id:'edx:coal_sand', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:1, minXp:0, maxXP:2, drop:'minecraft:coal'},
    {id:'edx:copper_frozen', minOre:2, maxOre:5, maxOreF1:10, maxOreF2:15, maxOreF3:20, tier:2, minXp:0, maxXP:0, drop:'minecraft:raw_copper', dropSmelt:'minecraft:copper_ingot'},
    {id:'edx:copper_red', minOre:2, maxOre:5, maxOreF1:10, maxOreF2:15, maxOreF3:20, tier:2, minXp:0, maxXP:0, drop:'minecraft:raw_copper', dropSmelt:'minecraft:copper_ingot'},
    {id:'edx:copper_sand', minOre:2, maxOre:5, maxOreF1:10, maxOreF2:15, maxOreF3:20, tier:2, minXp:0, maxXP:0, drop:'minecraft:raw_copper', dropSmelt:'minecraft:copper_ingot'},
    {id:'edx:diamond_frozen', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:diamond'},
    {id:'edx:diamond_red', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:diamond'},
    {id:'edx:diamond_sand', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:diamond'},
    {id:'edx:emerald_frozen', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:emerald'},
    {id:'edx:emerald_red', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:emerald'},
    {id:'edx:emerald_sand', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:3, maxXP:7, fortuneChanceSystem:'diamond', drop:'minecraft:emerald'},
    {id:'edx:fire_opal_ore', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:2, maxXP:5, drop:'edx:fire_opal'},
    {id:'edx:gold_frozen', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:0, maxXP:0, drop:'minecraft:raw_gold', dropSmelt:'minecraft:gold_ingot'},
    {id:'edx:gold_sand', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:0, maxXP:0, drop:'minecraft:raw_gold', dropSmelt:'minecraft:gold_ingot'},
    {id:'edx:gold_red', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:5, minXp:0, maxXP:0, drop:'minecraft:raw_gold', dropSmelt:'minecraft:gold_ingot'},
    {id:'edx:iron_frozen', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:3, minXp:0, maxXP:0, drop:'minecraft:raw_iron', dropSmelt:'minecraft:iron_ingot'},
    {id:'edx:iron_sand', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:3, minXp:0, maxXP:0, drop:'minecraft:raw_iron', dropSmelt:'minecraft:iron_ingot'},
    {id:'edx:iron_red', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:3, minXp:0, maxXP:0, drop:'minecraft:raw_iron', dropSmelt:'minecraft:iron_ingot'},
    {id:'edx:lapis_frozen', minOre:4, maxOre:9, maxOreF1:18, maxOreF2:27, maxOreF3:36, tier:2, minXp:2, maxXP:5, drop:'minecraft:lapis_lazuli'},
    {id:'edx:lapis_sand', minOre:4, maxOre:9, maxOreF1:18, maxOreF2:27, maxOreF3:36, tier:2, minXp:2, maxXP:5, drop:'minecraft:lapis_lazuli'},
    {id:'edx:lapis_red', minOre:4, maxOre:9, maxOreF1:18, maxOreF2:27, maxOreF3:36, tier:2, minXp:2, maxXP:5, drop:'minecraft:lapis_lazuli'},
    {id:'edx:light_seed_ice', minOre:1, maxOre:1, maxOreF1:1, maxOreF2:1, maxOreF3:1, tier:8, minXp:5, maxXP:10, drop:'edx:fossilized_light_seed'},
    {id:'edx:light_seed_purpur', minOre:1, maxOre:1, maxOreF1:1, maxOreF2:1, maxOreF3:1, tier:8, minXp:5, maxXP:10, drop:'edx:fossilized_light_seed'},
    {id:'edx:light_seed_end', minOre:1, maxOre:1, maxOreF1:1, maxOreF2:1, maxOreF3:1, tier:8, minXp:5, maxXP:10, drop:'edx:fossilized_light_seed'},
    {id:'edx:nickel_ore', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:6, minXp:0, maxXP:0, fortuneChanceSystem:'nickel', drop:'edx:raw_nickel', dropSmelt:'edx:nickel_ingot'},
    {id:'edx:platinium_ore', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:4, maxOreF3:6, tier:5, minXp:0, maxXP:0, drop:'edx:raw_platinium', dropSmelt:'edx:platinium_ingot'},
    {id:'edx:redstone_frozen', minOre:4, maxOre:5, maxOreF1:6, maxOreF2:7, maxOreF3:8, tier:5, minXp:1, maxXP:5, drop:'minecraft:redstone'},
    {id:'edx:redstone_sand', minOre:4, maxOre:5, maxOreF1:6, maxOreF2:7, maxOreF3:8, tier:5, minXp:1, maxXP:5, drop:'minecraft:redstone'},
    {id:'edx:redstone_red', minOre:4, maxOre:5, maxOreF1:6, maxOreF2:7, maxOreF3:8, tier:5, minXp:1, maxXP:5, drop:'minecraft:redstone'},
    {id:'edx:tin_ore', minOre:1, maxOre:3, maxOreF1:6, maxOreF2:9, maxOreF3:12, tier:3, minXp:0, maxXP:0, drop:'edx:raw_tin', dropSmelt:'edx:tin_ingot'},
    {id:'edx:tin_frozen', minOre:1, maxOre:3, maxOreF1:6, maxOreF2:9, maxOreF3:12, tier:3, minXp:0, maxXP:0, drop:'edx:raw_tin', dropSmelt:'edx:tin_ingot'},
    {id:'edx:tin_sand', minOre:1, maxOre:3, maxOreF1:6, maxOreF2:9, maxOreF3:12, tier:3, minXp:0, maxXP:0, drop:'edx:raw_tin', dropSmelt:'edx:tin_ingot'},
    {id:'edx:tin_red', minOre:1, maxOre:3, maxOreF1:6, maxOreF2:9, maxOreF3:12, tier:3, minXp:0, maxXP:0, drop:'edx:raw_tin', dropSmelt:'edx:tin_ingot'},
    {id:'edx:void_fossil_ore', minOre:1, maxOre:1, maxOreF1:1, maxOreF2:1, maxOreF3:1, tier:8, minXp:5, maxXP:10, drop:'edx:void_fossil'},
    {id:'edx:sulfur_ore', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:5, tier:1, minXp:1, maxXP:4, drop:'edx:sulfur'},
    {id:'edx:ruby_ore', minOre:1, maxOre:1, maxOreF1:2, maxOreF2:3, maxOreF3:4, tier:6, minXp:3, maxXP:7, drop:'edx:ruby', ruby:true} //ruby value is for the artifact
]

export function oreDestroy(block,item,player){
    if(item==undefined) return
    if(isPickaxe(item))
    {
        if(player.hasTag('molten_ingot') && isVanillaSmeltableOre(block) )
        {
            const ore = vanillaSmeltableOreDict.find(({ id }) => id === block.typeId)
            if(ore?.dropSmelt!=undefined)
            {
                system.runTimeout(() => {//if it works don't touch it
                    const entities = block.dimension.getEntities({location: block.location, type: "minecraft:item",maxDistance: 2});
                    for(const entity of entities)
                    {
                        var item = entity?.getComponent("minecraft:item")?.itemStack
                        if(item.typeId==ore.drop) //item.typeId is the id of the item of the entity, entity.typeId is "item"
                        { 
                            entity.remove()
                            system.runTimeout(() => { 
                                block.dimension.spawnItem(new ItemStack(ore.dropSmelt, 1), block.center());
                            },2)
                        }
                    }
                    
                })
            }     
        }
        else
        {
            if(!checkTier(item,block,player)) return;
            const hasSilk = hasSilktouch(item)
            if(hasSilk)
            {
                system.runTimeout(() => {
                    block.dimension.spawnItem(new ItemStack(block.typeId, 1), block.center());
                },2)
            }
            else
            {
                const blockId = block.typeId //after the runtimeout the block is air so the id change, it took me 1 fucking hour to figure it gaaaawwrrrr curse of depression!!!!
                system.runTimeout(() => {
                    moddedOreDrop(block,item,player,blockId)
                },2)
            }
        }
    }
}

function moddedOreDrop(block,item,player,blockId)
{
    const ore = oreDict.find(({ id }) => id === blockId)
    if(ore==undefined) return;
    const fortune = getFortuneValue(item)
    const itemAmount = itemCalcAmount(ore,fortune)  
    if(itemAmount==0) return
    if(player.hasTag('molten_ingot') && ore?.dropSmelt!=undefined)
        system.runTimeout(() => {
            block.dimension.spawnItem(new ItemStack(ore.dropSmelt, itemAmount), block.center());
        },2)
    else
        system.runTimeout(() => {
            block.dimension.spawnItem(new ItemStack(ore.drop, itemAmount), block.center());
        },2)
    xpDrop(ore,block)
    if(ore?.ruby!=undefined)
        if(Math.random()<1/50)
        {
            system.runTimeout(() => {
                block.dimension.spawnItem(new ItemStack("edx:bloody_ruby", 1), block.center());
            },2)
        }
}

function xpDrop(ore,block){
    const xpAmount = Math.random()*(ore.maxXP-ore.minXp)+ore.minXp
    for(let i = 0; i < xpAmount ; i++)
        block.dimension.spawnEntity("xp_orb",block.center());
}
function isModdedOre(block){
    return block.hasTag('minecraft:is_ore') 
}
function isVanillaSmeltableOre(block){
    return vanillaSmeltableOreDict.find(({ id }) => id === block.typeId)!=undefined
}

function hasSilktouch(item){
    return item?.getComponent('enchantable')?.getEnchantment("silk_touch")?.level==1
}

function getFortuneValue(item){
    return item?.getComponent('enchantable')?.getEnchantment("fortune")?.level
}

function isPickaxe(item){
    return item.hasTag('minecraft:is_pickaxe')
}

function checkTier(item,block,player){
    const ore = oreDict.find(({ id }) => id === block.typeId)
    if(ore==undefined) return false;
    const blockTierValue = ore.tier
    const itemTags = item.getTags()
    for(const tag of itemTags)
    {
        var itemTier = tiers.find(({ id }) => id === tag)
        if(itemTier!=undefined)
            break;
    }
    if(itemTier==undefined) return false;
    if(itemTier.value>=blockTierValue) {;return true} 
    else
    {
        sendTierMessage(blockTierValue,player)
        return false
    }
}

function sendTierMessage(blockTierValue,player)
{
    const tier = tiers.find(({ value }) => value === blockTierValue)
        var PickNeedMessage= {rawtext :[
      {translate: "message.PickNeedMessage"},{text:" "},{text: tier.name},{text:" "},{ translate: "message.OreMessage"}
]};
        var WikiPickOreMessage= {rawtext :[{ 
    translate: "message.WikiOreMessage",
    }]};
    player.sendMessage(PickNeedMessage)
    if(tier.value == 6 || tier.value == 7)
        player.sendMessage(WikiPickOreMessage) 
}

function itemCalcAmount(ore,fortune){
    if(ore?.maxOre==undefined) return 0;
    const fortuneList = [ore?.maxOre, ore?.maxOreF1, ore?.maxOreF2, ore?.maxOreF3]
    var fortuneChosen = ore.maxOre
    if(fortune!=undefined) fortuneChosen = fortuneList[fortune]
    var itemAmount = ore.minOre
    var random = Math.random();
    if(ore.fortuneChanceSystem=='diamond')
    {
        switch(fortune)
        {
            case 1: if(random<1/3) itemAmount =ore.maxOre; break;
            case 2: 
                if(random<1/4)
                {
                    itemAmount =ore.maxOreF1
                }
                else if(random<1/2 && random >=1/4)
                {
                    itemAmount =ore.maxOreF2
                }
                break;
            case 3: 
                if(random<1/5)
                {
                    itemAmount =ore.maxOreF1
                }
                else if(random<2/5 && random >=1/5)
                {
                    itemAmount =ore.maxOreF2
                }
                else if(random<3/5 && random >=2/5)
                {
                    itemAmount =ore.maxOreF3
                }
                break;
                    
        }
    }
    else if(ore.fortuneChanceSystem=='nickel')
        {
            switch(fortune)
            {
                case 1: if(random<1/4) itemAmount =ore.maxOre; break; //1.25 nickel en moyenne
                case 2: //1.6 nickel en moyenne
                    if(random<1/5)
                    {
                        itemAmount =ore.maxOreF1
                    }
                    else if(random<2/5 && random >=1/5)
                    {
                        itemAmount =ore.maxOreF2
                    }
                    break;
                case 3: //1.9 nickel en moyenne, if the code works idk
                    if(random<1/6)
                    {
                        itemAmount =ore.maxOreF1
                    }
                    else if(random<2/6 && random >=1/6)
                    {
                        itemAmount =ore.maxOreF2
                    }
                    else if(random<3/6 && random >=2/6)
                    {
                        itemAmount =ore.maxOreF3
                    }
                    break;
            }
        }
    else
    {
        itemAmount = Math.random()*(fortuneChosen-ore.minOre)+ore.minOre
    }
    return itemAmount

}


