import { system, world } from "@minecraft/server";
const MUSIC_DISC = [
    // length in seconds
    { name: 'minecraft:music_disc_13', length: 178 },
    { name: 'minecraft:music_disc_cat', length: 185 },
    { name: 'minecraft:music_disc_blocks', length: 345 },
    { name: 'minecraft:music_disc_chirp', length: 185 },
    { name: 'minecraft:music_disc_far', length: 174 },
    { name: 'minecraft:music_disc_mall', length: 197 },
    { name: 'minecraft:music_disc_mellohi', length: 96 },
    { name: 'minecraft:music_disc_stal', length: 150 },
    { name: 'minecraft:music_disc_strad', length: 188 },
    { name: 'minecraft:music_disc_ward', length: 251 },
    { name: 'minecraft:music_disc_11', length: 71 },
    { name: 'minecraft:music_disc_wait', length: 238 },
    { name: 'minecraft:music_disc_otherside', length: 195 },
    { name: 'minecraft:music_disc_5', length: 178 },
    { name: 'minecraft:music_disc_pigstep', length: 148 },
    { name: 'minecraft:music_disc_relic', length: 218 },
];
export class DanceEntity {
    constructor(config) {
        this.config = config;
    }
    static registerBehavior(config) {
        const eventEntity = new DanceEntity(config);
        this.entities.push(eventEntity);
    }
    static getEntity(id) {
        return DanceEntity.entities.find((entity) => entity.config.id === id);
    }
    static getPlaying(loc, dimId) {
        return world.getDynamicProperty(`jukebox.${dimId}.${JSON.stringify(loc)}`);
    }
    static setPlaying(block, value) {
        world.setDynamicProperty(`jukebox.${block.dimension.id}.${JSON.stringify(block.location)}`, value);
    }
    static initialize() {
        world.afterEvents.entityLoad.subscribe((data) => {
            const entity = data.entity;
            if (!entity || !entity.isValid())
                return;
            const found = this.getEntity(entity.typeId);
            if (!found)
                return;
            if (!entity.getProperty(found.config.propertyId))
                return;
            entity.setProperty(found.config.propertyId, false);
            if (found.config.onDanceEnd)
                found.config.onDanceEnd(entity);
        });
        world.afterEvents.playerInteractWithBlock.subscribe((data) => {
            if (data.block.typeId !== "minecraft:jukebox")
                return;
            const playing = this.getPlaying(data.block.location, data.block.dimension.id);
            if (playing) {
                this.setPlaying(data.block, undefined);
                this.stopDancing(data.block);
            }
            else {
                const disc = MUSIC_DISC.find((f) => f.name == data.beforeItemStack?.typeId);
                if (!disc)
                    return;
                this.setPlaying(data.block, true);
                this.startDancing(data.block, disc);
            }
        });
        world.afterEvents.playerBreakBlock.subscribe((data) => {
            if (!this.getPlaying(data.block.location, data.block.dimension.id))
                return;
            this.setPlaying(data.block, undefined);
            this.stopDancing(data.block);
        });
    }
    static stopDancing(block) {
        block.dimension.getEntities({ maxDistance: 35, location: block.location }).forEach((entity) => {
            const found = this.getEntity(entity.typeId);
            if (!found)
                return;
            if (!entity.getProperty(found.config.propertyId))
                return;
            if (entity.getDynamicProperty("cc.last_jukebox_playing") != `${block.dimension.id}.${JSON.stringify(block.location)}`)
                return;
            entity.setProperty(found.config.propertyId, false);
            if (found.config.onDanceEnd)
                found.config.onDanceEnd(entity);
        });
    }
    static startDancing(block, disc) {
        const blockLoc = block.location;
        const blockDIm = block.dimension.id;
        block.dimension.getEntities({ maxDistance: 25, location: block.location }).forEach((entity) => {
            const found = this.getEntity(entity.typeId);
            if (!found)
                return;
            if (entity.getProperty(found.config.propertyId))
                return;
            entity.setDynamicProperty("cc.last_jukebox_playing", `${block.dimension.id}.${JSON.stringify(block.location)}`);
            entity.setProperty(found.config.propertyId, true);
            if (found.config.onDance)
                found.config.onDance(entity);
            system.runTimeout(() => {
                if (!entity || !entity.isValid() || !entity.getProperty(found.config.propertyId))
                    return;
                if (!this.getPlaying(blockLoc, blockDIm))
                    return;
                if (entity.getDynamicProperty("cc.last_jukebox_playing") != `${block.dimension.id}.${JSON.stringify(block.location)}`)
                    return;
                entity.setProperty(found.config.propertyId, false);
                if (found.config.onDanceEnd)
                    found.config.onDanceEnd(entity);
            }, disc.length * 20);
        });
        const initialTick = world.getAbsoluteTime();
        const interval = system.runInterval(() => {
            if (!this.getPlaying(blockLoc, blockDIm) || world.getAbsoluteTime() - initialTick > disc.length * 20) {
                system.clearRun(interval);
                return;
            }
            block.dimension.getEntities({ maxDistance: 25, location: block.location }).forEach((entity) => {
                const found = this.getEntity(entity.typeId);
                if (!found)
                    return;
                if (entity.getProperty(found.config.propertyId))
                    return;
                entity.setProperty(found.config.propertyId, true);
                entity.setDynamicProperty("cc.last_jukebox_playing", `${block.dimension.id}.${JSON.stringify(block.location)}`);
                if (found.config.onDance)
                    found.config.onDance(entity);
                const blockLoc = block.location;
                const blockDIm = block.dimension.id;
                system.runTimeout(() => {
                    if (!entity || !entity.isValid() || !entity.getProperty(found.config.propertyId))
                        return;
                    if (!this.getPlaying(blockLoc, blockDIm))
                        return;
                    if (entity.getDynamicProperty("cc.last_jukebox_playing") != `${block.dimension.id}.${JSON.stringify(block.location)}`)
                        return;
                    entity.setProperty(found.config.propertyId, false);
                    if (found.config.onDanceEnd)
                        found.config.onDanceEnd(entity);
                }, (disc.length * 20) - (world.getAbsoluteTime() - initialTick));
            });
        }, 5);
    }
}
DanceEntity.entities = [];
