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

export const MythrilDustSystem = {

    config: {
        useCooldown: 60, // ticks (3 seconds) - increased cooldown for balance
        baseBoostPower: 2.2, // Reduced base upward velocity
        horizontalBoostPower: 1.2, // Reduced forward velocity
        blastRadius: 4.0, // Smaller damage radius
        damage: 6, // Reduced base damage to nearby enemies
        energyRadius: 5, // Smaller healing radius for allies
        mythrilBoostMultiplier: 1.5, // Reduced extra power with mythril armor
        particleCount: 50, // Fewer particles
        trailDuration: 80, // Shorter particle trail
        landingEffectRadius: 5,
        falldamageReduction: 0.7, // 70% fall damage reduction (not complete immunity)
        slowfallDuration: 200, // 10 seconds of slow fall (reduced from 15)
        shockwaveRadius: 6, // Smaller area of effect on launch
        maxLaunchHeight: 30 // Reduced maximum height boost
    },

    handleDustUse(player, itemStack) {
        try {
            // Check cooldown
            const lastUse = player.getDynamicProperty('myw:last_dust_use') || 0;
            const currentTime = Date.now();

            if (currentTime - lastUse < this.config.useCooldown * 50) {
                return false; // Silent cooldown
            }

            player.setDynamicProperty('myw:last_dust_use', currentTime);

            // Check mythril armor for bonuses
            const mythrilPower = this.getMythrilArmorCount(player);
            const hasFullSet = mythrilPower >= 4;

            // Apply balanced boost effect
            this.applyMythrilBoost(player, mythrilPower, hasFullSet);

            // Create visual and damage effects
            this.createBoostEffects(player, hasFullSet);

            // Create shockwave effect
            this.createLaunchShockwave(player, mythrilPower, hasFullSet);

            // Damage nearby enemies and heal allies
            this.handleNearbyEntities(player, mythrilPower, hasFullSet);

            // Consume item
            const inventory = player.getComponent('minecraft:inventory');
            if (inventory) {
                const selectedSlot = player.selectedSlotIndex;
                const item = inventory.container.getItem(selectedSlot);
                if (item && item.typeId === 'myw:mythril_dust' && item.amount > 1) {
                    inventory.container.setItem(selectedSlot, new ItemStack('myw:mythril_dust', item.amount - 1));
                } else {
                    inventory.container.setItem(selectedSlot, undefined);
                }
            }

            // Apply balanced fall protection
            this.applyFallProtection(player, mythrilPower);

            return true;

        } catch (error) {
            return false;
        }
    },

    applyMythrilBoost(player, mythrilPower, hasFullSet) {
        try {
            // Calculate balanced boost power based on mythril armor
            const basePower = this.config.baseBoostPower;
            const armorBonus = mythrilPower * 0.4; // Each armor piece adds 40% more power (reduced)
            const totalUpwardPower = basePower + armorBonus;

            // Get player's view direction for horizontal component
            const viewDirection = player.getViewDirection();

            // Calculate balanced velocities
            const upwardVelocity = totalUpwardPower * (hasFullSet ? this.config.mythrilBoostMultiplier : 1.0);
            const forwardPower = this.config.horizontalBoostPower * (hasFullSet ? 1.4 : 1.1);

            // Apply balanced boost
            const finalVelocity = {
                x: viewDirection.x * forwardPower,
                y: Math.min(upwardVelocity, 3.2), // Lower cap to prevent going too high
                z: viewDirection.z * forwardPower
            };

            // Apply the boost
            player.applyKnockback(
                finalVelocity.x,
                finalVelocity.z,
                Math.abs(finalVelocity.x) + Math.abs(finalVelocity.z),
                finalVelocity.y
            );

            // Add balanced speed effects
            if (hasFullSet) {
                player.addEffect('speed', 140, {
                    amplifier: 2, // Speed III (reduced from IV)
                    showParticles: false
                });
                player.addEffect('jump_boost', 140, {
                    amplifier: 2, // Jump Boost III (reduced from V)
                    showParticles: false
                });
                player.addEffect('resistance', 100, {
                    amplifier: 1, // Resistance II (reduced from III)
                    showParticles: false
                });
            } else if (mythrilPower >= 2) {
                player.addEffect('speed', 100, {
                    amplifier: 1, // Speed II (reduced from III)
                    showParticles: false
                });
                player.addEffect('jump_boost', 100, {
                    amplifier: 1, // Jump Boost II (reduced from III)
                    showParticles: false
                });
            }

            // Create particle trail
            this.createParticleTrail(player, hasFullSet);

        } catch (error) {
            // Error applying boost
        }
    },

    createParticleTrail(player, hasFullSet) {
        try {
            let trailTicks = 0;
            const maxTrailTicks = this.config.trailDuration;

            const trailInterval = system.runInterval(() => {
                try {
                    if (trailTicks >= maxTrailTicks || !player.isValid()) {
                        system.clearRun(trailInterval);
                        return;
                    }

                    const playerLocation = player.location;
                    const dimension = player.dimension;

                    // Create moderate trailing particles behind and around the player
                    const particleCount = hasFullSet ? 8 : 5; // Reduced particle count
                    for (let i = 0; i < particleCount; i++) {
                        const offset = {
                            x: (Math.random() - 0.5) * 2.5, // Smaller spread
                            y: Math.random() * -1.5,
                            z: (Math.random() - 0.5) * 2.5
                        };

                        const particleLocation = {
                            x: playerLocation.x + offset.x,
                            y: playerLocation.y + offset.y + 1,
                            z: playerLocation.z + offset.z
                        };

                        const particleType = hasFullSet ?
                            (Math.random() > 0.5 ? 'myw:mythril_particle_serpentine' : 'myw:mythril_particle') :
                            (Math.random() > 0.7 ? 'myw:mythril_particle' : 'myw:mythril_particle_minimalist');

                        dimension.spawnParticle(particleType, particleLocation);
                    }

                    // Create wind particles less frequently
                    if (trailTicks % 6 === 0) { // Reduced frequency
                        this.createWindParticles(dimension, playerLocation, hasFullSet);
                    }

                    // Create ascending particle spirals less frequently
                    if (hasFullSet && trailTicks % 15 === 0) { // Reduced frequency
                        this.createAscendingSpirals(dimension, playerLocation);
                    }

                    trailTicks++;

                } catch (error) {
                    system.clearRun(trailInterval);
                }
            }, 2); // Every 2 ticks instead of every tick

        } catch (error) {
            // Error creating trail
        }
    },

    createWindParticles(dimension, location, hasFullSet) {
        try {
            const windParticles = hasFullSet ? 10 : 6; // Reduced particles

            for (let i = 0; i < windParticles; i++) {
                const angle = (i / windParticles) * Math.PI * 2;
                const radius = 2 + Math.random() * 1.5; // Smaller radius

                const windLocation = {
                    x: location.x + Math.cos(angle) * radius,
                    y: location.y - 0.5 + Math.random() * 1.5,
                    z: location.z + Math.sin(angle) * radius
                };

                system.runTimeout(() => {
                    try {
                        const particleType = hasFullSet ? 'myw:mythril_particle_serpentine' : 'myw:mythril_particle';
                        dimension.spawnParticle(particleType, windLocation);
                    } catch (error) {
                        // Error with wind particles
                    }
                }, Math.random() * 20);
            }
        } catch (error) {
            // Error creating wind particles
        }
    },

    createAscendingSpirals(dimension, location) {
        try {
            // Create fewer spiraling particles
            for (let spiral = 0; spiral < 2; spiral++) { // Reduced from 3
                for (let i = 0; i < 6; i++) { // Reduced from 8
                    const angle = (i / 6) * Math.PI * 2 + (spiral * Math.PI * 0.66);
                    const radius = 2 - (spiral * 0.4);
                    const height = i * 0.3 + (spiral * 0.2);

                    const spiralLocation = {
                        x: location.x + Math.cos(angle) * radius,
                        y: location.y + height - 0.5,
                        z: location.z + Math.sin(angle) * radius
                    };

                    system.runTimeout(() => {
                        try {
                            dimension.spawnParticle('myw:mythril_particle_minimalist', spiralLocation);
                        } catch (error) {
                            // Error with spiral particles
                        }
                    }, i * 3 + spiral * 8);
                }
            }
        } catch (error) {
            // Error creating spirals
        }
    },

    createLaunchShockwave(player, mythrilPower, hasFullSet) {
        try {
            const location = player.location;
            const dimension = player.dimension;

            // Create smaller expanding shockwave rings
            for (let ring = 1; ring <= 3; ring++) { // Reduced from 5
                const ringRadius = ring * 1.5; // Smaller radius
                const particlesInRing = ring * 8; // Fewer particles
                const delay = ring * 6;

                system.runTimeout(() => {
                    try {
                        for (let i = 0; i < particlesInRing; i++) {
                            const angle = (i / particlesInRing) * Math.PI * 2;
                            const ringLocation = {
                                x: location.x + Math.cos(angle) * ringRadius,
                                y: location.y - 0.2,
                                z: location.z + Math.sin(angle) * ringRadius
                            };

                            const particleType = hasFullSet ? 'myw:mythril_particle_serpentine' : 'myw:mythril_particle';
                            dimension.spawnParticle(particleType, ringLocation);
                        }

                        // Create fewer upward bursts
                        for (let j = 0; j < 4; j++) { // Reduced from 8
                            const burstAngle = (j / 4) * Math.PI * 2;
                            const burstLocation = {
                                x: location.x + Math.cos(burstAngle) * ringRadius * 0.6,
                                y: location.y + Math.random() * 1.5,
                                z: location.z + Math.sin(burstAngle) * ringRadius * 0.6
                            };
                            dimension.spawnParticle('myw:mythril_particle', burstLocation);
                        }

                    } catch (error) {
                        // Error with shockwave particles
                    }
                }, delay);
            }

            // Sound effect for shockwave
            try {
                dimension.playSound('entity.breeze.wind_burst', location, {
                    volume: hasFullSet ? 1.0 : 0.7, // Reduced volume
                    pitch: 1.0
                });
            } catch (error) {
                // No sound available
            }

        } catch (error) {
            // Error creating shockwave
        }
    },

    createBoostEffects(player, hasFullSet) {
        try {
            const location = player.location;
            const dimension = player.dimension;

            // Balanced launch burst effect
            const burstParticles = hasFullSet ? this.config.particleCount * 1.2 : this.config.particleCount;

            for (let i = 0; i < burstParticles; i++) {
                const angle = (i / burstParticles) * Math.PI * 2;
                const elevation = Math.random() * Math.PI * 0.4; // Slightly less upward bias
                const distance = Math.random() * 2.5; // Smaller spread

                const particleLocation = {
                    x: location.x + Math.cos(angle) * Math.cos(elevation) * distance,
                    y: location.y + Math.sin(elevation) * distance - 0.3,
                    z: location.z + Math.sin(angle) * Math.cos(elevation) * distance
                };

                const delay = Math.random() * 12;
                system.runTimeout(() => {
                    try {
                        const particleType = hasFullSet ?
                            'myw:mythril_particle_serpentine' :
                            'myw:mythril_particle';
                        dimension.spawnParticle(particleType, particleLocation);
                    } catch (error) {
                        // Error with particles
                    }
                }, delay);
            }

            // Create ground impact effect
            this.createGroundImpactEffect(dimension, location, hasFullSet);

            // Sound effect
            try {
                dimension.playSound('entity.breeze.wind_burst', location, {
                    volume: hasFullSet ? 0.9 : 0.6,
                    pitch: hasFullSet ? 1.2 : 1.0
                });
            } catch (error) {
                // No sound available
            }

        } catch (error) {
            // Error creating boost effects
        }
    },

    createGroundImpactEffect(dimension, location, hasFullSet) {
        try {
            // Create smaller expanding ring effect on ground
            const groundY = Math.floor(location.y);

            for (let ring = 1; ring <= 2; ring++) { // Reduced from 3
                const radius = ring * 1.0; // Smaller radius
                const particlesInRing = ring * 4; // Fewer particles

                for (let i = 0; i < particlesInRing; i++) {
                    const angle = (i / particlesInRing) * Math.PI * 2;
                    const ringLocation = {
                        x: location.x + Math.cos(angle) * radius,
                        y: groundY + 0.1,
                        z: location.z + Math.sin(angle) * radius
                    };

                    system.runTimeout(() => {
                        try {
                            dimension.spawnParticle('myw:mythril_particle_minimalist', ringLocation);
                        } catch (error) {
                            // Error with ring particles
                        }
                    }, ring * 6);
                }
            }

        } catch (error) {
            // Error creating ground effect
        }
    },

    handleNearbyEntities(player, mythrilPower, hasFullSet) {
        try {
            const location = player.location;
            const dimension = player.dimension;
            const damageRadius = this.config.blastRadius;
            const healRadius = this.config.energyRadius;

            // Find nearby entities for damage
            const nearbyEntities = dimension.getEntities({
                location: location,
                maxDistance: Math.max(damageRadius, healRadius),
                excludeTypes: ['minecraft:item']
            });

            nearbyEntities.forEach(entity => {
                if (entity.id === player.id) return;

                const distance = this.getDistance(entity.location, location);

                // Damage hostile entities (balanced)
                if (distance <= damageRadius) {
                    if (this.isHostileEntity(entity)) {
                        const falloff = Math.max(0.4, 1 - (distance / damageRadius));
                        const baseDamage = this.config.damage;
                        const bonusDamage = mythrilPower * 0.3; // Reduced bonus
                        const finalDamage = (baseDamage + bonusDamage) * falloff;

                        try {
                            entity.applyDamage(finalDamage, { cause: EntityDamageCause.magic });

                            // Apply moderate knockback away from player
                            const knockbackDirection = {
                                x: entity.location.x - location.x,
                                y: Math.max(0.1, entity.location.y - location.y + 0.2),
                                z: entity.location.z - location.z
                            };

                            const knockbackDistance = Math.sqrt(
                                knockbackDirection.x ** 2 +
                                knockbackDirection.y ** 2 +
                                knockbackDirection.z ** 2
                            );

                            if (knockbackDistance > 0) {
                                const knockbackPower = 1.0 * falloff; // Reduced knockback
                                entity.applyKnockback(
                                    knockbackDirection.x / knockbackDistance * knockbackPower,
                                    knockbackDirection.z / knockbackDistance * knockbackPower,
                                    knockbackPower,
                                    Math.abs(knockbackDirection.y / knockbackDistance * knockbackPower * 0.3)
                                );
                            }

                            // Create damage effect
                            this.createDamageEffect(dimension, entity.location);

                        } catch (entityError) {
                            // Error damaging entity
                        }
                    }
                }

                // Heal allied players with mythril armor (balanced)
                if (distance <= healRadius && entity.typeId === 'minecraft:player') {
                    const allyMythrilCount = this.getMythrilArmorCount(entity);
                    if (allyMythrilCount > 0) {
                        // Apply small regeneration
                        entity.addEffect('regeneration', 40, { // Reduced duration
                            amplifier: 0,
                            showParticles: false
                        });

                        // Smaller bonus for full set users
                        if (allyMythrilCount >= 4) {
                            entity.addEffect('speed', 60, { // Reduced duration
                                amplifier: 0,
                                showParticles: false
                            });
                        }

                        // Healing particles
                        this.createHealingEffect(dimension, entity.location);
                    }
                }
            });

        } catch (error) {
            // Error handling entities
        }
    },

    applyFallProtection(player, mythrilPower) {
        try {
            // Apply balanced slow falling effect
            const duration = this.config.slowfallDuration + (mythrilPower * 20); // Reduced bonus
            const amplifier = mythrilPower >= 4 ? 1 : 0; // Reduced amplifier

            player.addEffect('slow_falling', duration, {
                amplifier: amplifier,
                showParticles: false
            });

            // Store balanced fall protection data
            player.setDynamicProperty('myw:fall_protection', Date.now() + (duration * 50));
            player.setDynamicProperty('myw:fall_reduction', this.config.falldamageReduction); // 70% reduction instead of immunity

            // Add balanced feather falling effect
            player.addEffect('jump_boost', duration, {
                amplifier: mythrilPower >= 4 ? 2 : 1, // Reduced amplifier
                showParticles: false
            });

        } catch (error) {
            // Error applying fall protection
        }
    },

    // VISUAL EFFECTS
    createDamageEffect(dimension, location) {
        try {
            for (let i = 0; i < 4; i++) { // Reduced particles
                system.runTimeout(() => {
                    try {
                        dimension.spawnParticle('myw:mythril_particle', {
                            x: location.x + (Math.random() - 0.5) * 1.0,
                            y: location.y + Math.random() * 1.2 + 0.3,
                            z: location.z + (Math.random() - 0.5) * 1.0
                        });
                    } catch (error) {
                        // Error with damage particles
                    }
                }, i * 4);
            }
        } catch (error) {
            // Error creating damage effect
        }
    },

    createHealingEffect(dimension, location) {
        try {
            // Smaller healing spiral
            for (let i = 0; i < 6; i++) { // Reduced from 8
                const angle = (i / 6) * Math.PI * 2;
                const radius = 0.8; // Smaller radius
                const height = i * 0.15; // Lower height

                system.runTimeout(() => {
                    try {
                        dimension.spawnParticle('myw:mythril_particle_minimalist', {
                            x: location.x + Math.cos(angle) * radius,
                            y: location.y + height,
                            z: location.z + Math.sin(angle) * radius
                        });
                    } catch (error) {
                        // Error with healing particles
                    }
                }, i * 5);
            }
        } catch (error) {
            // Error creating healing effect
        }
    },

    // UTILITY FUNCTIONS
    getMythrilArmorCount(player) {
        try {
            const equippableComp = player.getComponent('minecraft:equippable');
            if (!equippableComp) return 0;

            let mythrilCount = 0;
            const armorSlots = [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet];

            armorSlots.forEach(slot => {
                const item = equippableComp.getEquipment(slot);
                if (item && item.typeId.includes('myw:mythril')) {
                    mythrilCount++;
                }
            });

            return mythrilCount;
        } catch (error) {
            return 0;
        }
    },

    isHostileEntity(entity) {
        const hostileTypes = [
            'zombie', 'skeleton', 'creeper', 'spider', 'enderman', 'witch',
            'slime', 'magma_cube', 'blaze', 'ghast', 'piglin', 'hoglin',
            'zoglin', 'vindicator', 'evoker', 'pillager', 'ravager'
        ];

        return hostileTypes.some(type => entity.typeId.includes(type)) ||
            entity.hasComponent('minecraft:angry');
    },

    getDistance(loc1, loc2) {
        return Math.sqrt(
            (loc1.x - loc2.x) ** 2 +
            (loc1.y - loc2.y) ** 2 +
            (loc1.z - loc2.z) ** 2
        );
    }
};

