import { world, Block, BlockPermutation } from "@minecraft/server";
import * as itemConveyor from './item_conveyor';

/**
 * 
 * @param {Block} block 
 */
export function onPlace(block) {
    block?.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
    const cardinal = block?.permutation.getState(`minecraft:cardinal_direction`);
    const tags = block?.permutation.getTags();
    let type = ``;
    let connectableType = ``;
    const perm = undefined

    if (tags.length > 0) {
        tags.forEach(tag => {
            if (tag.startsWith(`cy_cr:`) && tag.includes(`connectable`)) {
                const parts = tag.split('_');
                type = parts[2];
                if (parts.length > 2) {
                    connectableType = parts[3]
                }
            }
        })
    };

    transformOthers(block, cardinal, type, perm, connectableType);
};
/**
 * 
 * @param {Block} block 
 * @param {BlockPermutation} perm 
 */
export function onDestroy(block, perm) {
    const cardinal = perm.getState(`minecraft:cardinal_direction`);
    const tags = perm.getTags();
    let type = ``;

    if (tags.length > 0) {
        tags.forEach(tag => {
            if (tag.startsWith(`cy_cr:`) && tag.includes(`connectable`)) {
                const parts = tag.split('_');
                type = parts[2];
            }
        })
    };
    transformOthers(block, cardinal, type, perm);
};
/**
 * 
 * @param {Block} block 
 */
export function transform(block, type) {
    const cardinal = block?.permutation.getState(`minecraft:cardinal_direction`);
    const blocks = detectBlocks(block, cardinal, type);
    let newCardinal = cardinal;
    let rot = 0;

    if (cardinal === `south`) {
        rot = 0;
    };
    if (cardinal === `north`) {
        rot = 180;
    };
    if (cardinal === `west`) {
        rot = 90;
    };
    if (cardinal === `east`) {
        rot = 270
    };

    if ((!blocks.right && !blocks.left && !blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) || (!blocks.right && !blocks.left && blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) || (!blocks.right && !blocks.left && blocks.north && blocks.south)) {
        try {
            const newId = newIdBlock(block, `middle`);
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        } catch { }
    } else if (blocks.up && !blocks.down) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        }
    } else if (!blocks.up && blocks.down) {
        if (!blocks.south) {
            const newId = newIdBlock(block, `end`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            };
        } else {
            const newId = newIdBlock(block, `middle`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            };
        }
    } else if (blocks.up && blocks.down) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true))
        }
    } else if (blocks.up2 && !blocks.down2) {
        if (!blocks.north) {
            const newId = newIdBlock(block, `end`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
                block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
            };
        } else {
            const newId = newIdBlock(block, `middle`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            };
        }
    } else if (!blocks.up2 && blocks.down2) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        }
    } else if (blocks.up2 && blocks.down2) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        }
    } else if (blocks.right && !blocks.left && blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            rot -= 90
        }
    } else if (!blocks.right && blocks.left && blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
            rot += 90
        }
    } else if (blocks.right && !blocks.left && !blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        }
    } else if (!blocks.right && blocks.left && !blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            rot += 90
        }
    } else if ((!blocks.north && blocks.south) || ((!blocks.north && !blocks.south) && ((blocks.up && !blocks.up2) || (!blocks.up && blocks.up2)))) {
        const newId = newIdBlock(block, `end`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        }
    } else if ((blocks.north && !blocks.south) || ((!blocks.north && !blocks.south) && ((blocks.down && !blocks.down2) || (!blocks.down && blocks.down2)))) {
        const newId = newIdBlock(block, `end`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        }
    };

    if (rot === 0 || rot === 360) {
        newCardinal = `south`
    };
    if (rot === 180) {
        newCardinal = `north`
    };
    if (rot === 90) {
        newCardinal = `west`
    };
    if (rot === 270 || rot === -90) {
        newCardinal = `east`
    };

    if (cardinal) {
        block.setPermutation(block.permutation.withState(`minecraft:cardinal_direction`, newCardinal));
    };
    if (block.typeId.startsWith(`cy_cr:`) && block.typeId.includes(`item_conveyor`)) {
        block.setPermutation(block.permutation.withState(`cy_cr:on`, false));
        itemConveyor.onStart(block, 0, cardinal, `stop`)
    }
};
/**
 * 
 * @param {Block} block 
 * @param {String} cardinal 
 * @param {String} type 
 * @param {*} perm 
 * @param {String} connectableType 
 * @returns 
 */
