/**
 * DSS State System - Main Module
 * Handles block state cycling interactions
 */

import { world, system } from "@minecraft/server";
import { 
    BLOCK_TYPES, 
    STATE_CHANGE_SOUND, 
    INTERACTION_COOLDOWN 
} from "./dss_state_config.js";
import { 
    debug, 
    formatPos, 
    sendPlayerMessage, 
    playPlayerSound, 
    getBlockTypeSuffix, 
    isDssStateBlock, 
    getCurrentState, 
    setBlockState, 
    getNextState, 
    playSoundAtBlock 
} from "./dss_state_utils.js";

//========== STATE MANAGEMENT ==========//

/** Track recent interactions to prevent spam */
const recentInteractions = new Map();

/**
 * Handle block interaction for DSS state blocks
 * @param {object} block - The block that was interacted with
 * @param {object} player - The player who interacted
 * @returns {boolean} True if interaction was handled
 */
export function handleDssStateInteraction(block, player) {
    if (!isDssStateBlock(block)) {
        return false;
    }
    
    const blockPos = formatPos(block.location);
    const playerId = player.id;
    const interactionKey = `${playerId}_${blockPos}`;
    
    // Check for recent interaction cooldown
    if (recentInteractions.has(interactionKey)) {
        const lastInteraction = recentInteractions.get(interactionKey);
        const timeSince = Date.now() - lastInteraction;
        
        if (timeSince < INTERACTION_COOLDOWN * 50) { // Convert ticks to ms
            return true; // Handled but ignored due to cooldown
        }
    }
    
    // Record this interaction
    recentInteractions.set(interactionKey, Date.now());
    
    // Clean up old interactions
    cleanupOldInteractions();
    
    // Handle the state change
    const success = cycleBlockState(block, player);
    
    if (success) {
        debug(`Player ${player.name} cycled state of block at ${blockPos}`);
        return true;
    }
    
    return false;
}

/**
 * Cycle the state of a DSS state block
 * @param {object} block - The block to cycle
 * @param {object} player - The player performing the action
 * @returns {boolean} True if successful
 */
function cycleBlockState(block, player) {
    if (!block || !player) return false;
    
    // Get block type suffix
    const suffix = getBlockTypeSuffix(block.typeId);
    if (!suffix) {
        debug(`No valid suffix found for block: ${block.typeId}`, "warn");
        return false;
    }
    
    // Get block type configuration
    const blockConfig = BLOCK_TYPES[suffix];
    if (!blockConfig) {
        debug(`No configuration found for suffix: ${suffix}`, "warn");
        return false;
    }
    
    // Get current state
    const currentState = getCurrentState(block);
    if (!currentState) {
        debug(`Could not get current state for block at ${formatPos(block.location)}`, "warn");
        return false;
    }
    
    // Get next state
    const nextState = getNextState(currentState, blockConfig.states);
    
    // Set the new state
    const success = setBlockState(block, nextState);
    
    if (success) {
        // Play sound effect
        playSoundAtBlock(block, STATE_CHANGE_SOUND);
        
        debug(`Changed state from ${currentState} to ${nextState} for block at ${formatPos(block.location)}`);
        return true;
    } else {
        debug(`Failed to set state for block at ${formatPos(block.location)}`, "error");
        return false;
    }
}

/**
 * Get a display name for a block
 * @param {string} blockId - The block identifier
 * @returns {string} Display name
 */
function getBlockDisplayName(blockId) {
    if (!blockId) return "Unknown Block";
    
    // Extract the last part of the identifier for display
    const parts = blockId.split(':');
    const name = parts[parts.length - 1];
    
    // Convert to title case
    return name.split('_')
        .map(word => word.charAt(0).toUpperCase() + word.slice(1))
        .join(' ');
}

/**
 * Clean up old interaction records
 */
function cleanupOldInteractions() {
    const cutoffTime = Date.now() - (INTERACTION_COOLDOWN * 50 * 5); // 5x cooldown period
    
    for (const [key, timestamp] of recentInteractions.entries()) {
        if (timestamp < cutoffTime) {
            recentInteractions.delete(key);
        }
    }
}

/**
 * Get statistics about the state system
 * @returns {object} Statistics object
 */
export function getStateSystemStats() {
    return {
        trackedInteractions: recentInteractions.size,
        supportedTypes: Object.keys(BLOCK_TYPES).length,
        totalStates: Object.values(BLOCK_TYPES).reduce((sum, config) => sum + config.maxState, 0)
    };
}

//========== WORLD EVENT HANDLERS ==========//

/**
 * Initialize the DSS State System
 */
export function initializeDssStateSystem() {
    debug("Initializing DSS State System...");
    
    // Set up periodic cleanup
    system.runInterval(() => {
        cleanupOldInteractions();
    }, 1200); // Clean every minute
    
    debug("DSS State System initialized successfully");
}

/**
 * Handle script events for debugging and monitoring
 * @param {object} event - The script event
 */
export function handleStateScriptEvent(event) {
    if (!event.id.startsWith("dss_state:")) return;
    
    const command = event.id.substring(10); // Remove "dss_state:" prefix
    
    switch (command) {
        case "stats":
            const stats = getStateSystemStats();
            const source = event.sourceEntity;
            if (source) {
                sendPlayerMessage(source, `§bDSS State System Statistics:`);
                sendPlayerMessage(source, `§7- Tracked Interactions: ${stats.trackedInteractions}`);
                sendPlayerMessage(source, `§7- Supported Types: ${stats.supportedTypes}`);
                sendPlayerMessage(source, `§7- Total States: ${stats.totalStates}`);
            }
            break;
            
        case "debug":
            debug("Debug command received");
            debug(`Recent interactions: ${recentInteractions.size}`);
            break;
            
        case "cleanup":
            cleanupOldInteractions();
            debug("Manual cleanup performed");
            break;
            
        default:
            debug(`Unknown command: ${command}`, "warn");
            break;
    }
}

//========== CUSTOM COMPONENT HANDLER ==========//

/**
 * Handle custom component events
 * @param {object} event - The custom component event
 */
export function handleDssStateCustomComponent(event) {
    const { block, player } = event;
    
    if (!block || !player) {
        debug("Invalid custom component event data", "warn");
        return;
    }
    
    debug(`Custom component triggered for block ${block.typeId} at ${formatPos(block.location)}`);
    
    // Handle the state interaction
    handleDssStateInteraction(block, player);
}

//========== EXPORT SYSTEM ==========//

// Export the main handler function for use in other modules
export { handleDssStateInteraction as default }; 