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

export const MythrilNuggetSystem = {

    activeProjectiles: new Map(),

    initialize() {
        // Detectar proyectiles
        system.runInterval(() => {
            this.detectProjectiles();
        }, 1);

        // Actualizar efectos
        system.runInterval(() => {
            this.updateEffects();
        }, 1);

        // Limpieza
        system.runInterval(() => {
            this.cleanup();
        }, 40);

        world.sendMessage('[OK] Mythril Nugget System - Active');
    },

    detectProjectiles() {
        try {
            world.getAllPlayers().forEach(player => {
                const entities = player.dimension.getEntities({
                    type: 'myw:mythril_nugget',
                    location: player.location,
                    maxDistance: 30
                });

                entities.forEach(entity => {
                    if (!this.activeProjectiles.has(entity.id)) {
                        this.activeProjectiles.set(entity.id, {
                            entity: entity,
                            launcher: player,
                            dimension: entity.dimension,
                            lastLocation: { ...entity.location },
                            velocity: { x: 0, y: 0, z: 0 },
                            age: 0,
                            mythrilLevel: this.getMythrilLevel(player),
                            hasGroundImpact: false
                        });
                    }
                });
            });
        } catch (error) { }
    },

    updateEffects() {
        this.activeProjectiles.forEach((data, entityId) => {
            if (!data.entity.isValid()) {
                this.activeProjectiles.delete(entityId);
                return;
            }

            data.age++;
            this.updateVelocity(data);
            this.createTrail(data);
            this.checkGroundImpact(data);
            data.lastLocation = { ...data.entity.location };
        });
    },

    updateVelocity(data) {
        const current = data.entity.location;
        const last = data.lastLocation;

        data.velocity = {
            x: current.x - last.x,
            y: current.y - last.y,
            z: current.z - last.z
        };
    },

    createTrail(data) {
        try {
            const loc = data.entity.location;
            const particleCount = 4 + (data.mythrilLevel * 2);

            for (let i = 0; i < particleCount; i++) {
                const particleLoc = {
                    x: loc.x + (Math.random() - 0.5) * 0.6,
                    y: loc.y + (Math.random() - 0.5) * 0.6,
                    z: loc.z + (Math.random() - 0.5) * 0.6
                };

                this.spawnParticle(data.dimension, particleLoc, data.mythrilLevel);
            }
        } catch (error) { }
    },

    checkGroundImpact(data) {
        if (data.hasGroundImpact) return;

        try {
            const loc = data.entity.location;
            const blockBelow = data.dimension.getBlock({
                x: Math.floor(loc.x),
                y: Math.floor(loc.y) - 1,
                z: Math.floor(loc.z)
            });

            const blockAt = data.dimension.getBlock({
                x: Math.floor(loc.x),
                y: Math.floor(loc.y),
                z: Math.floor(loc.z)
            });

            const nearGround = blockBelow && !blockBelow.isAir && loc.y <= Math.floor(loc.y) + 0.4;
            const inBlock = blockAt && !blockAt.isAir;
            const stopped = Math.abs(data.velocity.x) < 0.1 && Math.abs(data.velocity.y) < 0.1 && Math.abs(data.velocity.z) < 0.1;

            if ((nearGround || inBlock) && stopped) {
                data.hasGroundImpact = true;
                this.createGroundEffects(data, blockBelow || blockAt);
            }
        } catch (error) { }
    },

    createGroundEffects(data, block) {
        try {
            const loc = data.entity.location;
            const blockType = block ? block.typeId : '';

            // Efectos base
            this.createBaseImpact(data, loc);

            // Efectos específicos por bloque
            this.createBlockEffects(data, loc, blockType);

        } catch (error) { }
    },

    createBaseImpact(data, location) {
        const dimension = data.dimension;
        const particleCount = 20 + (data.mythrilLevel * 8);

        // Explosión principal
        for (let i = 0; i < particleCount; i++) {
            const angle = Math.random() * Math.PI * 2;
            const distance = Math.random() * 3;
            const impactLoc = {
                x: location.x + Math.cos(angle) * distance,
                y: location.y + Math.random() * 1.5,
                z: location.z + Math.sin(angle) * distance
            };

            system.runTimeout(() => {
                this.spawnParticle(dimension, impactLoc, data.mythrilLevel);
            }, Math.random() * 20);
        }

        // Ondas de choque
        for (let wave = 1; wave <= 3; wave++) {
            const waveRadius = wave * 1.5;
            const waveParticles = wave * 8;

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

                system.runTimeout(() => {
                    this.spawnParticle(dimension, waveLoc, data.mythrilLevel);
                }, wave * 10 + i);
            }
        }

        // Columna central
        const columnHeight = 2 + data.mythrilLevel;
        for (let h = 0; h < columnHeight; h++) {
            const colLoc = {
                x: location.x + (Math.random() - 0.5) * 0.6,
                y: location.y + h * 0.7,
                z: location.z + (Math.random() - 0.5) * 0.6
            };

            system.runTimeout(() => {
                this.spawnParticle(dimension, colLoc, data.mythrilLevel);
            }, h * 5);
        }
    },

    createBlockEffects(data, location, blockType) {
        const dimension = data.dimension;

        if (blockType.includes('stone')) {
            // Chispas de piedra
            for (let i = 0; i < 15; i++) {
                const sparkLoc = {
                    x: location.x + (Math.random() - 0.5) * 2.5,
                    y: location.y + Math.random() * 2,
                    z: location.z + (Math.random() - 0.5) * 2.5
                };
                system.runTimeout(() => {
                    this.spawnParticle(dimension, sparkLoc, data.mythrilLevel);
                }, i * 2);
            }

        } else if (blockType.includes('dirt') || blockType.includes('grass')) {
            // Explosión de tierra
            for (let i = 0; i < 25; i++) {
                const dirtLoc = {
                    x: location.x + (Math.random() - 0.5) * 2,
                    y: location.y + Math.random() * 3,
                    z: location.z + (Math.random() - 0.5) * 2
                };
                system.runTimeout(() => {
                    this.spawnParticle(dimension, dirtLoc, data.mythrilLevel);
                }, Math.random() * 15);
            }

        } else if (blockType.includes('sand')) {
            // Tormenta de arena
            for (let i = 0; i < 30; i++) {
                const angle = (i / 30) * Math.PI * 4;
                const radius = (i / 30) * 3;
                const sandLoc = {
                    x: location.x + Math.cos(angle) * radius,
                    y: location.y + Math.random() * 2.5,
                    z: location.z + Math.sin(angle) * radius
                };
                system.runTimeout(() => {
                    this.spawnParticle(dimension, sandLoc, data.mythrilLevel);
                }, i);
            }

        } else if (blockType.includes('water')) {
            // Ondas de agua
            for (let wave = 1; wave <= 4; wave++) {
                const waveRadius = wave * 1.2;
                for (let i = 0; i < wave * 6; i++) {
                    const angle = (i / (wave * 6)) * Math.PI * 2;
                    const waterLoc = {
                        x: location.x + Math.cos(angle) * waveRadius,
                        y: location.y + 0.2,
                        z: location.z + Math.sin(angle) * waveRadius
                    };
                    system.runTimeout(() => {
                        this.spawnParticle(dimension, waterLoc, data.mythrilLevel);
                    }, wave * 8 + i);
                }
            }
        }
    },

    spawnParticle(dimension, location, mythrilLevel) {
        try {
            if (mythrilLevel >= 3) {
                dimension.spawnParticle('myw:mythril_particle_serpentine', location);
            } else if (mythrilLevel >= 2) {
                dimension.spawnParticle('myw:mythril_particle', location);
            } else {
                dimension.spawnParticle('myw:mythril_particle_minimalist', location);
            }
        } catch (error) {
            try {
                const fallbacks = ['minecraft:critical_hit_emitter', 'minecraft:villager_happy', 'minecraft:end_rod'];
                const fallback = fallbacks[mythrilLevel % 3] || 'minecraft:villager_happy';
                dimension.spawnParticle(fallback, location);
            } catch (e) { }
        }
    },

    getMythrilLevel(player) {
        try {
            const equippable = player.getComponent('equippable');
            if (!equippable) return 0;

            let count = 0;
            ['Head', 'Chest', 'Legs', 'Feet'].forEach(slot => {
                try {
                    const item = equippable.getEquipment(slot);
                    if (item && item.typeId.includes('myw:mythril')) count++;
                } catch (error) { }
            });
            return count;
        } catch (error) {
            return 0;
        }
    },

    cleanup() {
        const toRemove = [];
        this.activeProjectiles.forEach((data, entityId) => {
            if (!data.entity.isValid() || data.age > 1500) {
                toRemove.push(entityId);
            }
        });
        toRemove.forEach(id => this.activeProjectiles.delete(id));
    }
};

export function initializeMythrilNuggetSystem() {
    MythrilNuggetSystem.initialize();
}