// AdvancedBulletTracking.js
class AdvancedBulletTracking {
    constructor() {
        this.config = {
            trackingEnabled: true,
            trackingPrecision: 0.9999,
            maxTrackingDistance: 520,
            minTrackingDistance: 0.1,
            trackingRange: 360,
            headshotPriority: true,
            ignoreTeammates: true,
            adaptivePrediction: true
        };
        
        this.weaponProfiles = {
            assaultRifle: {
                trackingBoost: 1.2,
                bulletVelocity: 900,
                recoilCompensation: 0.85,
                effectiveRange: 400
            },
            sniperRifle: {
                trackingBoost: 1.5,
                bulletVelocity: 950,
                recoilCompensation: 0.95,
                effectiveRange: 1000
            },
            smg: {
                trackingBoost: 1.1,
                bulletVelocity: 380,
                recoilCompensation: 0.75,
                effectiveRange: 200
            },
            shotgun: {
                trackingBoost: 0.9,
                bulletVelocity: 330,
                recoilCompensation: 0.6,
                effectiveRange: 50
            }
        };
        
        this.targetData = {
            currentTarget: null,
            targetHistory: [],
            predictionModel: null,
            hitProbability: 0
        };
    }

    initialize() {
        this.setupPredictionEngine();
        this.loadWeaponConfig();
        return this.config.trackingEnabled;
    }

    setupPredictionEngine() {
        this.predictionModel = {
            movementPrediction: this.calculateMovementPrediction.bind(this),
            bulletDropCompensation: this.calculateBulletDrop.bind(this),
            leadCalculation: this.calculateLeadTarget.bind(this),
            trajectoryOptimization: this.optimizeTrajectory.bind(this)
        };
    }

    calculateMovementPrediction(targetPosition, targetVelocity, bulletSpeed, distance) {
        const timeToTarget = distance / bulletSpeed;
        const predictedPosition = {
            x: targetPosition.x + (targetVelocity.x * timeToTarget),
            y: targetPosition.y + (targetVelocity.y * timeToTarget),
            z: targetPosition.z + (targetVelocity.z * timeToTarget)
        };
        
        return predictedPosition;
    }

    calculateBulletDrop(distance, bulletMass, gravity) {
        const drop = 0.5 * gravity * Math.pow(distance / this.config.bulletVelocity, 2);
        return Math.max(0, drop);
    }

    calculateLeadTarget(target, weaponType) {
        const weapon = this.weaponProfiles[weaponType];
        if (!weapon) return target.position;
        
        return this.predictionModel.movementPrediction(
            target.position,
            target.velocity,
            weapon.bulletVelocity,
            target.distance
        );
    }

    optimizeTrajectory(startPoint, endPoint, obstacles) {
        const directPath = this.calculateDirectPath(startPoint, endPoint);
        
        for (let obstacle of obstacles) {
            if (this.checkCollision(directPath, obstacle)) {
                return this.calculateAlternativePath(startPoint, endPoint, obstacle);
            }
        }
        
        return directPath;
    }

    acquireTarget(targets, currentWeapon) {
        if (!targets.length) return null;
        
        const validTargets = targets.filter(target => 
            target.distance <= this.config.maxTrackingDistance && 
            target.distance >= this.config.minTrackingDistance &&
            (!this.config.ignoreTeammates || !target.isTeammate)
        );
        
        if (!validTargets.length) return null;
        
        const scoredTargets = validTargets.map(target => ({
            target,
            score: this.calculateTargetScore(target, currentWeapon)
        }));
        
        scoredTargets.sort((a, b) => b.score - a.score);
        this.targetData.currentTarget = scoredTargets[0].target;
        
        return this.targetData.currentTarget;
    }

    calculateTargetScore(target, weaponType) {
        const weapon = this.weaponProfiles[weaponType];
        if (!weapon) return 0;
        
        let score = 0;
        
        const distanceScore = Math.max(0, 1 - (target.distance / weapon.effectiveRange));
        score += distanceScore * 0.4;
        
        if (this.config.headshotPriority && target.headVisible) {
            score += 0.3;
        }
        
        const velocityFactor = 1 - (Math.sqrt(
            target.velocity.x * target.velocity.x +
            target.velocity.y * target.velocity.y +
            target.velocity.z * target.velocity.z
        ) / 100);
        score += velocityFactor * 0.2;
        
        if (target.isStationary) {
            score += 0.1;
        }
        
        return Math.min(1, score);
    }

