import { world, system, ItemStack } from '@minecraft/server';

// Mystical Amulet System - Enhanced Version with Particles & Special Effects
const MYSTICAL_SLOTS = [
    { slot: 'mystical_slot_1', index: 0, name: 'Mystical Slot I' },
    { slot: 'mystical_slot_2', index: 1, name: 'Mystical Slot II' }
];

// Rarity levels for visual effects
const RARITY = {
    COMMON: { color: '§7', particle: null },
    UNCOMMON: { color: '§a', particle: null },
    RARE: { color: '§9', particle: 'myw:mythril_particle_minimalist' },
    EPIC: { color: '§5', particle: 'myw:mythril_particle' },
    LEGENDARY: { color: '§6', particle: 'myw:mythril_flight_particle' }
};

// Enhanced mystical amulets with special abilities
const MYSTICAL_AMULETS = [
    {
        identifier: 'myw:basic_power_amulet',
        slot: 'mystical_slot_1',
        name: 'Basic Power Amulet',
        rarity: RARITY.COMMON,
        effects: [
            { type: 'strength', level: 1, duration: 120 }
        ],
        stats: {
            mystical_power: 2
        },
        specialAbility: null
    },
    {
        identifier: 'myw:basic_defense_amulet',
        slot: 'mystical_slot_2',
        name: 'Basic Defense Amulet',
        rarity: RARITY.COMMON,
        effects: [
            { type: 'resistance', level: 1, duration: 120 }
        ],
        stats: {
            mystical_defense: 2
        },
        specialAbility: null
    },
    {
        identifier: 'myw:basic_defense_amulet_upgraded',
        slot: 'mystical_slot_2',
        name: 'Enhanced Defense Amulet',
        rarity: RARITY.RARE,
        effects: [
            { type: 'resistance', level: 2, duration: 120 },
            { type: 'fire_resistance', level: 1, duration: 120 },
            { type: 'absorption', level: 1, duration: 120 }
        ],
        stats: {
            mystical_defense: 5,
            mystical_vitality: 2
        },
        specialAbility: 'shield_burst' // Special defensive burst
    },
    {
        identifier: 'myw:ancient_mythril_vitality_amulet',
        slot: 'mystical_slot_1',
        name: 'Ancient Mythril Vitality Amulet',
        rarity: RARITY.LEGENDARY,
        effects: [
            { type: 'regeneration', level: 2, duration: 120 },
            { type: 'health_boost', level: 3, duration: 120 },
            { type: 'saturation', level: 1, duration: 120 },
            { type: 'resistance', level: 1, duration: 120 }
        ],
        stats: {
            mystical_vitality: 10,
            mystical_power: 3,
            mystical_defense: 3
        },
        specialAbility: 'life_aura' // Continuous healing aura
    },
    {
        identifier: 'myw:mythril_boots',
        slot: 'mystical_slot_1',
        name: 'Mythril Boots of Swiftness',
        rarity: RARITY.EPIC,
        effects: [
            { type: 'speed', level: 2, duration: 120 },
            { type: 'jump_boost', level: 2, duration: 120 }
        ],
        stats: {
            mystical_speed: 5,
            mystical_power: 3
        },
        specialAbility: 'swift_dash' // Enhanced movement
    }
];

// Player data tracking
const lastAmuletPos = new Map();
const lastHeldItemType = new Map();
const playerAbilityData = new Map(); // For special abilities cooldowns and effects
const particleTimers = new Map(); // For particle effects

/**
 * Get the mystical amulet manager entity for a player
 */
function getAmuletEntity(player) {
    const entities = player.dimension.getEntities({
        tags: [`mystical_amulet_${player.id}`]
    });
    return entities[0];
}

/**
 * Summon a new mystical amulet manager entity
 */
function summonAmuletEntity(player) {
    try {
        let entity = player.dimension.spawnEntity('myw:mystical_amulet_manager', player.location);
        entity.addTag(`mystical_amulet_${player.id}`);
        entity.getComponent('minecraft:tameable').tame(player);
        entity.nameTag = "mystical amulets"; // ← DEBE SER EXACTAMENTE ASÍ (minúsculas, sin formato)
        return entity;
    } catch (error) {
        console.warn(`[Mystical] Failed to spawn amulet entity for ${player.name}:`, error);
        return null;
    }
}

/**
 * Load player's amulets into the entity inventory
 */