export function transformOthers(block, cardinal, type, perm, connectableType) {
    const blocks = detectBlocks(block, cardinal, type, perm, connectableType);
    const blocks2 = localBlocks(block, cardinal);
    let newCardinal = cardinal;
    let rot = 0;

    if (cardinal === `south`) {
        rot = 0;
    };
    if (cardinal === `north`) {
        rot = 180;
    };
    if (cardinal === `west`) {
        rot = 90;
    };
    if (cardinal === `east`) {
        rot = 270
    };

    if ((!blocks.right && !blocks.left && !blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) || (!blocks.right && !blocks.left && blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) || (!blocks.right && !blocks.left && blocks.north && blocks.south)) {
        if (!blocks.right && !blocks.left && blocks.north && blocks.south) {
            transform(blocks2.south, type);
            transform(blocks2.north, type);

            if (blocks.up || blocks.up2 || blocks.down || blocks.down2) {
                transform(blocks2.up, type);
                transform(blocks2.up2, type);
                transform(blocks2.down, type);
                transform(blocks2.down2, type);
            }
        }
        return;
    } else if (blocks.up && !blocks.down) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true))
        }

        if (perm) {
            transform(blocks2.up, type)
        } else transform(blocks2.up, type);
        transform(blocks2.north, type)
    } else if (!blocks.up && blocks.down) {
        if (!blocks.south) {
            const newId = newIdBlock(block, `end`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            };
        }
        transform(blocks2.down, type)
        transform(blocks2.south, type)
        transform(blocks2.north, type)
    } else if (blocks.up && blocks.down) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true))
        };
        if (perm) {
            transform(blocks2.up, type)
        };
        transform(blocks2.down, type)
    } else if (blocks.up2 && !blocks.down2) {
        if (!blocks.north) {
            const newId = newIdBlock(block, `end`);
            if (block.typeId !== `minecraft:air`) {
                block.setPermutation(BlockPermutation.resolve(newId));
                block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
                block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
            };
        }
        transform(blocks2.up2, type);
        transform(blocks2.north, type)
        transform(blocks2.south, type)
    } else if (!blocks.up2 && blocks.down2) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        };
        transform(blocks2.down2, type)
        transform(blocks2.south, type)
    } else if (blocks.up2 && blocks.down2) {
        const newId = newIdBlock(block, `45_degreess`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        };
        if (perm) {
            transform(blocks2.up2, type)
        };
        transform(blocks2.down2, type);
        transform(blocks2.north, type)
    } else if (blocks.right && !blocks.left && blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            rot -= 90
        }

        transform(blocks2.right, type);
        transform(blocks2.north, type)
    } else if (!blocks.right && blocks.left && blocks.north && !blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
            rot += 90
        }

        transform(blocks2.left, type);
        transform(blocks2.north, type)
    } else if (blocks.right && !blocks.left && !blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        }

        transform(blocks2.right, type);
        transform(blocks2.north, type)
    } else if (!blocks.right && blocks.left && !blocks.north && blocks.south && !blocks.up && !blocks.down && !blocks.up2 && !blocks.down2) {
        const newId = newIdBlock(block, `corner`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            rot += 90
        }

        transform(blocks2.right, type);
        transform(blocks2.north, type)
    } else if (!blocks.north && blocks.south) {
        const newId = newIdBlock(block, `end`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
            block.setPermutation(block.permutation.withState(`cy_cr:mirrored`, true));
        };

        transform(blocks2.south, type)
    } else if (blocks.north && !blocks.south) {
        const newId = newIdBlock(block, `end`);
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(BlockPermutation.resolve(newId));
            block.setPermutation(block.permutation.withState(`cy_cr:placed`, true));
        };

        transform(blocks2.north, type);
    }

    if (rot === 0 || rot === 360) {
        newCardinal = `south`
    };
    if (rot === 180) {
        newCardinal = `north`
    };
    if (rot === 90) {
        newCardinal = `west`
    };
    if (rot === 270 || rot === -90) {
        newCardinal = `east`
    };
    if (cardinal) {
        if (block.typeId !== `minecraft:air`) {
            block.setPermutation(block.permutation.withState(`minecraft:cardinal_direction`, newCardinal));
        }
    }
};
/**
 * 
 * @param {Block} block 
 * @param {String} cardinal
 * @param {String} type
 * @returns {{right: Boolean, left: Boolean, north: Boolean, south: Boolean, up: Boolean, down: Boolean, up2: Boolean, down2: Boolean}}
 */
