class AdvancedRangeSystem {
    constructor() {
        this.config = {
            enabled: true,
            detectionRange: 1000,
            trackingRange: 800,
            effectiveRange: 600,
            closeRange: 50,
            mediumRange: 200,
            longRange: 400,
            extremeRange: 800,
            fov: 360,
            verticalFov: 180,
            sphericalDetection: true,
            dynamicRangeAdjustment: true
        };

        this.weaponRanges = {
            assault_rifle: {
                minRange: 30,
                maxRange: 600,
                optimalMin: 50,
                optimalMax: 300,
                effective: [80, 250],
                damageDropoff: {
                    close: 1.0,
                    medium: 0.85,
                    long: 0.65,
                    extreme: 0.4
                }
            },
            sniper_rifle: {
                minRange: 100,
                maxRange: 1200,
                optimalMin: 200,
                optimalMax: 800,
                effective: [300, 600],
                damageDropoff: {
                    close: 0.9,
                    medium: 1.0,
                    long: 0.95,
                    extreme: 0.8
                }
            },
            smg: {
                minRange: 5,
                maxRange: 200,
                optimalMin: 10,
                optimalMax: 100,
                effective: [15, 80],
                damageDropoff: {
                    close: 1.0,
                    medium: 0.7,
                    long: 0.4,
                    extreme: 0.2
                }
            },
            shotgun: {
                minRange: 1,
                maxRange: 80,
                optimalMin: 5,
                optimalMax: 30,
                effective: [8, 25],
                damageDropoff: {
                    close: 1.0,
                    medium: 0.6,
                    long: 0.3,
                    extreme: 0.1
                }
            },
            lmg: {
                minRange: 80,
                maxRange: 800,
                optimalMin: 100,
                optimalMax: 400,
                effective: [150, 350],
                damageDropoff: {
                    close: 0.8,
                    medium: 1.0,
                    long: 0.9,
                    extreme: 0.7
                }
            },
            dmr: {
                minRange: 100,
                maxRange: 800,
                optimalMin: 150,
                optimalMax: 500,
                effective: [200, 450],
                damageDropoff: {
                    close: 0.9,
                    medium: 1.0,
                    long: 0.95,
                    extreme: 0.85
                }
            },
            pistol: {
                minRange: 5,
                maxRange: 100,
                optimalMin: 10,
                optimalMax: 50,
                effective: [15, 40],
                damageDropoff: {
                    close: 1.0,
                    medium: 0.8,
                    long: 0.5,
                    extreme: 0.3
                }
            }
        };

        this.mapRanges = {
            erangel: {
                urban: [20, 150],
                rural: [100, 400],
                coastal: [50, 300],
                military: [200, 600],
                overall: [1, 800]
            },
            miramar: {
                desert: [150, 600],
                urban: [30, 200],
                mountain: [200, 800],
                overall: [1, 1000]
            },
            sanhok: {
                jungle: [10, 100],
                river: [50, 200],
                base: [20, 150],
                overall: [1, 400]
            },
            vikendi: {
                snow: [80, 400],
                urban: [25, 180],
                forest: [50, 300],
                overall: [1, 600]
            },
            livik: {
                hybrid: [15, 250],
                hotdrop: [5, 100],
                sniper: [100, 500],
                overall: [1, 500]
            }
        };

        this.attachmentEffects = {
            suppressor: {
                rangePenalty: 0.85,
                detectionReduction: 0.7
            },
            compensator: {
                rangeBonus: 1.05,
                recoilReduction: 0.15
            },
            muzzle_brake: {
                verticalRecoilReduction: 0.2,
                rangeBonus: 1.03
            },
            extended_barrel: {
                rangeBonus: 1.15,
                velocityIncrease: 1.1
            },
            red_dot: {
                closeRangeBonus: 1.02,
                acquisitionSpeed: 1.1
            },
            holographic: {
                mediumRangeBonus: 1.03,
                stability: 1.05
            },
            two_x: {
                mediumRangeBonus: 1.1,
                longRangePenalty: 0.95
            },
            three_x: {
                longRangeBonus: 1.2,
                closeRangePenalty: 0.9
            },
            four_x: {
                longRangeBonus: 1.3,
                closeRangePenalty: 0.85
            },
            six_x: {
                extremeRangeBonus: 1.5,
                mediumRangePenalty: 0.8
            },
            eight_x: {
                extremeRangeBonus: 1.7,
                closeRangePenalty: 0.7
            },
            tactical_stock: {
                stability: 1.05,
                movingAccuracy: 1.08
            },
            vertical_grip: {
                recoilControl: 1.03,
                firstShotAccuracy: 1.05
            },
            angled_grip: {
                aimSpeed: 1.02,
                adsTime: 0.95
            }
        };

        this.ammunitionRanges = {
            "556mm": {
                effectiveRange: 400,
                velocity: 900,
                drop: 0.12,
                penetration: 0.7
            },
            "762mm": {
                effectiveRange: 450,
                velocity: 780,
                drop: 0.15,
                penetration: 0.8
            },
            "9mm": {
                effectiveRange: 200,
                velocity: 380,
                drop: 0.08,
                penetration: 0.5
            },
            "45acp": {
                effectiveRange: 180,
                velocity: 280,
                drop: 0.1,
                penetration: 0.55
            },
            "12gauge": {
                effectiveRange: 50,
                velocity: 330,
                drop: 0.2,
                penetration: 0.9
            },
            "300magnum": {
                effectiveRange: 500,
                velocity: 910,
                drop: 0.1,
                penetration: 0.95
            }
        };

        this.rangeData = {
            currentDistance: 0,
            optimalWeapon: null,
            rangeEffectiveness: 0,
            environmentalFactors: 1.0,
            dynamicAdjustments: {}
        };

        this.performance = {
            rangeCalculations: 0,
            accuracyPredictions: 0,
            optimalSelections: 0
        };
    }

