import { world, system } from '@minecraft/server';
import { PlayerData } from './Handler/PlayerData';
import { AreaData } from './Handler/AreaData';
import { AreaUI } from './Handler/AreaUI';
import { TimeTracker } from './Handler/TimeTracker';
import { TimeTrackerUI } from './Handler/TimeTrackerUI';
import { LeaderboardHologram } from './Handler/LeaderboardHologram';
import { ItemHandler } from './Handler/ItemHandler';
import { SettingsManager } from './Handler/SettingsManager';
import { SettingsUI } from './Handler/SettingsUI';
// Create global instances
export const playerData = new PlayerData();
export const areaData = new AreaData();
export const areaUI = new AreaUI(areaData);
export const timeTracker = new TimeTracker(areaData);
export const timeTrackerUI = new TimeTrackerUI(timeTracker);
export const leaderboardHologram = new LeaderboardHologram(timeTracker);
export const settingsManager = new SettingsManager();
export const settingsUI = new SettingsUI(settingsManager);
export const itemHandler = new ItemHandler(timeTracker, timeTrackerUI, areaData, settingsManager, settingsUI);
// Function to create all required scoreboards
function createScoreboards(player) {
    let createdCount = 0;
    let existedCount = 0;
    // Note: area_data_db is no longer used - areas are hardcoded in AreaData.ts
    // Create player data scoreboard
    try {
        const playerDataObjective = world.scoreboard.getObjective("player_data_db");
        if (playerDataObjective) {
            existedCount++;
        }
        else {
            world.scoreboard.addObjective("player_data_db", "Player Data DB");
            createdCount++;
            player.sendMessage("§aCreated player_data_db scoreboard");
        }
    }
    catch (error) {
    }
    // Create time tracker scoreboard
    try {
        const timeTrackerObjective = world.scoreboard.getObjective("time_tracker_db");
        if (timeTrackerObjective) {
            existedCount++;
        }
        else {
            world.scoreboard.addObjective("time_tracker_db", "Time Tracker DB");
            createdCount++;
            player.sendMessage("§aCreated time_tracker_db scoreboard");
        }
    }
    catch (error) {
    }
    // Create leaderboard scoreboard
    try {
        const leaderboardObjective = world.scoreboard.getObjective("leaderboard_db");
        if (leaderboardObjective) {
            existedCount++;
        }
        else {
            world.scoreboard.addObjective("leaderboard_db", "Leaderboard DB");
            createdCount++;
            player.sendMessage("§aCreated leaderboard_db scoreboard");
        }
    }
    catch (error) {
    }
    player.sendMessage(`§eScoreboard setup complete: §a${createdCount} created§e, §7${existedCount} already existed`);
}
// Function to silently ensure scoreboards exist (used internally)
function ensureScoreboards() {
    // Note: area_data_db is no longer used - areas are hardcoded in AreaData.ts
    // Create player data scoreboard if it doesn't exist
    try {
        world.scoreboard.getObjective("player_data_db");
    }
    catch (error) {
        try {
            world.scoreboard.addObjective("player_data_db", "Player Data DB");
        }
        catch (createError) {
            // Failed to create scoreboard
        }
    }
}
// Function to teleport player to checkpoint of current zone
function teleportToCheckpoint(player) {
    const playerPos = player.location;
    // Use AreaData class to find current area
    const currentArea = areaData.getAreaByPosition(playerPos);
    if (!currentArea) {
        player.sendMessage("§cYou are not inside any zone!");
        return;
    }
    // Check if the area has a checkpoint
    if (!currentArea.data.checkpoint) {
        player.sendMessage(`§cZone "${currentArea.data.name}" does not have a checkpoint!`);
        return;
    }
    // Teleport player to the checkpoint
    const checkpoint = currentArea.data.checkpoint;
    try {
        player.teleport({ x: checkpoint.x + 0.5, y: checkpoint.y, z: checkpoint.z + 0.5 }, { rotation: { x: checkpoint.pitch, y: checkpoint.yaw } });
        player.sendMessage(`§aTeleported to checkpoint in zone "${currentArea.data.name}"!`);
    }
    catch (error) {
        player.sendMessage("§cFailed to teleport to checkpoint!");
        console.error(`Teleport error: ${error}`);
    }
}
// Function to show delete area confirmation
function showDeleteAreaConfirmation(player) {
    const playerPos = player.location;
    // Use AreaData class to find current area
    const currentArea = areaData.getAreaByPosition(playerPos);
    if (!currentArea) {
        player.sendMessage("§cYou are not inside any zone!");
        return;
    }
    // Show confirmation UI
    areaUI.showDeleteConfirmation(player, currentArea);
}
// Custom command registration and handling
system.beforeEvents.startup.subscribe((startupEvent) => {
    // Reset command - clears all player data and world data
    startupEvent.customCommandRegistry.registerCommand({ name: "mbl:reset", description: "Reset all player data and world data", permissionLevel: 0 }, (origin, ...args) => {
        const players = world.getPlayers();
        if (players.length === 0)
            return { status: 0 };
        const player = players[0];
        system.run(() => {
            try {
                let cleared = 0;
                // Clear all player settings
                for (const p of world.getAllPlayers()) {
                    try {
                        p.setDynamicProperty('player_settings', undefined);
                    }
                    catch { }
                }
                // Clear player_data_db scoreboard
                try {
                    const playerDataObj = world.scoreboard.getObjective("player_data_db");
                    if (playerDataObj) {
                        world.scoreboard.removeObjective(playerDataObj);
                        cleared++;
                    }
                }
                catch { }
                // Clear area_data_db scoreboard
                try {
                    const areaDataObj = world.scoreboard.getObjective("area_data_db");
                    if (areaDataObj) {
                        world.scoreboard.removeObjective(areaDataObj);
                        cleared++;
                    }
                }
                catch { }
                // Clear leaderboard_db scoreboard
                try {
                    const leaderboardObj = world.scoreboard.getObjective("leaderboard_db");
                    if (leaderboardObj) {
                        world.scoreboard.removeObjective(leaderboardObj);
                        cleared++;
                    }
                }
                catch { }
                // Clear time_tracker_db scoreboard
                try {
                    const timeTrackerObj = world.scoreboard.getObjective("time_tracker_db");
                    if (timeTrackerObj) {
                        world.scoreboard.removeObjective(timeTrackerObj);
                        cleared++;
                    }
                }
                catch { }
                // Clear any active runs in memory
                timeTracker.clearAllRuns();
                // Update all leaderboards to show empty state
                leaderboardHologram.updateAllLeaderboards();
                player.sendMessage(`§aReset complete! Cleared ${cleared} scoreboard databases and all player settings.`);
                player.sendMessage("§eAll player data, times, and settings have been reset.");
                player.sendMessage("§eLeaderboards have been refreshed.");
            }
            catch (error) {
                player.sendMessage("§cFailed to reset data!");
            }
        });
        return { status: 1 };
    });
    // Checkpoint teleport command
    startupEvent.customCommandRegistry.registerCommand({ name: "mbl:checkpoint", description: "Teleport to checkpoint of current zone", permissionLevel: 0 }, (origin, ...args) => {
        const players = world.getPlayers();
        if (players.length === 0)
            return { status: 0 };
        const player = players[0];
        system.run(() => {
            teleportToCheckpoint(player);
        });
        return { status: 1 };
    });
    // Exit command - teleport to world spawn
    startupEvent.customCommandRegistry.registerCommand({ name: "mbl:exit", description: "Return to world spawn", permissionLevel: 0 }, (origin, ...args) => {
        const players = world.getPlayers();
        if (players.length === 0)
            return { status: 0 };
        const player = players[0];
        system.run(() => {
            try {
                player.teleport({ x: 5, y: 20, z: 320 }, { dimension: player.dimension });
                player.sendMessage("§aTeleported to spawn!");
            }
            catch (error) {
                player.sendMessage("§cFailed to teleport!");
            }
        });
        return { status: 1 };
    });
    // Player stats command
    startupEvent.customCommandRegistry.registerCommand({ name: "mbl:stats", description: "View your personal statistics", permissionLevel: 0 }, (origin, ...args) => {
        const players = world.getPlayers();
        if (players.length === 0)
            return { status: 0 };
        const player = players[0];
        system.run(() => {
            timeTrackerUI.showPlayerStats(player);
        });
        return { status: 1 };
    });
});
// Apply ghost mode effects every second for players with it enabled
system.runInterval(() => {
    for (const player of world.getAllPlayers()) {
        const settings = settingsManager.getSettings(player);
        if (settings.ghostMode) {
            // Check if player is in a parkour area (not spawn/lobby area)
            const currentArea = areaData.getAreaByPosition(player.location);
            const shouldApplyEffect = currentArea ? !currentArea.data.isStartingArea : false;
            // Only apply the visual effect if in a parkour area
            if (shouldApplyEffect) {
                settingsManager.applyGhostMode(player, true);
            }
        }
    }
}, 20); // Run every second
// Apply resistance effects to all players to prevent death
system.runInterval(() => {
    for (const player of world.getAllPlayers()) {
        try {
            // Give resistance 255 (invulnerability) with no particles
            player.runCommand('effect @s resistance 999999 255 true');
            // Give fire resistance with no particles
            player.runCommand('effect @s fire_resistance 999999 1 true');
        }
        catch (error) {
            // Silently fail if command doesn't work
        }
    }
}, 100); // Run every 5 seconds (100 ticks)