function loadEntityInv(player, entity) {
    const entityInv = entity.getComponent('inventory')?.container;
    if (!entityInv) return;

    const playerTags = player.getTags();

    MYSTICAL_SLOTS.forEach(slot => {
        const validTag = playerTags.find(tag => {
            if (!tag.endsWith(`_${slot.slot}`)) return false;
            const id = tag.slice(0, tag.length - (slot.slot.length + 1));
            return MYSTICAL_AMULETS.some(amulet => amulet.identifier === id && amulet.slot === slot.slot);
        });

        if (validTag) {
            const id = validTag.slice(0, validTag.length - (slot.slot.length + 1));
            try {
                const item = new ItemStack(id);
                entityInv.setItem(slot.index, item);
                console.warn(`[Mystical] Loaded ${id} into ${slot.slot} for ${player.name}`);
            } catch (error) {
                console.warn(`[Mystical] Failed to load item ${id}:`, error);
            }
        }
    });
}

/**
 * Convert mystical amulet to tag format
 */
function amuletToTag(amulet) {
    if (!amulet) return null;
    return `${amulet.identifier}_${amulet.slot}`;
}

/**
 * Get player's mystical stats
 */
function getMysticalStats(player) {
    const tags = player.getTags();
    const stats = {
        mystical_power: 0,
        mystical_defense: 0,
        mystical_speed: 0,
        mystical_vitality: 0
    };

    for (const tag of tags) {
        const amulet = MYSTICAL_AMULETS.find(a => tag === `${a.identifier}_${a.slot}`);
        if (!amulet || !amulet.stats) continue;

        // Apply amulet stats
        Object.keys(amulet.stats).forEach(stat => {
            if (stats.hasOwnProperty(stat)) {
                stats[stat] += amulet.stats[stat];
            }
        });
    }

    return stats;
}

/**
 * Spawn particle effect at player location
 */
function spawnParticleEffect(player, particleType) {
    if (!particleType) return;

    try {
        const loc = player.location;
        const dimension = player.dimension;

        // Spawn particle at player center
        const particleLoc = {
            x: loc.x,
            y: loc.y + 1,
            z: loc.z
        };

        dimension.spawnParticle(particleType, particleLoc);
    } catch (error) {
        // Silently fail if particle doesn't exist
    }
}

/**
 * Get current tick count for timing
 */
let globalTickCounter = 0;

/**
 * Apply special ability effects (FIXED VERSION)
 */
function applySpecialAbility(player, ability) {
    if (!ability) return;

    const playerId = player.id;
    let abilityData = playerAbilityData.get(playerId);

    // Initialize ability data if doesn't exist
    if (!abilityData) {
        abilityData = {
            shieldBurstLastTick: 0,
            lifeAuraLastTick: 0,
            swiftDashLastTick: 0
        };
        playerAbilityData.set(playerId, abilityData);
    }

    const currentTick = globalTickCounter;

    switch (ability) {
        case 'shield_burst':
            // Every 10 seconds (200 ticks), create a defensive burst
            const shieldBurstCooldown = 200; // 10 seconds

            if (currentTick - abilityData.shieldBurstLastTick >= shieldBurstCooldown) {
                try {
                    player.addEffect('absorption', 200, { amplifier: 2, showParticles: true });
                    spawnParticleEffect(player, 'minecraft:crop_growth_emitter');
                    player.sendMessage('§9§l⚡ Shield Burst activated!');
                    player.playSound('random.orb', { pitch: 1.5, volume: 0.7 });
                    abilityData.shieldBurstLastTick = currentTick;
                    console.warn(`[Mystical] Shield Burst activated for ${player.name}`);
                } catch (error) {
                    console.warn(`[Mystical] Shield Burst error:`, error);
                }
            }
            break;

        case 'life_aura':
            // Every 2 seconds (40 ticks), heal nearby players
            const lifeAuraCooldown = 40; // 2 seconds

            if (currentTick - abilityData.lifeAuraLastTick >= lifeAuraCooldown) {
                try {
                    // Heal nearby players
                    const nearbyPlayers = player.dimension.getPlayers({
                        location: player.location,
                        maxDistance: 5
                    });

                    let healed = 0;
                    nearbyPlayers.forEach(p => {
                        p.addEffect('regeneration', 60, { amplifier: 1, showParticles: false });
                        healed++;
                    });

                    spawnParticleEffect(player, 'myw:mythril_flight_particle');

                    if (healed > 1) {
                        player.sendMessage(`§c❤ Life Aura healed ${healed} players`);
                    }

                    abilityData.lifeAuraLastTick = currentTick;
                } catch (error) {
                    console.warn(`[Mystical] Life Aura error:`, error);
                }
            }
            break;

        case 'swift_dash':
            // Every 0.5 seconds (10 ticks), spawn trail particles
            const swiftDashCooldown = 10; // 0.5 seconds

            if (currentTick - abilityData.swiftDashLastTick >= swiftDashCooldown) {
                spawnParticleEffect(player, 'myw:mythril_particle');
                abilityData.swiftDashLastTick = currentTick;
            }
            break;
    }
}

