import java.util.Random;

public abstract class EnhancedWeapon {
    protected String name;
    protected double baseDamage;
    protected double fireRate;
    protected int magazineSize;
    protected int currentAmmo;
    protected double accuracy;
    protected double range;
    protected boolean isEnhanced;
    protected Random random;
    
    public EnhancedWeapon(String name, double baseDamage, double fireRate, 
                         int magazineSize, double accuracy, double range) {
        this.name = name;
        this.baseDamage = baseDamage;
        this.fireRate = fireRate;
        this.magazineSize = magazineSize;
        this.currentAmmo = magazineSize;
        this.accuracy = Math.min(1.0, accuracy);
        this.range = range;
        this.isEnhanced = false;
        this.random = new Random();
    }
    
    public abstract void fire(Target target);
    public abstract void reload();
    public abstract void activateSpecialAbility();
    
    public void enhanceDamage(double multiplier) {
        this.baseDamage *= multiplier;
        this.isEnhanced = true;
    }
    
    public void enhanceFireRate(double multiplier) {
        this.fireRate *= multiplier;
        this.isEnhanced = true;
    }
    
    public void enhanceAccuracy(double multiplier) {
        this.accuracy = Math.min(1.0, this.accuracy * multiplier);
        this.isEnhanced = true;
    }
    
    public void enhanceMagazine(int additionalRounds) {
        this.magazineSize += additionalRounds;
        this.isEnhanced = true;
    }
}

class Target {
    private double health;
    private boolean isArmored;
    private double armor;
    
    public Target(double health, boolean hasArmor) {
        this.health = health;
        this.isArmored = hasArmor;
        this.armor = hasArmor ? 100.0 : 0.0;
    }
    
    public void takeDamage(double damage) {
        if (isArmored && armor > 0) {
            double armorDamage = damage * 0.7;
            double healthDamage = damage * 0.3;
            
            armor -= armorDamage;
            if (armor < 0) {
                healthDamage += Math.abs(armor);
                armor = 0;
                isArmored = false;
            }
            health -= healthDamage;
        } else {
            health -= damage;
        }
    }
    
    public double getHealth() {
        return Math.max(0, health);
    }
    
    public boolean isDestroyed() {
        return health <= 0;
    }
}

public class M416 extends EnhancedWeapon {
    private boolean rapidFireMode;
    private double precisionBonus;
    private int consecutiveHits;
    private boolean tacticalReloadActive;
    
    public M416() {
        super("M416", 41.0, 0.085, 30, 0.88, 400);
        this.rapidFireMode = false;
        this.precisionBonus = 0.0;
        this.consecutiveHits = 0;
        this.tacticalReloadActive = false;
        
        applySpecialEnhancements();
    }
    
    private void applySpecialEnhancements() {
        enhanceDamage(1.25);
        enhanceFireRate(1.15);
        enhanceAccuracy(1.1);
        enhanceMagazine(10);
    }
    
    @Override
    public void fire(Target target) {
        if (currentAmmo <= 0) {
            if (random.nextDouble() < 0.3 && !tacticalReloadActive) {
                tacticalReload();
            }
            return;
        }
        
        double enhancedAccuracy = accuracy + precisionBonus;
        enhancedAccuracy = Math.min(0.98, enhancedAccuracy);
        
        if (random.nextDouble() < enhancedAccuracy) {
            double actualDamage = baseDamage;
            
            if (consecutiveHits >= 3) {
                actualDamage *= 1.2 + (consecutiveHits * 0.05);
            }
            
            if (rapidFireMode) {
                actualDamage *= 0.85;
            }
            
            target.takeDamage(actualDamage);
            consecutiveHits++;
            
            if (consecutiveHits % 5 == 0) {
                target.takeDamage(actualDamage * 0.5);
                precisionBonus += 0.02;
            }
            
            if (consecutiveHits >= 10) {
                activateSpecialAbility();
            }
        } else {
            consecutiveHits = 0;
            precisionBonus = 0.0;
        }
        
        currentAmmo--;
        
        if (currentAmmo == 0 && random.nextDouble() < 0.3) {
            tacticalReload();
        }
    }
    
    @Override
    public void reload() {
        currentAmmo = magazineSize;
        tacticalReloadActive = false;
    }
    