// Register mythril dust component
export function registerMythrilDust(itemComponentRegistry) {
    itemComponentRegistry.registerCustomComponent('myw:mythril_dust', {
        onUse(eventData) {
            const { itemStack, source } = eventData;
            MythrilDustSystem.handleDustUse(source, itemStack);
        }
    });
}

// Initialize dust systems
export function initializeDustSystems() {
    // Fall damage reduction system (balanced)
    world.afterEvents.entityHurt.subscribe(eventData => {
        const entity = eventData.hurtEntity;

        if (entity.typeId === 'minecraft:player' && eventData.cause === EntityDamageCause.fall) {
            try {
                const protectionTime = entity.getDynamicProperty('myw:fall_protection') || 0;
                const currentTime = Date.now();

                if (currentTime < protectionTime) {
                    const reductionFactor = entity.getDynamicProperty('myw:fall_reduction') || 0;
                    const originalDamage = eventData.damage;
                    const reducedDamage = originalDamage * (1 - reductionFactor);

                    // Heal back the reduced damage
                    const healAmount = originalDamage - reducedDamage;
                    system.runTimeout(() => {
                        try {
                            entity.applyDamage(-healAmount); // Negative damage = healing

                            // Create smaller protection effect
                            const dimension = entity.dimension;
                            for (let i = 0; i < 3; i++) { // Reduced particles
                                system.runTimeout(() => {
                                    try {
                                        dimension.spawnParticle('myw:mythril_particle_minimalist', {
                                            x: entity.location.x + (Math.random() - 0.5) * 1.0,
                                            y: entity.location.y + Math.random() * 0.3,
                                            z: entity.location.z + (Math.random() - 0.5) * 1.0
                                        });
                                    } catch (error) {
                                        // Error with protection particles
                                    }
                                }, i * 4);
                            }
                        } catch (error) {
                            // Error with damage reduction
                        }
                    }, 1);
                }
            } catch (error) {
                // Error checking fall protection
            }
        }
    });

    world.sendMessage('[OK] Mythril Dust System initialized - Balanced Version');
}