    initialize() {
        this.loadConfiguration();
        this.setupRangeCalculator();
        return this.config.enabled;
    }

    setupRangeCalculator() {
        this.calculator = {
            spherical: this.calculateSphericalRange.bind(this),
            linear: this.calculateLinearRange.bind(this),
            adaptive: this.calculateAdaptiveRange.bind(this)
        };
    }

    calculateWeaponEffectiveness(weaponType, distance, attachments = []) {
        const weapon = this.weaponRanges[weaponType];
        if (!weapon) return 0;

        let effectiveness = 1.0;

        if (distance < weapon.minRange || distance > weapon.maxRange) {
            return 0;
        }

        if (distance <= weapon.optimalMin) {
            effectiveness = weapon.damageDropoff.close;
        } else if (distance <= weapon.optimalMax) {
            effectiveness = weapon.damageDropoff.medium;
        } else if (distance <= weapon.maxRange * 0.7) {
            effectiveness = weapon.damageDropoff.long;
        } else {
            effectiveness = weapon.damageDropoff.extreme;
        }

        effectiveness *= this.calculateAttachmentBonus(attachments, distance);
        effectiveness *= this.calculateEnvironmentalFactor(distance);

        return Math.max(0, Math.min(1, effectiveness));
    }

    calculateAttachmentBonus(attachments, distance) {
        let bonus = 1.0;

        attachments.forEach(attachment => {
            const effect = this.attachmentEffects[attachment];
            if (effect) {
                if (effect.rangeBonus) bonus *= effect.rangeBonus;
                if (distance <= 100 && effect.closeRangeBonus) bonus *= effect.closeRangeBonus;
                if (distance > 100 && distance <= 300 && effect.mediumRangeBonus) bonus *= effect.mediumRangeBonus;
                if (distance > 300 && effect.longRangeBonus) bonus *= effect.longRangeBonus;
            }
        });

        return bonus;
    }

    calculateEnvironmentalFactor(distance) {
        let factor = 1.0;

        if (this.isRaining()) factor *= 0.9;
        if (this.isFoggy()) factor *= 0.8;
        if (this.isNight()) factor *= 0.7;
        if (this.isWindy()) factor *= 0.95;

        const distancePenalty = Math.max(0.5, 1 - (distance / 2000));
        factor *= distancePenalty;

        return factor;
    }

    getOptimalWeapon(distance, availableWeapons, attachments = {}) {
        let bestWeapon = null;
        let bestScore = -1;

        availableWeapons.forEach(weaponType => {
            const weaponAttachments = attachments[weaponType] || [];
            const score = this.calculateWeaponEffectiveness(weaponType, distance, weaponAttachments);

            if (score > bestScore) {
                bestScore = score;
                bestWeapon = weaponType;
            }
        });

        this.rangeData.optimalWeapon = bestWeapon;
        this.rangeData.rangeEffectiveness = bestScore;
        this.performance.optimalSelections++;

        return {
            weapon: bestWeapon,
            effectiveness: bestScore,
            recommendedRange: this.getWeaponRange(bestWeapon)
        };
    }

    getWeaponRange(weaponType) {
        const weapon = this.weaponRanges[weaponType];
        if (!weapon) return null;

        return {
            min: weapon.minRange,
            max: weapon.maxRange,
            optimal: [weapon.optimalMin, weapon.optimalMax],
            effective: weapon.effective
        };
    }