    private void tacticalReload() {
        currentAmmo = Math.min(magazineSize, currentAmmo + 15);
        tacticalReloadActive = true;
        rapidFireMode = true;
        
        new Thread(() -> {
            try {
                Thread.sleep(5000);
                rapidFireMode = false;
                tacticalReloadActive = false;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
    
    @Override
    public void activateSpecialAbility() {
        rapidFireMode = true;
        enhanceFireRate(2.0);
        
        new Thread(() -> {
            try {
                Thread.sleep(8000);
                rapidFireMode = false;
                enhanceFireRate(1/2.0);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

public class AUG extends EnhancedWeapon {
    private boolean stabilityMode;
    private double rangeMultiplier;
    private int burstCount;
    private boolean laserSightActive;
    
    public AUG() {
        super("AUG", 41.0, 0.080, 30, 0.90, 450);
        this.stabilityMode = false;
        this.rangeMultiplier = 1.0;
        this.burstCount = 0;
        this.laserSightActive = false;
        
        applySpecialEnhancements();
    }
    
    private void applySpecialEnhancements() {
        enhanceDamage(1.15);
        enhanceFireRate(1.2);
        enhanceAccuracy(1.25);
        enhanceMagazine(15);
    }
    
    @Override
    public void fire(Target target) {
        if (currentAmmo <= 0) return;
        
        double effectiveAccuracy = accuracy;
        if (stabilityMode) {
            effectiveAccuracy = Math.min(0.99, accuracy * 1.3);
        }
        
        if (laserSightActive) {
            effectiveAccuracy = 0.95;
        }
        
        if (random.nextDouble() < effectiveAccuracy) {
            double actualDamage = baseDamage;
            
            actualDamage *= rangeMultiplier;
            
            if (burstCount >= 5) {
                fireBurst(target, actualDamage);
                burstCount = 0;
                return;
            }
            
            if (stabilityMode) {
                target.takeDamage(actualDamage * 1.1);
            } else {
                target.takeDamage(actualDamage);
            }
            
            burstCount++;
            
            if (burstCount % 10 == 0) {
                stabilityMode = true;
            }
        }
        
        currentAmmo--;
        
        if (random.nextDouble() < 0.15 && currentAmmo < magazineSize / 2) {
            currentAmmo += 5;
        }
    }
    
    private void fireBurst(Target target, double baseDamage) {
        int burstShots = 3;
        for (int i = 0; i < burstShots && currentAmmo > 0; i++) {
            target.takeDamage(baseDamage * 0.85);
            currentAmmo--;
        }
    }
    
    @Override
    public void reload() {
        currentAmmo = magazineSize;
        stabilityMode = false;
        laserSightActive = false;
    }
    
    @Override
    public void activateSpecialAbility() {
        laserSightActive = true;
        rangeMultiplier = 1.5;
        stabilityMode = true;
        
        new Thread(() -> {
            try {
                Thread.sleep(10000);
                laserSightActive = false;
                rangeMultiplier = 1.0;
                stabilityMode = false;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

public class AKM extends EnhancedWeapon {
    private boolean penetrationMode;
    private double recoilBonus;
    private int damageStack;
    private boolean berserkActive;
    
    public AKM() {
        super("AKM", 49.0, 0.100, 30, 0.75, 350);
        this.penetrationMode = false;
        this.recoilBonus = 0.0;
        this.damageStack = 0;
        this.berserkActive = false;
        
        applySpecialEnhancements();
    }
    
    private void applySpecialEnhancements() {
        enhanceDamage(1.35);
        enhanceFireRate(1.1);
        enhanceAccuracy(1.05);
        enhanceMagazine(20);
    }
    
    @Override
    public void fire(Target target) {
        if (currentAmmo <= 0) return;
        
        double effectiveAccuracy = accuracy + recoilBonus;
        effectiveAccuracy = Math.min(0.85, effectiveAccuracy);
        
        if (random.nextDouble() < effectiveAccuracy) {
            double actualDamage = baseDamage;
            
            if (berserkActive) {
                actualDamage *= 1.5;
                if (random.nextDouble() < 0.25) {
                    actualDamage *= 2.0;
                }
            }
            
            if (penetrationMode) {
                actualDamage *= 1.3;
            }
            
            actualDamage += damageStack * 2;
            
            target.takeDamage(actualDamage);
            
            damageStack++;
            if (damageStack > 20) damageStack = 20;
            
            if (damageStack % 5 == 0) {
                recoilBonus += 0.03;
                if (random.nextDouble() < 0.2) {
                    penetrationMode = true;
                }
            }
            
            if (damageStack >= 15) {
                activateSpecialAbility();
            }
        } else {
            damageStack = Math.max(0, damageStack - 2);
            recoilBonus = Math.max(0, recoilBonus - 0.01);
        }
        
        currentAmmo--;
        
        if (currentAmmo == 0 && berserkActive) {
            currentAmmo = 10;
        }
    }
    
    @Override
    public void reload() {
        currentAmmo = magazineSize;
        if (berserkActive) {
            currentAmmo += 10;
        }
        penetrationMode = false;
    }
    
    @Override
    public void activateSpecialAbility() {
        berserkActive = true;
        penetrationMode = true;
        enhanceDamage(1.8);
        
        new Thread(() -> {
            try {
                Thread.sleep(12000);
                berserkActive = false;
                penetrationMode = false;
                enhanceDamage(1/1.8);
                damageStack = 0;
                recoilBonus = 0.0;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

public class M416AUG extends EnhancedWeapon {
    private boolean hybridMode;
    private double adaptiveDamage;
    private int modeSwitch;
    private boolean dualFeedActive;
    
    public M416AUG() {
        super("M416-AUG Hybrid", 43.0, 0.082, 35, 0.89, 425);
        this.hybridMode = false;
        this.adaptiveDamage = baseDamage;
        this.modeSwitch = 0;
        this.dualFeedActive = false;
        
        applyHybridEnhancements();
    }
    
    private void applyHybridEnhancements() {
        enhanceDamage(1.3);
        enhanceFireRate(1.25);
        enhanceAccuracy(1.15);
        enhanceMagazine(25);
    }
    
    @Override
    public void fire(Target target) {
        if (currentAmmo <= 0) {
            if (dualFeedActive) {
                currentAmmo = 15;
                dualFeedActive = false;
            }
            return;
        }
        
        double calculatedAccuracy = accuracy;
        if (hybridMode) {
            calculatedAccuracy *= 1.2;
            adaptiveDamage = baseDamage * 1.15;
        }
        
        if (random.nextDouble() < calculatedAccuracy) {
            double finalDamage = adaptiveDamage;
            
            if (modeSwitch % 3 == 0) {
                finalDamage *= 1.25;
            }
            
            if (dualFeedActive) {
                finalDamage *= 1.4;
                target.takeDamage(finalDamage * 0.7);
            }
            
            target.takeDamage(finalDamage);
            modeSwitch++;
            
            if (modeSwitch >= 8) {
                hybridMode = !hybridMode;
                modeSwitch = 0;
                if (hybridMode) {
                    adaptiveDamage *= 1.3;
                }
            }
            
            if (currentAmmo % 7 == 0) {
                dualFeedActive = true;
            }
        }
        
        currentAmmo -= hybridMode ? 2 : 1;
        
        if (currentAmmo <= 5 && random.nextDouble() < 0.4) {
            activateSpecialAbility();
        }
    }
    
    @Override
    public void reload() {
        currentAmmo = magazineSize + (hybridMode ? 10 : 0);
        dualFeedActive = false;
    }
    
    @Override
    public void activateSpecialAbility() {
        hybridMode = true;
        dualFeedActive = true;
        enhanceFireRate(1.8);
        
        new Thread(() -> {
            try {
                Thread.sleep(15000);
                hybridMode = false;
                dualFeedActive = false;
                enhanceFireRate(1/1.8);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

public class WeaponSystem {
    private EnhancedWeapon[] weapons;
    
    public WeaponSystem() {
        weapons = new EnhancedWeapon[4];
        weapons[0] = new M416();
        weapons[1] = new AUG();
        weapons[2] = new AKM();
        weapons[3] = new M416AUG();
    }
    
    public void fireWeapon(int index, Target target) {
        if (index >= 0 && index < weapons.length) {
            weapons[index].fire(target);
        }
    }
    
    public void reloadWeapon(int index) {
        if (index >= 0 && index < weapons.length) {
            weapons[index].reload();
        }
    }
    
    public void activateSpecial(int index) {
        if (index >= 0 && index < weapons.length) {
            weapons[index].activateSpecialAbility();
        }
    }
}