import { ItemStack } from '@minecraft/server';
import { b_list, debugging } from './config.js';

/**
 * Check if a block type is in the breakable list
 * @param {string} blockTypeId - The block type identifier
 * @returns {boolean} - True if the block should break when support is removed
 */
export function isBreakableBlock(blockTypeId) {
    return b_list.includes(blockTypeId);
}

/**
 * Get the block above a given position
 * @param {Dimension} dimension - The dimension to check in
 * @param {Vector3} position - The position to check above
 * @returns {Block|null} - The block above or null if none exists
 */
export function getBlockAbove(dimension, position) {
    try {
        const abovePos = {
            x: position.x,
            y: position.y + 1,
            z: position.z
        };
        return dimension.getBlock(abovePos);
    } catch (error) {
        debugLog(`Error getting block above position ${position.x}, ${position.y}, ${position.z}: ${error.message}`);
        return null;
    }
}

/**
 * Get all blocks above a position that should break (up to a reasonable height)
 * @param {Dimension} dimension - The dimension to check in
 * @param {Vector3} position - The starting position
 * @param {number} maxHeight - Maximum height to check (default: 10)
 * @returns {Array<{block: Block, position: Vector3}>} - Array of blocks and their positions
 */
export function getBreakableBlocksAbove(dimension, position, maxHeight = 10) {
    const blocksToBreak = [];
    
    for (let i = 1; i <= maxHeight; i++) {
        const checkPos = {
            x: position.x,
            y: position.y + i,
            z: position.z
        };
        
        try {
            const block = dimension.getBlock(checkPos);
            if (!block || block.typeId === 'minecraft:air') {
                break; // Stop if we hit air or can't get the block
            }
            
            if (isBreakableBlock(block.typeId)) {
                blocksToBreak.push({
                    block: block,
                    position: checkPos
                });
            } else {
                // If we hit a non-breakable block, stop checking higher
                break;
            }
        } catch (error) {
            debugLog(`Error checking block at height ${i} above ${position.x}, ${position.y}, ${position.z}: ${error.message}`);
            break;
        }
    }
    
    return blocksToBreak;
}

/**
 * Break a block with proper effects and item drop
 * @param {Dimension} dimension - The dimension containing the block
 * @param {Vector3} position - The position of the block to break
 * @param {Block} block - The block to break
 */
export function breakBlock(dimension, position, block) {
    try {
        // Spawn the block as an item before breaking it
        try {
            const itemStack = new ItemStack(block.typeId, 1);
            const dropPosition = {
                x: position.x + 0.5,
                y: position.y + 0.5,
                z: position.z + 0.5
            };
            
            dimension.spawnItem(itemStack, dropPosition);
            debugLog(`Dropped item ${block.typeId} at position ${dropPosition.x}, ${dropPosition.y}, ${dropPosition.z}`);
        } catch (itemError) {
            debugLog(`Could not spawn item for block ${block.typeId}: ${itemError.message}`);
        }
        
        // Set the block to air
        dimension.setBlockType(position, 'minecraft:air');
        
        // Spawn particle effects if possible
        try {
            dimension.spawnParticle('minecraft:destroy_block_particle', position, {
                'minecraft:particle_initial_velocity': {x: 0, y: 0.5, z: 0}
            });
        } catch (particleError) {
            debugLog(`Could not spawn particles for broken block: ${particleError.message}`);
        }
        
        debugLog(`Broke block ${block.typeId} at position ${position.x}, ${position.y}, ${position.z}`);
    } catch (error) {
        debugLog(`Error breaking block at ${position.x}, ${position.y}, ${position.z}: ${error.message}`);
    }
}

/**
 * Process breaking blocks above a destroyed block
 * @param {Dimension} dimension - The dimension where the break occurred
 * @param {Vector3} position - The position where the original block was broken
 */
export function processBlocksAbove(dimension, position) {
    const blocksToBreak = getBreakableBlocksAbove(dimension, position);
    
    if (blocksToBreak.length > 0) {
        debugLog(`Found ${blocksToBreak.length} blocks to break above position ${position.x}, ${position.y}, ${position.z}`);
        
        // Break blocks from top to bottom to simulate natural falling
        for (let i = blocksToBreak.length - 1; i >= 0; i--) {
            const { block, position: blockPos } = blocksToBreak[i];
            breakBlock(dimension, blockPos, block);
        }
    }
}

/**
 * Debug logging function
 * @param {string} message - The message to log
 */
export function debugLog(message) {
    if (debugging) {
        console.warn(`[BreakBelow] ${message}`);
    }
}

/**
 * Initialize the break-below system
 */
export function initializeSystem() {
    debugLog("Break-below system initialized");
    debugLog(`Monitoring ${b_list.length} block types: ${b_list.join(', ')}`);
}