/**
 * Apply mystical effects to player (enhanced version)
 */
function applyMysticalEffects(player) {
    const tags = player.getTags();
    let effectsApplied = 0;
    let highestRarity = null;

    for (const tag of tags) {
        const amulet = MYSTICAL_AMULETS.find(a => tag === `${a.identifier}_${a.slot}`);
        if (!amulet) continue;

        // Track highest rarity for particle effects
        if (!highestRarity || amulet.rarity.particle) {
            highestRarity = amulet.rarity;
        }

        // Apply all effects from the amulet
        if (amulet.effects && amulet.effects.length > 0) {
            amulet.effects.forEach(effect => {
                try {
                    player.addEffect(effect.type, effect.duration, {
                        amplifier: effect.level,
                        showParticles: false
                    });
                    effectsApplied++;
                } catch (error) {
                    console.warn(`[Mystical] Failed to apply effect ${effect.type}:`, error);
                }
            });
        }

        // Apply special abilities
        if (amulet.specialAbility) {
            applySpecialAbility(player, amulet.specialAbility);
        }
    }

    // Spawn rarity particles
    if (highestRarity && highestRarity.particle) {
        const playerId = player.id;
        const timer = particleTimers.get(playerId) || 0;

        if (timer <= 0) {
            spawnParticleEffect(player, highestRarity.particle);
            particleTimers.set(playerId, 20); // Every second
        } else {
            particleTimers.set(playerId, timer - 1);
        }
    }
}

/**
 * Show mystical stats with enhanced formatting
 */
function showMysticalStats(player) {
    const stats = getMysticalStats(player);
    const equippedAmulets = player.getTags()
        .map(tag => MYSTICAL_AMULETS.find(a => tag === `${a.identifier}_${a.slot}`))
        .filter(a => a !== undefined);

    if (equippedAmulets.length > 0) {
        // Build stats message
        let message = `§5§l╔══════ MYSTICAL STATS ══════╗\n`;

        if (stats.mystical_power > 0) message += `§7│ §6⚔ Power: §e${stats.mystical_power}\n`;
        if (stats.mystical_defense > 0) message += `§7│ §9🛡 Defense: §b${stats.mystical_defense}\n`;
        if (stats.mystical_speed > 0) message += `§7│ §a⚡ Speed: §e${stats.mystical_speed}\n`;
        if (stats.mystical_vitality > 0) message += `§7│ §c❤ Vitality: §e${stats.mystical_vitality}\n`;

        message += `§5§l╚═════════════════════════╝`;

        player.sendMessage(message);

        // Show equipped amulets
        equippedAmulets.forEach(amulet => {
            const abilityText = amulet.specialAbility ? ` §8[${amulet.specialAbility}]` : '';
            player.sendMessage(`${amulet.rarity.color}✦ ${amulet.name}${abilityText}`);
        });

        // Play enhanced sound
        player.playSound('random.levelup', { pitch: 1.5, volume: 0.5 });
    }
}

/**
 * Handle amulet equipping/unequipping (enhanced)
 */
