using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Muzzles;

namespace AlienAttack.MonoGame.Things.Weapons;

public class Minigun : Weapon
{
    public override int FireThreshold => 15;

    public override void Fire(Sprite owner, SpriteUpdateContext context)
    {
        // Calculate bullet spawn positions relative to the player's bounding box
        int x1 = (int)owner.XPosition + 14;
        int x2 = (int)owner.XPosition + owner.BoundBox.Width - 16;
        int y = (int)owner.YPosition + 10;

        // Create bullets with velocity (0, -4)
        MinigunBulletLarge bullet1 = new(x1, y, 0, -6, owner);
        MinigunBulletLarge bullet2 = new(x2, y, 0, -6, owner);

        // Queue the bullets for spawning
        context.SpawnSprite(bullet1);
        context.SpawnSprite(bullet2);

        context.AudioManager.PlayPlayerFire();
    }
}

public abstract class MinigunSingle : Weapon
{
    public override void Fire(Sprite owner, SpriteUpdateContext context)
    {
        FireBulletFromMuzzleContext fireBulletContext = new()
        {
            Owner = owner,
            SpriteUpdateContext = context,
            BulletWidth = MinigunBulletSmall.Width,
            BulletHeight = MinigunBulletSmall.Height,
            Factory = (x, y, vx, vy2, o) => new MinigunBulletSmall(x, y, vx, vy2, o),
            ExtraOffset = new(4f, 0),
            Shots =
            [
                new() { Muzzle = MuzzleId.Center, XVelocity = 0, YVelocity = -6 }
            ]
        };

        FireFromMuzzle(fireBulletContext);

        context.AudioManager.PlayPlayerFire();
    }
}

public class MinigunSingleSlow : MinigunSingle
{
    public override int FireThreshold => 20;
}

public class MinigunSingleAverage : MinigunSingle
{
    public override int FireThreshold => 15;
}


public class MinigunSingleFast : MinigunSingle
{
    public override int FireThreshold => 10;
}

public abstract class MinigunDouble : Weapon
{
    public override void Fire(Sprite owner, SpriteUpdateContext context)
    {
        FireBulletFromMuzzleContext fireBulletContext = new()
        {
            Owner = owner,
            SpriteUpdateContext = context,
            BulletWidth = MinigunBulletMedium.Width,
            BulletHeight = MinigunBulletMedium.Height,
            Factory = (x, y, vx, vy2, o) => new MinigunBulletMedium(x, y, vx, vy2, o),
            ExtraOffset = new(4f, 0),
            Shots =
            [
                new() { Muzzle = MuzzleId.Left, XVelocity = 0, YVelocity = -6 },
                new() { Muzzle = MuzzleId.Right, XVelocity = 0, YVelocity = -6 }
            ]
        };

        FireFromMuzzle(fireBulletContext);

        context.AudioManager.PlayPlayerFire();
    }
}

public class MinigunDoubleSlow : MinigunDouble
{
    public override int FireThreshold => 30;
}

public class MinigunDoubleAverage : MinigunDouble
{
    public override int FireThreshold => 20;
}

public class MinigunDoubleFast : MinigunDouble
{
    public override int FireThreshold => 15;
}

public abstract class MinigunTriple : Weapon
{
    public override void Fire(Sprite owner, SpriteUpdateContext context)
    {
        FireBulletFromMuzzleContext fireBulletContext = new()
        {
            Owner = owner,
            SpriteUpdateContext = context,
            BulletWidth = MinigunBulletMedium.Width,
            BulletHeight = MinigunBulletMedium.Height,
            Factory = (x, y, vx, vy2, o) => new MinigunBulletMedium(x, y, vx, vy2, o),
            ExtraOffset = new(4f, 0),
            Shots =
            [
                new() { Muzzle = MuzzleId.Left, XVelocity = 0, YVelocity = -6 },
                new() { Muzzle = MuzzleId.Center, XVelocity = 0, YVelocity = -6 },
                new() { Muzzle = MuzzleId.Right, XVelocity = 0, YVelocity = -6 }
            ]
        };

        FireFromMuzzle(fireBulletContext);

        context.AudioManager.PlayPlayerFire();
    }
}

public class MinigunTripleSlow : MinigunTriple
{
    public override int FireThreshold => 30;
}

public class MinigunTripleAverage : MinigunTriple
{
    public override int FireThreshold => 20;
}

public class MinigunTripleFast : MinigunTriple
{
    public override int FireThreshold => 15;
}

public abstract class MinigunTripleSpread : Weapon
{
    public override void Fire(Sprite owner, SpriteUpdateContext context)
    {
        FireBulletFromMuzzleContext fireBulletContext = new()
        {
            Owner = owner,
            SpriteUpdateContext = context,
            BulletWidth = LaserBulletLarge.Width,
            BulletHeight = LaserBulletLarge.Height,
            Factory = (x, y, vx, vy2, o) => new LaserBulletLarge(x, y, vx, vy2, o),
            ExtraOffset = new(4f, 0),
            Shots =
            [
                new() { Muzzle = MuzzleId.Left, XVelocity = -1, YVelocity = -6 },
                new() { Muzzle = MuzzleId.Right, XVelocity = 1, YVelocity = -6 },
                new() { Muzzle = MuzzleId.Center, XVelocity = 0, YVelocity = -6 }
            ]
        };

        FireFromMuzzle(fireBulletContext);

        context.AudioManager.PlayPlayerFire();
    }
}

public class MinigunTripleSpreadSlow : MinigunTripleSpread
{
    public override int FireThreshold => 30;
}

public class MinigunTripleSpreadAverage : MinigunTripleSpread
{
    public override int FireThreshold => 20;
}


public class MinigunTripleSpreadFast : MinigunTripleSpread
{
    public override int FireThreshold => 15;
}