    calculateEngagementRange(targetDistance, currentWeapon, environment = {}) {
        const weaponRange = this.getWeaponRange(currentWeapon);
        if (!weaponRange) return 'invalid';

        if (targetDistance <= this.config.closeRange) return 'close';
        if (targetDistance <= this.config.mediumRange) return 'medium';
        if (targetDistance <= this.config.longRange) return 'long';
        if (targetDistance <= this.config.extremeRange) return 'extreme';
        return 'out_of_range';
    }

    getRangeAdvice(targetDistance, currentWeapon, availableWeapons) {
        const engagementRange = this.calculateEngagementRange(targetDistance, currentWeapon);
        const optimalWeapon = this.getOptimalWeapon(targetDistance, availableWeapons);
        const effectiveness = this.calculateWeaponEffectiveness(currentWeapon, targetDistance);

        return {
            currentRange: engagementRange,
            optimalWeapon: optimalWeapon.weapon,
            effectiveness: effectiveness,
            recommendation: this.generateRecommendation(engagementRange, effectiveness),
            shouldSwitch: optimalWeapon.effectiveness > effectiveness * 1.2
        };
    }

    generateRecommendation(range, effectiveness) {
        if (effectiveness < 0.3) {
            return 'DISENGAGE_OR_CLOSE_DISTANCE';
        } else if (effectiveness < 0.6) {
            return 'USE_COVER_AND_ADVANCE';
        } else if (effectiveness < 0.8) {
            return 'ENGAGE_WITH_CAUTION';
        } else {
            return 'OPTIMAL_ENGAGEMENT_RANGE';
        }
    }

    calculateBallisticDrop(distance, ammunitionType, zeroing = 100) {
        const ammo = this.ammunitionRanges[ammunitionType];
        if (!ammo) return 0;

        const drop = ammo.drop * Math.pow(distance / 100, 2);
        const zeroAdjustment = ammo.drop * Math.pow(zeroing / 100, 2);

        return drop - zeroAdjustment;
    }

    calculateLeadTarget(targetDistance, targetVelocity, ammunitionType) {
        const ammo = this.ammunitionRanges[ammunitionType];
        if (!ammo) return 0;

        const timeToTarget = targetDistance / ammo.velocity;
        const leadDistance = Math.sqrt(targetVelocity.x ** 2 + targetVelocity.y ** 2) * timeToTarget;

        return leadDistance;
    }

    getMapSpecificRanges(mapName, areaType = 'overall') {
        const map = this.mapRanges[mapName];
        if (!map) return this.config;

        const specificRange = map[areaType];
        if (specificRange) {
            return {
                minRange: specificRange[0],
                maxRange: specificRange[1],
                optimalMin: specificRange[0] * 1.5,
                optimalMax: specificRange[1] * 0.8
            };
        }

        return map.overall ? {
            minRange: map.overall[0],
            maxRange: map.overall[1]
        } : this.config;
    }

    adjustRangeDynamically(currentSituation) {
        const adjustments = {};

        if (currentSituation.isMoving) {
            adjustments.accuracyMultiplier = 0.8;
        }

        if (currentSituation.isCrouching) {
            adjustments.accuracyMultiplier = 1.1;
        }

        if (currentSituation.isProne) {
            adjustments.accuracyMultiplier = 1.2;
        }

        if (currentSituation.hasCover) {
            adjustments.engagementRange = currentSituation.coverDistance * 0.8;
        }

        this.rangeData.dynamicAdjustments = adjustments;
        return adjustments;
    }

    getRangeStatistics() {
        return {
            performance: this.performance,
            currentData: this.rangeData,
            configuration: this.config
        };
    }

    // Utility methods
    isRaining() { return Math.random() > 0.7; }
    isFoggy() { return Math.random() > 0.8; }
    isNight() { return Math.random() > 0.9; }
    isWindy() { return Math.random() > 0.6; }

    loadConfiguration() {
        try {
            const saved = localStorage.getItem('rangeSystemConfig');
            if (saved) {
                const config = JSON.parse(saved);
                Object.assign(this.config, config);
            }
        } catch (e) {
            console.warn('Range config load failed');
        }
    }

    saveConfiguration() {
        try {
            localStorage.setItem('rangeSystemConfig', JSON.stringify(this.config));
        } catch (e) {
            console.warn('Range config save failed');
        }
    }
}

const rangeSystem = new AdvancedRangeSystem();

rangeSystem.initialize();

export default rangeSystem