export function detectBlocks(block, cardinal, type, perm, connectableType) {
    let r = false;
    let l = false;
    let n = false;
    let s = false;
    let u = false;
    let d = false;
    let u2 = false;
    let d2 = false;

    const blocks = localBlocks(block, cardinal);

    if (blocks.right && blocks.right.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.right, type, perm);

        if (isSameType) {
            r = true;
        } else r = false;
    };
    if (blocks.left && blocks.left.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.left, type, perm);

        if (isSameType) {
            l = true;
        } else l = false;
    };
    if (blocks.north && blocks.north.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.north, type, perm);

        if (isSameType) {
            n = true;
        } else n = false;
    };
    if (blocks.south && blocks.south.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.south, type, perm);

        if (isSameType) {
            s = true;
        } else s = false;
    };
    if (blocks.up && blocks.up.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.up, type, perm);

        if (isSameType) {
            u = true;
        } else u = false;
    };
    if (blocks.down && blocks.down.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.down, type, perm);

        if (isSameType) {
            d = true;
        } else d = false;
    };
    if (blocks.up2 && blocks.up2.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.up2, type, perm);

        if (isSameType) {
            u2 = true;
        } else u2 = false;
    };
    if (blocks.down2 && blocks.down2.typeId !== `minecraft:air`) {
        const isSameType = sameType(blocks.down2, type, perm);

        if (isSameType) {
            d2 = true;
        } else d2 = false;
    };
    //world.sendMessage(`block: ${block.typeId} right: ${r} left: ${l} north: ${n} south: ${s} up: ${u} down: ${d} up2: ${u2} down2: ${d2}`)

    return { right: r, left: l, north: n, south: s, up: u, down: d, up2: u2, down2: d2 };
};
/**
 * 
 * @param {Block} block 
 * @param {String} cardinal 
 * @returns {{right: Block, left: Block, north: Block, south: Block, up: Block, down: Block, up2: Block, down2: Block}}
 */
export function localBlocks(block, cardinal) {
    let right;
    let left;
    let north;
    let south;
    let up;
    let down;
    let up2;
    let down2;

    if (cardinal === `south`) {
        right = block?.east(1);
        left = block?.west(1);
        north = block?.north(1);
        south = block?.south(1);
        up = block?.south(1).above(1);
        down = block?.north(1).below(1);
        up2 = block?.south(1).below(1);
        down2 = block?.north(1).above(1)
    };
    if (cardinal === `north`) {
        right = block?.west(1);
        left = block?.east(1);
        north = block?.south(1);
        south = block?.north(1);
        up = block?.north(1).above(1);
        down = block?.south(1).below(1);
        up2 = block?.north(1).below(1);
        down2 = block?.south(1).above(1)
    };
    if (cardinal === `east`) {
        right = block?.north(1);
        left = block?.south(1);
        north = block?.west(1);
        south = block?.east(1);
        up = block?.east(1).above(1);
        down = block?.west(1).below(1);
        up2 = block?.east(1).below(1);
        down2 = block?.west(1).above(1)
    };
    if (cardinal === `west`) {
        right = block?.south(1);
        left = block?.north(1);
        north = block?.east(1);
        south = block?.west(1);
        up = block?.west(1).above(1);
        down = block?.east(1).below(1);
        up2 = block?.west(1).below(1);
        down2 = block?.east(1).above(1)
    };
    //world.sendMessage(`right: ${right.typeId} left: ${left.typeId} north: ${north.typeId} south: ${south.typeId} up: ${up.typeId} down: ${down.typeId} up2: ${up2.typeId} down2: ${down2.typeId}`);

    return { right: right, left: left, north: north, south: south, up: up, down: down, up2: up2, down2: down2 }
}
/**
 * 
 * @param {Block} block
 * @param {String} type
 * @param {BlockPermutation} perm
 * @returns {Boolean}
 */
function sameType(block, type, perm) {
    let tags;
    if (perm === undefined) {
        tags = block?.permutation.getTags();
    } else {
        tags = perm.getTags();
    }
    let type2 = ``;

    if (tags.length > 0) {
        tags.forEach(tag => {
            if (tag.startsWith(`cy_cr:`) && tag.includes(`connectable`)) {
                const parts = tag.split('_');
                type2 = parts[2];
            }
        })
    };

    //world.sendMessage(`${block.typeId} ${type2} ${type}`)
    if (type2 !== undefined && type !== undefined) {
        if (type2 === type) {
            return true;
        } else return false;
    } else return false;
};
/**
 * 
 * @param {Block} block 
 * @param {String} replace 
 */
function newIdBlock(block, replace) {
    let newId = ``;

    if (block.typeId.includes("block")) {
        newId = block.typeId.replace("block", replace);
    } else if (block.typeId.includes("corner")) {
        newId = block.typeId.replace("corner", replace);
    } else if (block.typeId.includes("left")) {
        newId = block.typeId.replace("left", replace);
    } else if (block.typeId.includes("right")) {
        newId = block.typeId.replace("right", replace);
    } else if (block.typeId.includes("middle")) {
        newId = block.typeId.replace("middle", replace);
    } else if (block.typeId.includes("45_degreess")) {
        newId = block.typeId.replace("45_degreess", replace);
    } else if (block.typeId.includes("end")) {
        newId = block.typeId.replace("end", replace);
    }

    return newId;
};