function handleAmuletChange(player, slot, slotIndex) {
    const amuletInv = player.dimension.getEntities({
        tags: [`mystical_amulet_${player.id}`]
    })[0];

    if (!amuletInv) return;

    const entityInv = amuletInv.getComponent('inventory')?.container;
    const playerInv = player.getComponent('inventory')?.container;
    if (!entityInv || !playerInv) return;

    const invSlot = entityInv.getSlot(slotIndex);
    const entityItem = invSlot.getItem();

    if (!entityItem) {
        // Remove amulet
        const tag = player.getTags().find(tag =>
            MYSTICAL_AMULETS.some(a => tag === `${a.identifier}_${a.slot}` && a.slot === slot)
        );

        if (tag) {
            const amuletId = tag.slice(0, tag.length - (slot.length + 1));
            const amulet = MYSTICAL_AMULETS.find(a => a.identifier === amuletId);

            player.removeTag(tag);
            player.removeTag(amuletId);

            // Reset ability data when unequipping
            if (amulet && amulet.specialAbility) {
                const abilityData = playerAbilityData.get(player.id);
                if (abilityData) {
                    if (amulet.specialAbility === 'shield_burst') abilityData.shieldBurstLastTick = 0;
                    if (amulet.specialAbility === 'life_aura') abilityData.lifeAuraLastTick = 0;
                    if (amulet.specialAbility === 'swift_dash') abilityData.swiftDashLastTick = 0;
                }
            }

            console.warn(`[Mystical] Unequipped ${amuletId} from ${slot}`);

            if (amulet) {
                player.sendMessage(`${amulet.rarity.color}§l✖ Unequipped: §r${amulet.rarity.color}${amulet.name}`);
                player.playSound('random.break', { pitch: 0.8 });
            }

            applyMysticalEffects(player);
            showMysticalStats(player);
        }
        return;
    }

    // Check if item is a valid mystical amulet
    const amulet = MYSTICAL_AMULETS.find(a => a.identifier === entityItem.typeId);

    if (amulet && amulet.slot === slot) {
        const currentTag = player.getTags().find(tag =>
            tag.endsWith(`_${slot}`) &&
            MYSTICAL_AMULETS.some(a => tag === `${a.identifier}_${a.slot}`)
        );

        const newTag = amuletToTag(amulet);

        if (currentTag !== newTag) {
            // Remove old tags
            if (currentTag) {
                const oldId = currentTag.slice(0, currentTag.length - (slot.length + 1));
                player.removeTag(currentTag);
                player.removeTag(oldId);
            }

            if (newTag) {
                const amuletId = newTag.slice(0, newTag.length - (slot.length + 1));
                player.addTag(newTag);
                player.addTag(amuletId);

                console.warn(`[Mystical] Equipped ${amuletId} in ${slot}`);

                // Enhanced equip message with rarity
                let equipMessage = `${amulet.rarity.color}§l✦ EQUIPPED §r${amulet.rarity.color}${amulet.name}`;
                if (amulet.specialAbility) {
                    equipMessage += `\n§8└─ Special: §7${amulet.specialAbility}`;
                }
                player.sendMessage(equipMessage);

                // Spawn equip particles
                if (amulet.rarity.particle) {
                    for (let i = 0; i < 5; i++) {
                        system.runTimeout(() => {
                            spawnParticleEffect(player, amulet.rarity.particle);
                        }, i * 2);
                    }
                }

                // Enhanced sound based on rarity
                const pitch = amulet.rarity === RARITY.LEGENDARY ? 2.0 :
                    amulet.rarity === RARITY.EPIC ? 1.7 :
                        amulet.rarity === RARITY.RARE ? 1.4 : 1.2;
                player.playSound('random.orb', { pitch: pitch });

                // Apply effects immediately
                applyMysticalEffects(player);

                // Show stats after a brief delay
                system.runTimeout(() => {
                    showMysticalStats(player);
                }, 20);
            }
        }
    } else {
        // Invalid item for this slot
        console.warn(`[Mystical] Invalid item ${entityItem.typeId} for slot ${slot}`);
        entityInv.setItem(slotIndex);
        if (playerInv.emptySlotsCount === 0) {
            player.dimension.spawnItem(entityItem, player.location);
        } else {
            playerInv.addItem(entityItem);
        }

        player.sendMessage(`§c§l✖ ERROR: §cThis item cannot be placed in ${slot.replace('mystical_slot_', 'Mystical Slot ')}`);
        player.playSound('note.bass', { pitch: 0.5 });
    }
}

/**
 * Register the amulets bag and mystical amulets custom components
 */
export function registerAmuletsBag(itemComponentRegistry) {
    itemComponentRegistry.registerCustomComponent('myw:amulets_bag', {
        onUse(eventData) {
            const { source: player } = eventData;
            player.sendMessage("§5§l✦ MYSTICAL AMULETS ✦\n§7Hold the bag to access your mystical slots!");
            player.playSound("item.book.page_turn");
        }
    });

    // Register all amulet components
    const amuletComponents = [
        'basic_power_amulet',
        'basic_defense_amulet',
        'basic_defense_amulet_upgraded',
        'ancient_mythril_vitality_amulet'
    ];

    amuletComponents.forEach(componentName => {
        itemComponentRegistry.registerCustomComponent(`myw:${componentName}`, {
            onUse(eventData) {
                const { source: player } = eventData;
                const amulet = MYSTICAL_AMULETS.find(a => a.identifier === `myw:${componentName}`);
                if (amulet) {
                    player.sendMessage(`${amulet.rarity.color}§l${amulet.name}\n§7Use the Mystical Amulets Bag to equip!`);
                    player.playSound('random.orb');
                }
            }
        });
    });
}

/**
 * Initialize the mystical amulet system
 */