    trackBulletToTarget(bulletStart, target, weaponType) {
        if (!this.config.trackingEnabled || !target) return bulletStart;
        
        const weapon = this.weaponProfiles[weaponType];
        if (!weapon) return bulletStart;
        
        const leadTarget = this.calculateLeadTarget(target, weaponType);
        const optimizedTrajectory = this.optimizeTrajectory(bulletStart, leadTarget, []);
        
        this.targetData.hitProbability = this.calculateHitProbability(target, weaponType);
        
        return optimizedTrajectory;
    }

    calculateHitProbability(target, weaponType) {
        const weapon = this.weaponProfiles[weaponType];
        if (!weapon) return 0;
        
        let baseProbability = this.config.trackingPrecision;
        
        const distanceFactor = Math.max(0, 1 - (target.distance / weapon.effectiveRange));
        baseProbability *= distanceFactor;
        
        const movementPenalty = Math.sqrt(
            target.velocity.x * target.velocity.x +
            target.velocity.y * target.velocity.y
        ) / 50;
        baseProbability *= Math.max(0.1, 1 - movementPenalty);
        
        if (this.config.headshotPriority && target.headVisible) {
            baseProbability *= 1.2;
        }
        
        return Math.min(1, baseProbability * weapon.trackingBoost);
    }

    updateWeaponProfile(weaponType, newProfile) {
        if (this.weaponProfiles[weaponType]) {
            this.weaponProfiles[weaponType] = {
                ...this.weaponProfiles[weaponType],
                ...newProfile
            };
        }
    }

    getTrackingStatus() {
        return {
            enabled: this.config.trackingEnabled,
            currentTarget: this.targetData.currentTarget,
            hitProbability: this.targetData.hitProbability,
            weaponProfiles: this.weaponProfiles
        };
    }

    calculateDirectPath(start, end) {
        return {
            start,
            end,
            waypoints: [start, end],
            length: this.calculateDistance(start, end)
        };
    }

    calculateAlternativePath(start, end, obstacle) {
        const midPoint = {
            x: (start.x + end.x) / 2,
            y: (start.y + end.y) / 2 + 50,
            z: (start.z + end.z) / 2
        };
        
        return {
            start,
            end,
            waypoints: [start, midPoint, end],
            length: this.calculateDistance(start, midPoint) + this.calculateDistance(midPoint, end)
        };
    }

    checkCollision(path, obstacle) {
        const pathVector = {
            x: path.end.x - path.start.x,
            y: path.end.y - path.start.y,
            z: path.end.z - path.start.z
        };
        
        const toObstacle = {
            x: obstacle.position.x - path.start.x,
            y: obstacle.position.y - path.start.y,
            z: obstacle.position.z - path.start.z
        };
        
        const pathLength = Math.sqrt(pathVector.x * pathVector.x + pathVector.y * pathVector.y + pathVector.z * pathVector.z);
        const projection = (toObstacle.x * pathVector.x + toObstacle.y * pathVector.y + toObstacle.z * pathVector.z) / (pathLength * pathLength);
        
        return projection >= 0 && projection <= 1;
    }

    calculateDistance(point1, point2) {
        const dx = point2.x - point1.x;
        const dy = point2.y - point1.y;
        const dz = point2.z - point1.z;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }

    loadWeaponConfig() {
        try {
            const savedConfig = localStorage.getItem('bulletTrackingConfig');
            if (savedConfig) {
                const config = JSON.parse(savedConfig);
                this.config = { ...this.config, ...config };
            }
        } catch (error) {
            console.warn('Failed to load saved config:', error);
        }
    }

    saveConfig() {
        try {
            localStorage.setItem('bulletTrackingConfig', JSON.stringify(this.config));
        } catch (error) {
            console.warn('Failed to save config:', error);
        }
    }
}

const bulletTracker = new AdvancedBulletTracking();
export default bulletTracker;
