import { world, system } from "@minecraft/server";

// 可以踩踏出矿石的方块
const oreBlocks = {
    "minecraft:stone": 0,
    "minecraft:deepslate": 1,
    "minecraft:dripstone_block": 2,
    "minecraft:andesite": 0,
    "minecraft:diorite": 0,
    "minecraft:granite": 0,
    "minecraft:blackstone": 0,
    "minecraft:tuff": 0,
    "minecraft:basalt": 0,
}

// 钟乳石避免生成在这些方块下面
const avoidBlocks = [
    "minecraft:pointed_dripstone",
    "pm_mock:mossy_pointed_dripstone"
]

// 冲撞技能
function chargeKnockback(sourceEntity) {
    sourceEntity.runCommandAsync(`tag @s add pm_mock:charge`);
    const nearbyEntities = sourceEntity.dimension.getEntities({
        location: sourceEntity.location,
        maxDistance: 3.5,
        minDistance: 1,
        excludeTypes: ["minecraft:item", "minecraft:xp_orb", "minecraft:arrow", "minecraft:thrown_trident", "minecraft:snowball", "minecraft:ender_pearl"]
    });

    const totalDamage = 4;
    nearbyEntities.forEach(entity => {
        entity.runCommandAsync(`damage @s ${totalDamage} entity_attack entity @e[tag=pm_mock:charge]`);
        const view = sourceEntity.getViewDirection();
        entity.applyKnockback(view.x, view.z, 1, 0.0);
    });

    system.runTimeout(() => {
        sourceEntity.runCommandAsync(`tag @s remove pm_mock:charge`);
    }, 2);
}


// 生成随机点
function generateRandomPoints(center, minRadius, maxRadius, count) {
    const points = [];
    for (let i = 0; i < count; i++) {
        const angle = Math.random() * 2 * Math.PI;
        const radius = Math.sqrt(Math.random() * (maxRadius * maxRadius - minRadius * minRadius)) + minRadius;
        const x = center.x + radius * Math.cos(angle);
        const z = center.z + radius * Math.sin(angle);
        points.push({ x, z });
    }
    return points;
}

// 温顺状态下的践踏技能
// 实体附近随机选点，下方如果有固体方块就破坏或者刷新的矿物
function stompTamed(sourceEntity) {
    const entityLocation = sourceEntity.location;
    const randomCounts = Math.floor(Math.random() * 4) + 3;
    const points = generateRandomPoints(entityLocation, 2, 6, randomCounts);

    points.forEach(point => {
        for (let y = 1; y >= -5; y--) {
            const blockLocation = { x: point.x, y: entityLocation.y + y, z: point.z };
            const block = sourceEntity.dimension.getBlock(blockLocation);

            if (!block.isAir && !block.isLiquid && !block.isWaterlogged && !block.typeId.endsWith('_leaves')) {
                const blockTypeId = block.typeId;
                block.above().setType(blockTypeId);
                sourceEntity.dimension.runCommand(`execute positioned ${blockLocation.x} ${blockLocation.y} ${blockLocation.z} run /setblock ~~1~ air destroy`);

                if (oreBlocks.hasOwnProperty(blockTypeId)) {
                    const spawnedEntity = sourceEntity.dimension.spawnEntity('pm_mock:ancient_ore_nodes_dummy', block.above().location);
                    spawnedEntity.setRotation({ x: 0, y: Math.random() * 360 - 180 });
                    spawnedEntity.setProperty('pm_mock:ancient_ore_nodes_variant', oreBlocks[blockTypeId]);
                }

                break;
            }
        }
    });
}



// 矿石生成
function generateOreNodes(entity) {
    if (entity.typeId !== 'pm_mock:ancient_ore_nodes_dummy') return;

    const entityLocation = entity.location;
    const entityRotationY = entity.getRotation().y;
    const block = entity.dimension.getBlock(entityLocation);
    block.setType('pm_mock:ancient_ore_nodes');

    // 根据底下方块设置变种
    let variantState = 0;
    if (block.below().typeId === 'minecraft:deepslate') {
        variantState = 1;
    }
    else if (block.below().typeId === 'minecraft:dripstone_block') {
        variantState = 2;
    }

    // 映射旋转角度到对应的值
    let newRotationState = 0;
    let newRotation = entityRotationY;

    // 将旋转角度归一化到0-360度
    if (newRotation < 0) {
        newRotation += 360;
    }

    // 确保角度在0-360度之间
    newRotation = newRotation % 360;

    // 映射到最近的90度倍数
    newRotation = Math.floor(newRotation / 90) * 90;

    switch (newRotation) {
        case 0:
            newRotationState = 3;
            break;
        case 90:
            newRotationState = 4;
            break;
        case 180:
            newRotationState = 1;
            break;
        case 270:
            newRotationState = 2;
            break;
        default:
            newRotationState = 0;
    }

    block.setPermutation(block.permutation.withState("pm_mock:ancient_ore_nodes_rotation", newRotationState));
    block.setPermutation(block.permutation.withState("pm_mock:ancient_ore_nodes_variant", variantState));

    // const rotationState = block.permutation.getState('pm_mock:ancient_ore_nodes_rotation');
    // variantState = block.permutation.getState('pm_mock:ancient_ore_nodes_variant');

    // console.warn(`实体旋转：${entityRotationY}, 处理后${newRotation}, 方块 (${entityLocation.x}, ${entityLocation.y}, ${entityLocation.z}) 旋转: ${rotationState} 变种: ${variantState}`);

    system.runTimeout(() => {
        entity.remove();
    }, 2);
}