export function initializeMysticalAmuletSystem() {
    console.warn('[Mystical] §5✦ Initializing Enhanced Mystical Amulet System...');

    // Give mystical bag to new players
    world.afterEvents.playerSpawn.subscribe((ev) => {
        const { player, initialSpawn } = ev;
        if (player.hasTag("mystical_amulet_init")) return;
        player.addTag("mystical_amulet_init");

        let mysticalBag = new ItemStack("myw:amulets_bag", 1);
        mysticalBag.keepOnDeath = true;
        let inventory = player.getComponent("minecraft:inventory").container;
        inventory.addItem(mysticalBag);

        player.sendMessage("§5§l✦══════════════════✦\n§5§lMYSTICAL AMULETS\n§7You received a Mystical Amulets Bag!\n§5§l✦══════════════════✦");
        player.playSound('random.levelup');
        console.warn(`[Mystical] Gave amulets bag to ${player.name}`);
    });

    // Main system loop
    system.runInterval(() => {
        for (const player of world.getPlayers()) {
            const equip = player.getComponent("equippable");
            const inventory = player.getComponent("inventory")?.container;
            if (!equip || !inventory) continue;

            const mainHand = equip.getEquipment("Mainhand");
            const currentType = mainHand?.typeId ?? null;
            const previousType = lastHeldItemType.get(player.id);

            // Handle item locking for mystical bag
            if (previousType && previousType !== currentType && previousType === "myw:amulets_bag") {
                for (let i = 0; i < inventory.size; i++) {
                    const item = inventory.getItem(i);
                    if (item && item.typeId === previousType) {
                        item.lockMode = "none";
                        item.keepOnDeath = true;
                        inventory.setItem(i, item);
                    }
                }
            }

            lastHeldItemType.set(player.id, currentType);
            const slot = player.selectedSlotIndex;

            // Only show mystical amulet manager when holding the bag
            if (!mainHand || currentType !== "myw:amulets_bag") {
                getAmuletEntity(player)?.remove();
                continue;
            }

            // Lock the mystical bag in slot
            system.runTimeout(() => {
                const current = equip.getEquipment("Mainhand");
                if (current?.typeId === currentType) {
                    current.lockMode = "slot";
                    current.keepOnDeath = true;
                    inventory.setItem(slot, current);
                } else {
                    for (let i = 0; i < inventory.size; i++) {
                        const item = inventory.getItem(i);
                        if (item?.typeId === currentType) {
                            item.lockMode = "none";
                            item.keepOnDeath = true;
                            inventory.setItem(i, item);
                        }
                    }
                }
            }, 1);

            // Get or create amulet manager entity
            let amuletInv = getAmuletEntity(player);
            if (!amuletInv) {
                amuletInv = summonAmuletEntity(player);
                if (!amuletInv) continue;
            }

            // Load amulets into entity inventory if not loaded
            if (!amuletInv.getTags().includes("myw:amuletsLoaded")) {
                loadEntityInv(player, amuletInv);
                amuletInv.addTag("myw:amuletsLoaded");
            }

            // Position the entity near player
            const head = player.getHeadLocation();
            const view = player.getViewDirection();
            const newPos = {
                x: head.x + view.x * 0.5,
                y: head.y + view.y * 0.5,
                z: head.z + view.z * 0.5
            };

            const key = player.id;
            const lastPos = lastAmuletPos.get(key);
            const distance = (a, b) => Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2 + (a.z - b.z) ** 2);

            if (!lastPos || distance(newPos, lastPos) > 0.4) {
                amuletInv.teleport(newPos, { dimension: player.dimension });
                lastAmuletPos.set(key, newPos);
            }

            // Check for amulet changes
            if (!player.hasTag("myw:amuletChecked")) {
                for (const slotData of MYSTICAL_SLOTS) {
                    handleAmuletChange(player, slotData.slot, slotData.index);
                }
                player.addTag("myw:amuletChecked");
                system.runTimeout(() => player.removeTag("myw:amuletChecked"), 1);
            }
        }
    }, 10);

    // Global tick counter for ability cooldowns
    system.runInterval(() => {
        globalTickCounter++;
    }, 1);

    // Apply mystical effects periodically (every 5 seconds)
    system.runInterval(() => {
        for (const player of world.getPlayers()) {
            applyMysticalEffects(player);
        }
    }, 100);

    world.sendMessage('§5§l✦ MYSTICAL AMULETS §r§5System initialized successfully! ✦');
    console.warn('[Mystical] §aSystem initialization complete!');
}

// Export the system components
export { MYSTICAL_SLOTS, MYSTICAL_AMULETS, getMysticalStats, showMysticalStats };