import { world } from '@minecraft/server';
import { statsDb } from './main';
/**
 * Utility functions for common stats operations
 */
export class StatsUtils {
    /**
     * Start timing a grid for a player
     */
    static startGridTimer(player, gridId) {
        const key = `grid_timer_${player.name}_${gridId}`;
        world.setDynamicProperty(key, Date.now());
    }
    /**
     * End timing a grid and record the time
     */
    static endGridTimer(player, gridId) {
        const key = `grid_timer_${player.name}_${gridId}`;
        const startTime = world.getDynamicProperty(key);
        if (!startTime) {
            console.warn(`No timer found for player ${player.name} on grid ${gridId}`);
            return null;
        }
        const completionTime = Date.now() - startTime;
        // Clear the timer
        world.setDynamicProperty(key, undefined);
        // Update the player's stats
        statsDb.updateGridTime(player.name, gridId, completionTime);
        return completionTime;
    }
    /**
     * Start timing overall completion
     */
    static startOverallTimer(player) {
        const key = `overall_timer_${player.name}`;
        world.setDynamicProperty(key, Date.now());
    }
    /**
     * End overall timing and record completion
     */
    static endOverallTimer(player) {
        const key = `overall_timer_${player.name}`;
        const startTime = world.getDynamicProperty(key);
        if (!startTime) {
            console.warn(`No overall timer found for player ${player.name}`);
            return null;
        }
        const completionTime = Date.now() - startTime;
        // Clear the timer
        world.setDynamicProperty(key, undefined);
        // Update the player's stats
        statsDb.updateOverallCompletion(player.name, completionTime);
        return completionTime;
    }
    /**
     * Use a checkpoint (increment counter)
     */
    static useCheckpoint(player) {
        statsDb.incrementCheckpointUsage(player.name);
        // Optional: Show message to player
        player.sendMessage(`§6Checkpoint used! Total checkpoints: §e${this.getCheckpointCount(player)}`);
    }
    /**
     * Get current checkpoint count for a player
     */
    static getCheckpointCount(player) {
        const stats = statsDb.loadPlayerStats(player.name);
        return stats ? stats.checkpointsUsed : 0;
    }
    /**
     * Get player's best time for a specific grid
     */
    static getPersonalBest(player, gridId) {
        const stats = statsDb.loadPlayerStats(player.name);
        return stats ? (stats.personalBests[gridId] || null) : null;
    }
    /**
     * Get player's overall best completion time
     */
    static getBestCompletionTime(player) {
        const stats = statsDb.loadPlayerStats(player.name);
        return stats ? stats.bestCompletionTime : null;
    }
    /**
     * Format time in a readable way (mm:ss.sss)
     */
    static formatTime(milliseconds) {
        const totalSeconds = Math.floor(milliseconds / 1000);
        const minutes = Math.floor(totalSeconds / 60);
        const seconds = totalSeconds % 60;
        const ms = milliseconds % 1000;
        return `${minutes}:${seconds.toString().padStart(2, '0')}.${ms.toString().padStart(3, '0')}`;
    }
    /**
     * Show player statistics to the player
     */
    static showPlayerStats(player) {
        const stats = statsDb.loadPlayerStats(player.name);
        if (!stats) {
            player.sendMessage("§cFailed to load your statistics!");
            return;
        }
        const messages = [
            "§6=== Your Parkour Statistics ===",
            `§bTotal Play Time: §f${this.formatTime(stats.totalPlayTime)}`,
            `§bCheckpoints Used: §f${stats.checkpointsUsed}`,
            `§bMap Completions: §f${stats.completionCount}`,
            `§bBest Overall Time: §f${stats.bestCompletionTime ? this.formatTime(stats.bestCompletionTime) : 'Not completed yet'}`,
            "§6=== Grid Times ===",
        ];
        // Add grid-specific times
        for (const [gridId, time] of Object.entries(stats.personalBests)) {
            messages.push(`§bGrid ${gridId}: §f${this.formatTime(time)}`);
        }
        // Send messages to player
        messages.forEach(msg => player.sendMessage(msg));
    }
    /**
     * Show leaderboard to a player
     */
    static showLeaderboard(player, metric = 'bestCompletionTime', limit = 10) {
        const leaderboard = statsDb.getLeaderboard(metric, limit);
        if (leaderboard.length === 0) {
            player.sendMessage("§cNo leaderboard data available yet!");
            return;
        }
        const title = metric === 'bestCompletionTime' ? 'Best Times' :
            metric === 'completionCount' ? 'Most Completions' : 'Most Play Time';
        const messages = [`§6=== Leaderboard: ${title} ===`];
        leaderboard.forEach((entry, index) => {
            const position = index + 1;
            const value = metric === 'bestCompletionTime' ? this.formatTime(entry.value) :
                metric === 'totalPlayTime' ? this.formatTime(entry.value) :
                    entry.value.toString();
            messages.push(`§e${position}. §b${entry.username}: §f${value}`);
        });
        messages.forEach(msg => player.sendMessage(msg));
    }
    /**
     * Reset player statistics (admin function)
     */
    static resetPlayerStats(playerName) {
        return statsDb.deletePlayerStats(playerName);
    }
    /**
     * Get total number of players in database
     */
    static getTotalPlayers() {
        return statsDb.getAllPlayerStats().length;
    }
    /**
     * Export player data as JSON string (for backups)
     */
    static exportPlayerData(playerName) {
        const stats = statsDb.loadPlayerStats(playerName);
        return stats ? JSON.stringify(stats, null, 2) : null;
    }
    /**
     * Import player data from JSON string (for restores)
     */
    static importPlayerData(jsonData) {
        try {
            const stats = JSON.parse(jsonData);
            return statsDb.savePlayerStats(stats);
        }
        catch (error) {
            console.error(`Failed to import player data: ${error}`);
            return false;
        }
    }
    /**
     * Check if a player has completed a specific grid
     */
    static hasCompletedGrid(player, gridId) {
        const stats = statsDb.loadPlayerStats(player.name);
        return stats ? (gridId in stats.gridTimes) : false;
    }
    /**
     * Get completion percentage (completed grids / total grids)
     */
    static getCompletionPercentage(player, totalGrids) {
        const stats = statsDb.loadPlayerStats(player.name);
        if (!stats)
            return 0;
        const completedGrids = Object.keys(stats.gridTimes).length;
        return totalGrids > 0 ? Math.round((completedGrids / totalGrids) * 100) : 0;
    }
    /**
     * Get average grid completion time
     */
    static getAverageGridTime(player) {
        const stats = statsDb.loadPlayerStats(player.name);
        if (!stats)
            return null;
        const times = Object.values(stats.gridTimes);
        if (times.length === 0)
            return null;
        const total = times.reduce((sum, time) => sum + time, 0);
        return total / times.length;
    }
}
// Example command handlers (you can integrate these with your command system)
export function handleStatsCommand(player, args) {
    if (args.length === 0) {
        StatsUtils.showPlayerStats(player);
        return;
    }
    const subCommand = args[0].toLowerCase();
    switch (subCommand) {
        case 'leaderboard':
        case 'lb':
            const metric = args[1] || 'bestCompletionTime';
            const limit = parseInt(args[2]) || 10;
            StatsUtils.showLeaderboard(player, metric, limit);
            break;
        case 'reset':
            if (args[1]) {
                StatsUtils.resetPlayerStats(args[1]);
                player.sendMessage(`§aReset statistics for ${args[1]}`);
            }
            else {
                StatsUtils.resetPlayerStats(player.name);
                player.sendMessage("§aYour statistics have been reset!");
            }
            break;
        case 'export':
            const exportData = StatsUtils.exportPlayerData(player.name);
            if (exportData) {
                // In a real implementation, you might want to save this to a file or send to admin
                player.sendMessage("§aData exported successfully! (Check console)");
                console.log(`Export data for ${player.name}:`, exportData);
            }
            else {
                player.sendMessage("§cFailed to export data!");
            }
            break;
        default:
            player.sendMessage("§cUsage: /stats [leaderboard|reset|export]");
    }
}
