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

export class SummonClass {
	static async blockSummoning(source, block, pattern, offsets, entity = 'zombie', summonOffset = 0) {
        let view = source.getRotation();
		const {x,y,z} = block.location;
        let roundedRotation = Math.round(view.y / 90) * 90;
        let normalizedRotation = ((roundedRotation % 360) + 360) % 360;

        // Check blocks based on the normalized rotation
        let isPatternMatching = this.checkBlockPattern(source, x, y, z, pattern, offsets, normalizedRotation);

        //console.warn(`Pattern match: ${isPatternMatching}`);
		if (isPatternMatching) {
            this.setBlock(source, 'minecraft:air', block.location);
			this.removeBlockPattern(source, x, y, z, pattern, offsets, normalizedRotation)
			const newCoords = { x: x, y: y + summonOffset, z: z}
            await this.sleep(20)
			source.dimension.spawnEntity(entity, newCoords).setRotation({x: normalizedRotation, y: 0});
		}
    }

    static removeBlockPattern(source, x, y, z, pattern, offsets, rotation) {
        for (let i = 0; i < pattern.length; i++) {
            let { dx, dy, dz } = offsets[i];

            // Adjust for rotation
            if (rotation === 90) {
                [dx, dz] = [dz, -dx];
            } else if (rotation === 180) {
                dx = -dx;
                dz = -dz;
            } else if (rotation === 270) {
                [dx, dz] = [-dz, dx];
            }

            // Get the block type at the current offset position
            const coords = { x: x + dx, y: y + dy, z: z + dz };
            //console.warn(`Checking block at (${coords.x}, ${coords.y}, ${coords.z}) against pattern: ${pattern[i]}`);
            let blockType = this.getBlockTypeAt(source, coords, pattern[i]);

            if (blockType) {
                //console.warn(`Removing Block at (${coords.x}, ${coords.y}, ${coords.z})`);
				this.setBlock(source, 'minecraft:air', coords);
            }
        }
    }
	
    static checkBlockPattern(source, x, y, z, pattern, offsets, rotation) {
        for (let i = 0; i < pattern.length; i++) {
            let { dx, dy, dz } = offsets[i];

            // Adjust for rotation
            if (rotation === 90) {
                [dx, dz] = [dz, -dx];
            } else if (rotation === 180) {
                dx = -dx;
                dz = -dz;
            } else if (rotation === 270) {
                [dx, dz] = [-dz, dx];
            }

            // Get the block type at the current offset position
            const coords = { x: x + dx, y: y + dy, z: z + dz };
            //console.warn(`Checking block at (${coords.x}, ${coords.y}, ${coords.z}) against pattern: ${pattern[i]}`);
            let blockType = this.getBlockTypeAt(source, coords, pattern[i]);

            if (!blockType) {
                //console.warn(`Pattern mismatch at (${coords.x}, ${coords.y}, ${coords.z})`);
                return false;
            }
        }
        return true;
    }

    static getBlockTypeAt(source, coords, block) {
        const sourceBlock = source.dimension.getBlock(coords);
        if (sourceBlock) {
            if (sourceBlock.permutation.matches(block.toString())) {
                //console.warn(`Block at (${coords.x}, ${coords.y}, ${coords.z}) matches ${block}`);
                return true;
            } else {
                //console.warn(`Block at (${coords.x}, ${coords.y}, ${coords.z}) does not match ${block}`);
                return false;
            }
        } else {
            //console.warn(`No block found at (${coords.x}, ${coords.y}, ${coords.z})`);
            return false;
        }
    }

    static getElectricBall(source, coords, block) {
        const sourceBlock = source.dimension.getBlock(coords);
        if (sourceBlock) {
            if (sourceBlock.permutation.matches(block.toString())) {
                //console.warn(`Block at (${coords.x}, ${coords.y}, ${coords.z}) matches ${block}`);
                return { matches: true, block: sourceBlock };
            } else {
                //console.warn(`Block at (${coords.x}, ${coords.y}, ${coords.z}) does not match ${block}`);
                return { matches: false, block: null };
            }
        } else {
            //console.warn(`No block found at (${coords.x}, ${coords.y}, ${coords.z})`);
            return { matches: false, block: null };
        }
    }

	static async sleep(ticks) {
		return new Promise((resolve) => system.runTimeout(() => resolve(undefined), ticks));
	}

    static setBlock(source, blockPerm, coords) {
        const block = source.dimension.getBlock(coords);
        block.setPermutation(BlockPermutation.resolve(blockPerm));
    }
       
}