// 事件监听
system.afterEvents.scriptEventReceive.subscribe((event) => {
    const { id, message, sourceEntity } = event;

    // 冲撞技能
    if (id === 'pm_mock:cave_brawler_charge') {
        const chargeAction = system.runInterval(() => {
            if (sourceEntity.isValid()) {
                const view = sourceEntity.getViewDirection();
                sourceEntity.applyKnockback(view.x, view.z, 2.5, 0.6);

                chargeKnockback(sourceEntity);

                if (!sourceEntity.isOnGround) {
                    sourceEntity.applyKnockback(view.x, view.z, 0.0, -0.6);
                }

                const commands = [
                    "camerashake add @a[r=10] 0.1 0.15 positional",
                    "camerashake add @a[r=10] 0.1 0.1 positional",
                    "camerashake add @a[rm=10,r=20] 0.05 0.15 positional",
                    "camerashake add @a[rm=10,r=20] 0.05 0.1 positional",
                ]
                commands.forEach(command => {
                    sourceEntity.runCommand(command);
                });

                system.runTimeout(() => {
                    system.clearRun(chargeAction);
                }, 5 * 20);
            }
            else {
                system.clearRun(chargeAction);

            }

        }, 2);
    }

    // 践踏技能
    // 实体附近随机选点，上方如果有固体方块就刷一个钟乳石
    else if (id === 'pm_mock:cave_brawler_stomp') {
        const entityLocation = sourceEntity.location;
        const points = generateRandomPoints(entityLocation, 1, 10, 20);

        points.forEach(point => {
            for (let y = 3; y <= 20; y++) {
                const blockLocation = { x: point.x, y: entityLocation.y + y, z: point.z };
                const block = sourceEntity.dimension.getBlock(blockLocation);

                if (!block.isAir && !block.isLiquid && !block.isWaterlogged && !block.typeId.endsWith('_leaves')) {
                    // 随机选择y-1到y-3之间的位置
                    const randomYOffset = Math.floor(Math.random() * 3) + 1;
                    const spawnLocation = { x: blockLocation.x, y: blockLocation.y - randomYOffset, z: blockLocation.z };

                    // 增加延时，延时设置为0到20时间单位的随机值
                    const delay = Math.floor(Math.random() * 21);
                    system.runTimeout(() => {
                        sourceEntity.dimension.spawnEntity("pm_mock:cave_brawler_dripstone", spawnLocation);
                    }, delay);

                    // 检查这个位置能不能生成钟乳石
                    if (!avoidBlocks.includes(block.typeId)) {
                        block.below().setType('pm_mock:mossy_pointed_dripstone')
                        // console.warn(`生成的钟乳石位置：(${block.location.x}, ${block.location.y -1}, ${block.location.z})`);
                    }

                    else if (block.typeId === "pm_mock:mossy_pointed_dripstone") {
                        block.dimension.runCommand(`execute positioned ${block.location.x} ${block.location.y} ${block.location.z} run setblock ~~~ air destroy`)
                    }

                    break;
                }
            }
        });
    }

    // 温顺状态下的践踏技能
    // 实体附近随机选点，下方如果有固体方块就破坏或者刷新的矿物
    else if (id === 'pm_mock:cave_brawler_stomp_tamed') {
        stompTamed(sourceEntity);
        const commands = [
            "camerashake add @a[r=10] 0.2 0.7 positional",
            "camerashake add @a[r=10] 0.2 0.2 positional",
            "camerashake add @a[rm=10,r=20] 0.1 0.7 positional",
            "camerashake add @a[rm=10,r=20] 0.1 0.2 positional",
        ]
        commands.forEach(command => {
            sourceEntity.runCommand(command);
        });
    }

    // 矿石dummy触发的生成矿石
    else if (id === 'pm_mock:ancient_ore_nodes_generate') {
        generateOreNodes(sourceEntity);
    }
});


// 玩家与方块交互事件
world.afterEvents.playerInteractWithBlock.subscribe((event) => {
    const { block, beforeItemStack, player } = event;

    if (block.typeId === "minecraft:jukebox") {
        // 玩家与唱片机交互
        // const blockLocation = block.location;

        // const itemName = beforeItemStack.typeId;
        

        // const itemNameSlice = itemName.slice(0, 21);


        // if (itemNameSlice === "minecraft:music_disc_") {
        //     // 获取周围的实体
        //     const nearbyEntities = player.dimension.getEntities({
        //         location: { x: blockLocation.x, y: blockLocation.y, z: blockLocation.z },
        //         minDistance: 0,
        //         maxDistance: 48,
        //         type: "pm_mock:cave_brawler"
        //     });
    
        //     for (const entity of nearbyEntities) {
        //         const tameState = entity.getProperty('pm_mock:tame_state')
        //         if (tameState === 0) {
        //             // 驯服
        //             entity.triggerEvent('become_tamed')
        //         }
                
                
        //     }
        // }

        


    }
    else if (block.typeId === "minecraft:noteblock") {
        // 玩家与音符盒交互
        const blockLocation = block.location;
        const nearbyEntities = player.dimension.getEntities({
            location: { x: blockLocation.x, y: blockLocation.y, z: blockLocation.z },
            minDistance: 0,
            maxDistance: 32,
            type: "pm_mock:cave_brawler"
        });

        for (const entity of nearbyEntities) {
            const tameState = entity.getProperty('pm_mock:tame_state')
            if (tameState === 0) {
                // 驯服
                entity.triggerEvent('become_tamed')
            }
            
            
        }
    }
})