"""
Data migration: pre-populate the public catalog with well-known commercial
firearms, scopes, suppressors, bipods, magazines, factory ammo, and reloading
components (primers, brass, bullets, powders).

All Gear sub-class objects must set gear_type explicitly — Django does NOT run
custom save() overrides when using historical models inside data migrations.
"""
from django.db import migrations


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _get(apps, model_name):
    return apps.get_model('gears', model_name)


def _verified(apps):
    return 'VERIFIED'


# ---------------------------------------------------------------------------
# Populate functions
# ---------------------------------------------------------------------------

def populate_firearms(apps, schema_editor):
    Firearm = _get(apps, 'Firearm')
    status = _verified(apps)

    firearms = [
        # ── Bolt-action rifles ──────────────────────────────────────────────
        dict(brand='Remington', model_name='700 ADL', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Remington', model_name='700 BDL', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.30-06 Springfield', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Remington', model_name='700 SPS', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Remington', model_name='700 SPS Tactical', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=508, status=status),
        dict(brand='Remington', model_name='700 5R', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Remington', model_name='700 PCR', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Tikka', model_name='T3x Lite', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=600, status=status),
        dict(brand='Tikka', model_name='T3x TAC A1', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Tikka', model_name='T3x TAC A1 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Tikka', model_name='T3x Sporter', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=600, status=status),
        dict(brand='Tikka', model_name='T3x CTR', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=510, status=status),
        dict(brand='Savage', model_name='110 Tactical', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Savage', model_name='110 Elite Precision .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Savage', model_name='110 Elite Precision 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Savage', model_name='110 Long Range Hunter .300WM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.300 Win Mag', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Bergara', model_name='B-14 HMR .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=559, status=status),
        dict(brand='Bergara', model_name='B-14 HMR 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=559, status=status),
        dict(brand='Bergara', model_name='B-14 BMP', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Bergara', model_name='B-14 Wilderness Ridge 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=559, status=status),
        dict(brand='Sako', model_name='85 Black Bear', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=572, status=status),
        dict(brand='Sako', model_name='TRG 22 A1', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Sako', model_name='TRG 42 A1', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.338 Lapua Mag', action='BOLT',
             barrel_length_mm=690, status=status),
        dict(brand='Steyr Mannlicher', model_name='SSG 08 .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=600, status=status),
        dict(brand='Steyr Mannlicher', model_name='SSG 08 .338', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.338 Lapua Mag', action='BOLT',
             barrel_length_mm=690, status=status),
        dict(brand='Accuracy International', model_name='AXMC .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Accuracy International', model_name='AXMC .338', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.338 Lapua Mag', action='BOLT',
             barrel_length_mm=686, status=status),
        dict(brand='Accuracy International', model_name='AW50', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.50 BMG', action='BOLT',
             barrel_length_mm=686, status=status),
        dict(brand='Barrett', model_name='MRAD .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Barrett', model_name='MRAD .338', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.338 Lapua Mag', action='BOLT',
             barrel_length_mm=686, status=status),
        dict(brand='Barrett', model_name='MRAD .300NM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.300 Norma Mag', action='BOLT',
             barrel_length_mm=686, status=status),
        dict(brand='Browning', model_name='X-Bolt Pro LR 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Browning', model_name='X-Bolt Pro LR .300WM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.300 Win Mag', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Ruger', model_name='Precision Rifle 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Ruger', model_name='Precision Rifle .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Ruger', model_name='Precision Rifle .300WM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.300 Win Mag', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='Blaser', model_name='R8 Professional .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=580, status=status),
        dict(brand='Blaser', model_name='R8 Ultimate 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=580, status=status),
        dict(brand='Mauser', model_name='M18 .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=560, status=status),
        dict(brand='Mauser', model_name='M18 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=560, status=status),
        dict(brand='Mauser', model_name='M18 .300WM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.300 Win Mag', action='BOLT',
             barrel_length_mm=600, status=status),
        dict(brand='Christensen Arms', model_name='Mesa 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=559, status=status),
        dict(brand='Christensen Arms', model_name='MPR 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Howa', model_name='1500 Hogue .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Howa', model_name='1500 Mini-Action 6.5 Grendel', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Grendel', action='BOLT',
             barrel_length_mm=510, status=status),
        dict(brand='CZ', model_name='600 Range .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=660, status=status),
        dict(brand='CZ', model_name='600 Alpha 6.5CM', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
             barrel_length_mm=560, status=status),
        dict(brand='Winchester', model_name='Model 70 Super Grade .30-06', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.30-06 Springfield', action='BOLT',
             barrel_length_mm=610, status=status),
        dict(brand='Winchester', model_name='Model 70 Featherweight .308', gear_type='FIREARM',
             firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
             barrel_length_mm=559, status=status),
        # ── Semi-auto rifles / carbines ────────────────────────────────────
        dict(brand='Colt', model_name='LE6920', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='Daniel Defense', model_name='DDM4 V7', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=32, status=status),
        dict(brand='Daniel Defense', model_name='DDM4 MK18', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=267, magazine_capacity=30, status=status),
        dict(brand='FN Herstal', model_name='SCAR 16S', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='FN Herstal', model_name='SCAR 17S', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='7.62x51mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=20, status=status),
        dict(brand='Heckler & Koch', model_name='HK416 A5', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='Heckler & Koch', model_name='MR223 A3', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='BCM', model_name='RECCE-16 MCMR', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='LWRC International', model_name='IC-A5', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='SIG Sauer', model_name='MCX Spear', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='6.8x51mm', action='SEMI_AUTO',
             barrel_length_mm=381, magazine_capacity=20, status=status),
        dict(brand='SIG Sauer', model_name='MCX Rattler', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=165, magazine_capacity=30, status=status),
        dict(brand='Aero Precision', model_name='M4E1', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='5.56x45mm NATO', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=30, status=status),
        dict(brand='Ruger', model_name='PC Carbine 9mm', gear_type='FIREARM',
             firearm_type='CARBINE', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=406, magazine_capacity=17, status=status),
        # ── Pistols ──────────────────────────────────────────────────────────
        dict(brand='Glock', model_name='G17 Gen5', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=17, status=status),
        dict(brand='Glock', model_name='G19 Gen5', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=102, magazine_capacity=15, status=status),
        dict(brand='Glock', model_name='G34 Gen5 MOS', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=135, magazine_capacity=17, status=status),
        dict(brand='Glock', model_name='G21 Gen4', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='.45 ACP', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=13, status=status),
        dict(brand='Glock', model_name='G22 Gen4', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='.40 S&W', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=15, status=status),
        dict(brand='SIG Sauer', model_name='P320 M17', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=127, magazine_capacity=21, status=status),
        dict(brand='SIG Sauer', model_name='P320 M18', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=21, status=status),
        dict(brand='SIG Sauer', model_name='P226 Legion', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=112, magazine_capacity=15, status=status),
        dict(brand='SIG Sauer', model_name='P320 X5 Legion', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=127, magazine_capacity=21, status=status),
        dict(brand='Beretta', model_name='92FS', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=125, magazine_capacity=15, status=status),
        dict(brand='Beretta', model_name='APX A1', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=108, magazine_capacity=17, status=status),
        dict(brand='CZ', model_name='75 B', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=16, status=status),
        dict(brand='CZ', model_name='Shadow 2', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=120, magazine_capacity=17, status=status),
        dict(brand='CZ', model_name='P-10 C', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=102, magazine_capacity=15, status=status),
        dict(brand='Walther', model_name='PPQ M2', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=102, magazine_capacity=15, status=status),
        dict(brand='Walther', model_name='PDP Full-Size', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=114, magazine_capacity=18, status=status),
        dict(brand='Heckler & Koch', model_name='VP9', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=108, magazine_capacity=15, status=status),
        dict(brand='Heckler & Koch', model_name='USP .45', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='.45 ACP', action='SEMI_AUTO',
             barrel_length_mm=108, magazine_capacity=12, status=status),
        dict(brand='Smith & Wesson', model_name='M&P 9 M2.0', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=108, magazine_capacity=17, status=status),
        dict(brand='Springfield Armory', model_name='XD-M Elite 5.25"', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='9x19mm', action='SEMI_AUTO',
             barrel_length_mm=133, magazine_capacity=22, status=status),
        dict(brand='FN Herstal', model_name='FNX-45 Tactical', gear_type='FIREARM',
             firearm_type='PISTOL', caliber='.45 ACP', action='SEMI_AUTO',
             barrel_length_mm=127, magazine_capacity=15, status=status),
        # ── Revolvers ─────────────────────────────────────────────────────────
        dict(brand='Smith & Wesson', model_name='686 Plus', gear_type='FIREARM',
             firearm_type='REVOLVER', caliber='.357 Magnum', action='SEMI_AUTO',
             barrel_length_mm=152, magazine_capacity=7, status=status),
        dict(brand='Smith & Wesson', model_name='629 Classic', gear_type='FIREARM',
             firearm_type='REVOLVER', caliber='.44 Magnum', action='SEMI_AUTO',
             barrel_length_mm=152, magazine_capacity=6, status=status),
        dict(brand='Ruger', model_name='GP100', gear_type='FIREARM',
             firearm_type='REVOLVER', caliber='.357 Magnum', action='SEMI_AUTO',
             barrel_length_mm=102, magazine_capacity=6, status=status),
        dict(brand='Ruger', model_name='Super Redhawk Alaskan', gear_type='FIREARM',
             firearm_type='REVOLVER', caliber='.454 Casull', action='SEMI_AUTO',
             barrel_length_mm=64, magazine_capacity=6, status=status),
        dict(brand='Colt', model_name='Python 4.25"', gear_type='FIREARM',
             firearm_type='REVOLVER', caliber='.357 Magnum', action='SEMI_AUTO',
             barrel_length_mm=108, magazine_capacity=6, status=status),
        # ── Shotguns ───────────────────────────────────────────────────────────
        dict(brand='Mossberg', model_name='500 ATI Tactical', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='PUMP',
             barrel_length_mm=470, magazine_capacity=8, status=status),
        dict(brand='Mossberg', model_name='590A1', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='PUMP',
             barrel_length_mm=508, magazine_capacity=9, status=status),
        dict(brand='Remington', model_name='870 Express', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='PUMP',
             barrel_length_mm=711, magazine_capacity=4, status=status),
        dict(brand='Remington', model_name='870 Tactical', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='PUMP',
             barrel_length_mm=470, magazine_capacity=6, status=status),
        dict(brand='Benelli', model_name='M2 Field', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='SEMI_AUTO',
             barrel_length_mm=711, magazine_capacity=3, status=status),
        dict(brand='Benelli', model_name='M4 Tactical', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='SEMI_AUTO',
             barrel_length_mm=470, magazine_capacity=5, status=status),
        dict(brand='Beretta', model_name='A400 Xtreme Plus', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='SEMI_AUTO',
             barrel_length_mm=762, magazine_capacity=3, status=status),
        dict(brand='Browning', model_name='Maxus II', gear_type='FIREARM',
             firearm_type='SHOTGUN', caliber='12 Gauge', action='SEMI_AUTO',
             barrel_length_mm=762, magazine_capacity=4, status=status),
    ]

    for data in firearms:
        Firearm.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            caliber=data['caliber'],
            defaults=data,
        )


def populate_scopes(apps, schema_editor):
    Scope = _get(apps, 'Scope')
    status = _verified(apps)

    scopes = [
        dict(brand='Vortex', model_name='Razor HD Gen III 1-10x24', gear_type='SCOPE',
             magnification_min=1, magnification_max=10, objective_diameter_mm=24,
             tube_diameter_mm=34, reticle_type='ILLUMINATED', status=status),
        dict(brand='Vortex', model_name='Razor HD Gen III 6-36x56', gear_type='SCOPE',
             magnification_min=6, magnification_max=36, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Vortex', model_name='Viper PST Gen II 5-25x50', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Vortex', model_name='Viper PST Gen II 2-10x32', gear_type='SCOPE',
             magnification_min=2, magnification_max=10, objective_diameter_mm=32,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Vortex', model_name='Strike Eagle 1-8x24', gear_type='SCOPE',
             magnification_min=1, magnification_max=8, objective_diameter_mm=24,
             tube_diameter_mm=30, reticle_type='ILLUMINATED', status=status),
        dict(brand='Vortex', model_name='Strike Eagle 5-25x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='ETCHED_GLASS', status=status),
        dict(brand='Vortex', model_name='Crossfire II 6-18x44', gear_type='SCOPE',
             magnification_min=6, magnification_max=18, objective_diameter_mm=44,
             tube_diameter_mm=25, reticle_type='BDC', status=status),
        dict(brand='Vortex', model_name='Diamondback Tactical 6-24x50', gear_type='SCOPE',
             magnification_min=6, magnification_max=24, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Vortex', model_name='Golden Eagle HD 15-60x52', gear_type='SCOPE',
             magnification_min=15, magnification_max=60, objective_diameter_mm=52,
             tube_diameter_mm=35, reticle_type='DUPLEX', status=status),
        dict(brand='Leupold', model_name='Mark 5HD 5-25x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=56,
             tube_diameter_mm=35, reticle_type='MIL_DOT', status=status),
        dict(brand='Leupold', model_name='Mark 5HD 3.6-18x44', gear_type='SCOPE',
             magnification_min=4, magnification_max=18, objective_diameter_mm=44,
             tube_diameter_mm=35, reticle_type='MIL_DOT', status=status),
        dict(brand='Leupold', model_name='VX-6HD 3-18x50', gear_type='SCOPE',
             magnification_min=3, magnification_max=18, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='ILLUMINATED', status=status),
        dict(brand='Leupold', model_name='VX-6HD 4-24x52', gear_type='SCOPE',
             magnification_min=4, magnification_max=24, objective_diameter_mm=52,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Leupold', model_name='Mark 3HD 4-12x40', gear_type='SCOPE',
             magnification_min=4, magnification_max=12, objective_diameter_mm=40,
             tube_diameter_mm=25, reticle_type='DUPLEX', status=status),
        dict(brand='Leupold', model_name='Mark 4 LR/T 8.5-25x50', gear_type='SCOPE',
             magnification_min=9, magnification_max=25, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='ATACR 7-35x56 F1', gear_type='SCOPE',
             magnification_min=7, magnification_max=35, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='ATACR 5-25x56 F1', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='ATACR 4-16x42 F1', gear_type='SCOPE',
             magnification_min=4, magnification_max=16, objective_diameter_mm=42,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='NXS 3.5-15x50', gear_type='SCOPE',
             magnification_min=4, magnification_max=15, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='NXS 8-32x56', gear_type='SCOPE',
             magnification_min=8, magnification_max=32, objective_diameter_mm=56,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='SHV 4-14x50', gear_type='SCOPE',
             magnification_min=4, magnification_max=14, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Nightforce', model_name='SHV 3-10x42', gear_type='SCOPE',
             magnification_min=3, magnification_max=10, objective_diameter_mm=42,
             tube_diameter_mm=30, reticle_type='DUPLEX', status=status),
        dict(brand='Schmidt & Bender', model_name='PM II 5-25x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Schmidt & Bender', model_name='PM II 3-20x50', gear_type='SCOPE',
             magnification_min=3, magnification_max=20, objective_diameter_mm=50,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Schmidt & Bender', model_name='PM II 4-16x42', gear_type='SCOPE',
             magnification_min=4, magnification_max=16, objective_diameter_mm=42,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Schmidt & Bender', model_name='Polar T96 6-36x56', gear_type='SCOPE',
             magnification_min=6, magnification_max=36, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='ETCHED_GLASS', status=status),
        dict(brand='Swarovski', model_name='Z8i 2.3-18x56', gear_type='SCOPE',
             magnification_min=2, magnification_max=18, objective_diameter_mm=56,
             tube_diameter_mm=30, reticle_type='ILLUMINATED', status=status),
        dict(brand='Swarovski', model_name='Z8i 3.5-28x50', gear_type='SCOPE',
             magnification_min=4, magnification_max=28, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='ILLUMINATED', status=status),
        dict(brand='Swarovski', model_name='Z5i 3.5-18x44', gear_type='SCOPE',
             magnification_min=4, magnification_max=18, objective_diameter_mm=44,
             tube_diameter_mm=25, reticle_type='ILLUMINATED', status=status),
        dict(brand='Zeiss', model_name='Victory V8 4.8-35x60', gear_type='SCOPE',
             magnification_min=5, magnification_max=35, objective_diameter_mm=60,
             tube_diameter_mm=36, reticle_type='ILLUMINATED', status=status),
        dict(brand='Zeiss', model_name='Conquest V4 6-24x50', gear_type='SCOPE',
             magnification_min=6, magnification_max=24, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Zeiss', model_name='LRP S5 6-36x56', gear_type='SCOPE',
             magnification_min=6, magnification_max=36, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='March', model_name='FX 5-40x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=40, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='March', model_name='FX 8-80x56', gear_type='SCOPE',
             magnification_min=8, magnification_max=80, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='ETCHED_GLASS', status=status),
        dict(brand='Bushnell', model_name='Elite Tactical DMR3 3.5-21x50', gear_type='SCOPE',
             magnification_min=4, magnification_max=21, objective_diameter_mm=50,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Bushnell', model_name='Elite Tactical XRS3 6-36x56', gear_type='SCOPE',
             magnification_min=6, magnification_max=36, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Bushnell', model_name='Prime 3-12x40', gear_type='SCOPE',
             magnification_min=3, magnification_max=12, objective_diameter_mm=40,
             tube_diameter_mm=25, reticle_type='BDC', status=status),
        dict(brand='Athlon', model_name='Argos BTR Gen2 6-24x50', gear_type='SCOPE',
             magnification_min=6, magnification_max=24, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Athlon', model_name='Cronus BTR Gen2 4.5-29x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=29, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Kahles', model_name='K525i 5-25x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=25, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Kahles', model_name='K318i 3.5-18x50', gear_type='SCOPE',
             magnification_min=4, magnification_max=18, objective_diameter_mm=50,
             tube_diameter_mm=30, reticle_type='MIL_DOT', status=status),
        dict(brand='Steiner', model_name='T6Xi 5-30x56', gear_type='SCOPE',
             magnification_min=5, magnification_max=30, objective_diameter_mm=56,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
        dict(brand='Steiner', model_name='T5Xi 3-15x50', gear_type='SCOPE',
             magnification_min=3, magnification_max=15, objective_diameter_mm=50,
             tube_diameter_mm=34, reticle_type='MIL_DOT', status=status),
    ]

    for data in scopes:
        Scope.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            defaults=data,
        )


def populate_suppressors(apps, schema_editor):
    Suppressor = _get(apps, 'Suppressor')
    status = _verified(apps)

    suppressors = [
        dict(brand='SilencerCo', model_name='Omega 300', gear_type='SUPPRESSOR',
             max_caliber='.300 Win Mag', thread_pitch='5/8-24',
             length_mm=178, weight_g=454, status=status),
        dict(brand='SilencerCo', model_name='Saker ASR 762', gear_type='SUPPRESSOR',
             max_caliber='7.62mm NATO', thread_pitch='ASR',
             length_mm=203, weight_g=538, status=status),
        dict(brand='SilencerCo', model_name='Harvester Big Bore', gear_type='SUPPRESSOR',
             max_caliber='.338 Lapua Mag', thread_pitch='5/8-24',
             length_mm=229, weight_g=596, status=status),
        dict(brand='SilencerCo', model_name='Octane 9', gear_type='SUPPRESSOR',
             max_caliber='9mm', thread_pitch='1/2-28',
             length_mm=203, weight_g=340, status=status),
        dict(brand='SilencerCo', model_name='Hybrid 46M', gear_type='SUPPRESSOR',
             max_caliber='.458 SOCOM', thread_pitch='5/8-24',
             length_mm=210, weight_g=680, status=status),
        dict(brand='Dead Air', model_name='Sandman-S', gear_type='SUPPRESSOR',
             max_caliber='7.62mm NATO', thread_pitch='KeyMo',
             length_mm=178, weight_g=540, status=status),
        dict(brand='Dead Air', model_name='Sandman-L', gear_type='SUPPRESSOR',
             max_caliber='7.62mm NATO', thread_pitch='KeyMo',
             length_mm=229, weight_g=680, status=status),
        dict(brand='Dead Air', model_name='Nomad-L', gear_type='SUPPRESSOR',
             max_caliber='.300 Win Mag', thread_pitch='5/8-24',
             length_mm=222, weight_g=553, status=status),
        dict(brand='Dead Air', model_name='Ghost 45M', gear_type='SUPPRESSOR',
             max_caliber='.45 ACP', thread_pitch='5/8-24',
             length_mm=203, weight_g=454, status=status),
        dict(brand='Thunderbeast', model_name='Ultra 7', gear_type='SUPPRESSOR',
             max_caliber='.308 Win', thread_pitch='5/8-24',
             length_mm=178, weight_g=380, status=status),
        dict(brand='Thunderbeast', model_name='Ultra 9', gear_type='SUPPRESSOR',
             max_caliber='.300 Win Mag', thread_pitch='5/8-24',
             length_mm=229, weight_g=453, status=status),
        dict(brand='Rugged', model_name='Obsidian45', gear_type='SUPPRESSOR',
             max_caliber='.45 ACP', thread_pitch='5/8-24',
             length_mm=190, weight_g=369, status=status),
        dict(brand='Rugged', model_name='Surge 762', gear_type='SUPPRESSOR',
             max_caliber='7.62mm NATO', thread_pitch='5/8-24',
             length_mm=191, weight_g=529, status=status),
        dict(brand='Ase Utra', model_name='S-series S20', gear_type='SUPPRESSOR',
             max_caliber='.308 Win', thread_pitch='M15x1',
             length_mm=200, weight_g=410, status=status),
        dict(brand='Ase Utra', model_name='Radien', gear_type='SUPPRESSOR',
             max_caliber='.338 Lapua Mag', thread_pitch='M18x1.5',
             length_mm=235, weight_g=595, status=status),
        dict(brand='Hausken', model_name='JD224 Whisper', gear_type='SUPPRESSOR',
             max_caliber='.308 Win', thread_pitch='M14x1',
             length_mm=218, weight_g=440, status=status),
        dict(brand='Surefire', model_name='SOCOM762-RC2', gear_type='SUPPRESSOR',
             max_caliber='7.62mm NATO', thread_pitch='SOCOM',
             length_mm=203, weight_g=680, status=status),
        dict(brand='Gemtech', model_name='Sandstorm', gear_type='SUPPRESSOR',
             max_caliber='.300 Win Mag', thread_pitch='5/8-24',
             length_mm=210, weight_g=567, status=status),
    ]

    for data in suppressors:
        Suppressor.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            defaults=data,
        )


def populate_bipods(apps, schema_editor):
    Bipod = _get(apps, 'Bipod')
    status = _verified(apps)

    bipods = [
        dict(brand='Harris', model_name='S-BRM 6-9"', gear_type='BIPOD',
             min_height_mm=152, max_height_mm=229,
             attachment_type='SLING_STUD', status=status),
        dict(brand='Harris', model_name='BRMS 9-13"', gear_type='BIPOD',
             min_height_mm=229, max_height_mm=330,
             attachment_type='SLING_STUD', status=status),
        dict(brand='Harris', model_name='S-L 9-13" Notched', gear_type='BIPOD',
             min_height_mm=229, max_height_mm=330,
             attachment_type='PICATINNY', status=status),
        dict(brand='Atlas', model_name='BT10 V8 5H', gear_type='BIPOD',
             min_height_mm=145, max_height_mm=229,
             attachment_type='PICATINNY', status=status),
        dict(brand='Atlas', model_name='BT47 AccuShot 5H MLOK', gear_type='BIPOD',
             min_height_mm=145, max_height_mm=229,
             attachment_type='MLOK', status=status),
        dict(brand='Magpul', model_name='Bipod MLOK', gear_type='BIPOD',
             min_height_mm=180, max_height_mm=267,
             attachment_type='MLOK', status=status),
        dict(brand='Magpul', model_name='Bipod Picatinny', gear_type='BIPOD',
             min_height_mm=180, max_height_mm=267,
             attachment_type='PICATINNY', status=status),
        dict(brand='Accu-Shot', model_name='PSSS-11 Stalker', gear_type='BIPOD',
             min_height_mm=127, max_height_mm=279,
             attachment_type='PICATINNY', status=status),
        dict(brand='MDT', model_name='Fieldsport Bipod', gear_type='BIPOD',
             min_height_mm=152, max_height_mm=267,
             attachment_type='ARCA_SWISS', status=status),
        dict(brand='Area 419', model_name='Arcalock Bipod 6-9"', gear_type='BIPOD',
             min_height_mm=152, max_height_mm=229,
             attachment_type='ARCA_SWISS', status=status),
    ]

    for data in bipods:
        Bipod.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            defaults=data,
        )


def populate_magazines(apps, schema_editor):
    Magazine = _get(apps, 'Magazine')
    status = _verified(apps)

    magazines = [
        dict(brand='Magpul', model_name='PMAG 30 AR/M4 Gen M3', gear_type='MAGAZINE',
             caliber='5.56x45mm NATO', capacity=30, status=status),
        dict(brand='Magpul', model_name='PMAG 20 AR/M4 Gen M3', gear_type='MAGAZINE',
             caliber='5.56x45mm NATO', capacity=20, status=status),
        dict(brand='Magpul', model_name='PMAG 10 AR/M4 Gen M3', gear_type='MAGAZINE',
             caliber='5.56x45mm NATO', capacity=10, status=status),
        dict(brand='Magpul', model_name='PMAG 20 SR/LR Gen M3', gear_type='MAGAZINE',
             caliber='.308 Win', capacity=20, status=status),
        dict(brand='Magpul', model_name='PMAG 10 SR/LR Gen M3', gear_type='MAGAZINE',
             caliber='.308 Win', capacity=10, status=status),
        dict(brand='Accuracy International', model_name='AICS 10-rd .308', gear_type='MAGAZINE',
             caliber='.308 Win', capacity=10, status=status),
        dict(brand='Accuracy International', model_name='AICS 5-rd .308', gear_type='MAGAZINE',
             caliber='.308 Win', capacity=5, status=status),
        dict(brand='Accuracy International', model_name='AICS 10-rd .338 Lapua', gear_type='MAGAZINE',
             caliber='.338 Lapua Mag', capacity=10, status=status),
        dict(brand='Accuracy International', model_name='AICS 5-rd .338 Lapua', gear_type='MAGAZINE',
             caliber='.338 Lapua Mag', capacity=5, status=status),
        dict(brand='Glock', model_name='OEM 9mm 17-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=17, status=status),
        dict(brand='Glock', model_name='OEM 9mm 15-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=15, status=status),
        dict(brand='Glock', model_name='OEM 9mm 33-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=33, status=status),
        dict(brand='Glock', model_name='OEM .40 S&W 15-rd', gear_type='MAGAZINE',
             caliber='.40 S&W', capacity=15, status=status),
        dict(brand='SIG Sauer', model_name='P320/P250 9mm 21-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=21, status=status),
        dict(brand='SIG Sauer', model_name='P226 9mm 15-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=15, status=status),
        dict(brand='CZ', model_name='CZ 75 9mm 16-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=16, status=status),
        dict(brand='CZ', model_name='CZ Shadow 2 9mm 17-rd', gear_type='MAGAZINE',
             caliber='9x19mm', capacity=17, status=status),
        dict(brand='Tikka', model_name='T3 .308 5-rd', gear_type='MAGAZINE',
             caliber='.308 Win', capacity=5, status=status),
        dict(brand='Tikka', model_name='T3 6.5 Creedmoor 5-rd', gear_type='MAGAZINE',
             caliber='6.5 Creedmoor', capacity=5, status=status),
    ]

    for data in magazines:
        Magazine.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            caliber=data.get('caliber', ''),
            defaults=data,
        )


def populate_ammo(apps, schema_editor):
    Ammo = _get(apps, 'Ammo')
    status = _verified(apps)

    ammo_list = [
        # ── .308 Win ──────────────────────────────────────────────────────────
        dict(brand='Federal', name='Gold Medal Match 175gr', caliber='.308 Win',
             bullet_weight_gr='175', bullet_type='SMK',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2600, box_count=20, status=status),
        dict(brand='Federal', name='Gold Medal Match 168gr', caliber='.308 Win',
             bullet_weight_gr='168', bullet_type='SMK',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2650, box_count=20, status=status),
        dict(brand='Hornady', name='ELD Match 168gr', caliber='.308 Win',
             bullet_weight_gr='168', bullet_type='HPBT',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2710, box_count=20, status=status),
        dict(brand='Hornady', name='ELD Match 178gr', caliber='.308 Win',
             bullet_weight_gr='178', bullet_type='HPBT',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2600, box_count=20, status=status),
        dict(brand='Lapua', name='Scenar-L OT 175gr', caliber='.308 Win',
             bullet_weight_gr='175', bullet_type='HPBT',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2575, box_count=50, status=status),
        dict(brand='Lapua', name='Scenar-L OT 155gr', caliber='.308 Win',
             bullet_weight_gr='155', bullet_type='HPBT',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2953, box_count=50, status=status),
        dict(brand='Berger', name='Hybrid OTM Tactical 185gr', caliber='.308 Win',
             bullet_weight_gr='185', bullet_type='HPBT',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2600, box_count=20, status=status),
        dict(brand='Black Hills', name='Match 175gr SMK', caliber='.308 Win',
             bullet_weight_gr='175', bullet_type='SMK',
             primer_size='LR', case_material='BRASS',
             muzzle_velocity_fps=2600, box_count=20, status=status),
        # ── 6.5 Creedmoor ─────────────────────────────────────────────────────
        dict(brand='Federal', name='Gold Medal Match 140gr SMK', caliber='6.5 Creedmoor',
             bullet_weight_gr='140', bullet_type='SMK',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2710, box_count=20, status=status),
        dict(brand='Hornady', name='ELD Match 147gr', caliber='6.5 Creedmoor',
             bullet_weight_gr='147', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2695, box_count=20, status=status),
        dict(brand='Hornady', name='ELD Match 140gr', caliber='6.5 Creedmoor',
             bullet_weight_gr='140', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2710, box_count=20, status=status),
        dict(brand='Lapua', name='Scenar-L OT 136gr', caliber='6.5 Creedmoor',
             bullet_weight_gr='136', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2822, box_count=50, status=status),
        dict(brand='Berger', name='Hybrid OTM 130gr', caliber='6.5 Creedmoor',
             bullet_weight_gr='130', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2875, box_count=20, status=status),
        dict(brand='Nosler', name='RDF 140gr', caliber='6.5 Creedmoor',
             bullet_weight_gr='140', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2700, box_count=20, status=status),
        # ── .300 Win Mag ──────────────────────────────────────────────────────
        dict(brand='Federal', name='Gold Medal Match 215gr A-Tip', caliber='.300 Win Mag',
             bullet_weight_gr='215', bullet_type='A_TIP',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2830, box_count=20, status=status),
        dict(brand='Hornady', name='ELD Match 195gr', caliber='.300 Win Mag',
             bullet_weight_gr='195', bullet_type='HPBT',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2930, box_count=20, status=status),
        dict(brand='Berger', name='Hybrid OTM 215gr', caliber='.300 Win Mag',
             bullet_weight_gr='215', bullet_type='HPBT',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2770, box_count=20, status=status),
        # ── .338 Lapua Mag ────────────────────────────────────────────────────
        dict(brand='Lapua', name='Scenar-L OT 250gr', caliber='.338 Lapua Mag',
             bullet_weight_gr='250', bullet_type='HPBT',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2870, box_count=10, status=status),
        dict(brand='Federal', name='Gold Medal Berger 300gr', caliber='.338 Lapua Mag',
             bullet_weight_gr='300', bullet_type='HPBT',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2650, box_count=20, status=status),
        dict(brand='Hornady', name='Precision Hunter 270gr', caliber='.338 Lapua Mag',
             bullet_weight_gr='270', bullet_type='HPBT',
             primer_size='LRM', case_material='BRASS',
             muzzle_velocity_fps=2745, box_count=20, status=status),
        # ── 5.56x45mm NATO ────────────────────────────────────────────────────
        dict(brand='Federal', name='XM193 55gr', caliber='5.56x45mm NATO',
             bullet_weight_gr='55', bullet_type='FMJ',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=3165, box_count=20, status=status),
        dict(brand='Federal', name='XM855 62gr', caliber='5.56x45mm NATO',
             bullet_weight_gr='62', bullet_type='FMJ',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=3020, box_count=20, status=status),
        dict(brand='Hornady', name='TAP FPD 75gr', caliber='5.56x45mm NATO',
             bullet_weight_gr='75', bullet_type='HP',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2790, box_count=20, status=status),
        dict(brand='Black Hills', name='77gr OTM', caliber='5.56x45mm NATO',
             bullet_weight_gr='77', bullet_type='HPBT',
             primer_size='SR', case_material='BRASS',
             muzzle_velocity_fps=2750, box_count=50, status=status),
        # ── 9x19mm ────────────────────────────────────────────────────────────
        dict(brand='Federal', name='HST 124gr', caliber='9x19mm',
             bullet_weight_gr='124', bullet_type='HP',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1150, box_count=20, status=status),
        dict(brand='Federal', name='HST 147gr', caliber='9x19mm',
             bullet_weight_gr='147', bullet_type='HP',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1000, box_count=20, status=status),
        dict(brand='Speer', name='Gold Dot 124gr', caliber='9x19mm',
             bullet_weight_gr='124', bullet_type='HP',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1150, box_count=20, status=status),
        dict(brand='Hornady', name='Critical Defense 115gr', caliber='9x19mm',
             bullet_weight_gr='115', bullet_type='HP',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1140, box_count=25, status=status),
        dict(brand='Winchester', name='PDX1 Defender 124gr', caliber='9x19mm',
             bullet_weight_gr='124', bullet_type='HP',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1175, box_count=20, status=status),
        dict(brand='Federal', name='American Eagle FMJ 115gr', caliber='9x19mm',
             bullet_weight_gr='115', bullet_type='FMJ',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1180, box_count=50, status=status),
        dict(brand='Federal', name='American Eagle FMJ 124gr', caliber='9x19mm',
             bullet_weight_gr='124', bullet_type='FMJ',
             primer_size='SP', case_material='BRASS',
             muzzle_velocity_fps=1150, box_count=50, status=status),
        # ── .45 ACP ───────────────────────────────────────────────────────────
        dict(brand='Federal', name='HST 230gr', caliber='.45 ACP',
             bullet_weight_gr='230', bullet_type='HP',
             primer_size='LP', case_material='BRASS',
             muzzle_velocity_fps=890, box_count=20, status=status),
        dict(brand='Speer', name='Gold Dot 230gr', caliber='.45 ACP',
             bullet_weight_gr='230', bullet_type='HP',
             primer_size='LP', case_material='BRASS',
             muzzle_velocity_fps=890, box_count=20, status=status),
        dict(brand='Hornady', name='Critical Duty 220gr', caliber='.45 ACP',
             bullet_weight_gr='220', bullet_type='HP',
             primer_size='LP', case_material='BRASS',
             muzzle_velocity_fps=975, box_count=20, status=status),
        # ── 12 Gauge ──────────────────────────────────────────────────────────
        dict(brand='Federal', name='Premium 00 Buck', caliber='12 Gauge',
             bullet_weight_gr='486', bullet_type='SP',
             case_material='BRASS',
             muzzle_velocity_fps=1325, box_count=5, status=status),
        dict(brand='Hornady', name='Critical Defense 00 Buck', caliber='12 Gauge',
             bullet_weight_gr='486', bullet_type='SP',
             case_material='BRASS',
             muzzle_velocity_fps=1600, box_count=10, status=status),
        dict(brand='Winchester', name='Super-X Rifled Slug', caliber='12 Gauge',
             bullet_weight_gr='437', bullet_type='SP',
             case_material='BRASS',
             muzzle_velocity_fps=1600, box_count=5, status=status),
    ]

    for data in ammo_list:
        Ammo.objects.get_or_create(
            brand=data['brand'],
            name=data['name'],
            caliber=data['caliber'],
            defaults=data,
        )


def populate_reloading_components(apps, schema_editor):
    Primer = _get(apps, 'Primer')
    Brass = _get(apps, 'Brass')
    Bullet = _get(apps, 'Bullet')
    Powder = _get(apps, 'Powder')

    # ── Primers ───────────────────────────────────────────────────────────────
    primers = [
        dict(brand='CCI', name='200 Large Rifle', size='LR'),
        dict(brand='CCI', name='250 Large Rifle Magnum', size='LRM'),
        dict(brand='CCI', name='400 Small Rifle', size='SR'),
        dict(brand='CCI', name='450 Small Rifle Magnum', size='SR'),
        dict(brand='CCI', name='500 Small Pistol', size='SP'),
        dict(brand='CCI', name='550 Small Pistol Magnum', size='SP'),
        dict(brand='CCI', name='300 Large Pistol', size='LP'),
        dict(brand='CCI', name='350 Large Pistol Magnum', size='LP'),
        dict(brand='Federal', name='210 Large Rifle', size='LR'),
        dict(brand='Federal', name='210M Large Rifle Match', size='LR'),
        dict(brand='Federal', name='215M Large Rifle Magnum Match', size='LRM'),
        dict(brand='Federal', name='205M Small Rifle Match', size='SR'),
        dict(brand='Federal', name='100 Small Pistol', size='SP'),
        dict(brand='Federal', name='150 Large Pistol', size='LP'),
        dict(brand='Winchester', name='WLR Large Rifle', size='LR'),
        dict(brand='Winchester', name='WLRM Large Rifle Magnum', size='LRM'),
        dict(brand='Winchester', name='WSR Small Rifle', size='SR'),
        dict(brand='Winchester', name='WSP Small Pistol', size='SP'),
        dict(brand='Winchester', name='WLP Large Pistol', size='LP'),
        dict(brand='Remington', name='9-1/2 Large Rifle', size='LR'),
        dict(brand='Remington', name='9-1/2M Large Rifle Magnum', size='LRM'),
        dict(brand='Remington', name='6-1/2 Small Rifle', size='SR'),
        dict(brand='Remington', name='1-1/2 Small Pistol', size='SP'),
        dict(brand='Lapua', name='Large Rifle', size='LR'),
        dict(brand='Lapua', name='Small Rifle', size='SR'),
        dict(brand='Murom', name='KVB-7.62 Large Rifle', size='LR'),
        dict(brand='Fiocchi', name='Small Rifle', size='SR'),
        dict(brand='Fiocchi', name='Large Rifle', size='LR'),
    ]

    for data in primers:
        Primer.objects.get_or_create(brand=data['brand'], name=data['name'], defaults=data)

    # ── Brass ─────────────────────────────────────────────────────────────────
    brass_list = [
        dict(brand='Lapua', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Lapua', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Lapua', caliber='.338 Lapua Mag', primer_pocket='LRM', trim_length_mm='68.50'),
        dict(brand='Lapua', caliber='.30-06 Springfield', primer_pocket='LR', trim_length_mm='62.90'),
        dict(brand='Peterson', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Peterson', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Peterson', caliber='.300 Win Mag', primer_pocket='LRM', trim_length_mm='64.00'),
        dict(brand='Peterson', caliber='6mm Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Starline', caliber='9x19mm', primer_pocket='SP', trim_length_mm='19.15'),
        dict(brand='Starline', caliber='.45 ACP', primer_pocket='LP', trim_length_mm='22.86'),
        dict(brand='Starline', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Starline', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Nosler', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Nosler', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Federal', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Federal', caliber='.30-06 Springfield', primer_pocket='LR', trim_length_mm='62.90'),
        dict(brand='Winchester', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Winchester', caliber='9x19mm', primer_pocket='SP', trim_length_mm='19.15'),
        dict(brand='Remington', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
        dict(brand='Hornady', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Alpha Munitions', caliber='6.5 Creedmoor', primer_pocket='SR', trim_length_mm='47.50'),
        dict(brand='Alpha Munitions', caliber='.308 Win', primer_pocket='LR', trim_length_mm='51.18'),
    ]

    for data in brass_list:
        Brass.objects.get_or_create(brand=data['brand'], caliber=data['caliber'], defaults=data)

    # ── Bullets ───────────────────────────────────────────────────────────────
    bullets = [
        dict(brand='Sierra', model_name='MatchKing 175gr HPBT .30 cal', weight_gr='175',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.505', bc_g7='0.259'),
        dict(brand='Sierra', model_name='MatchKing 168gr HPBT .30 cal', weight_gr='168',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.475', bc_g7='0.243'),
        dict(brand='Sierra', model_name='MatchKing 155gr HPBT .30 cal', weight_gr='155',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.447', bc_g7='0.227'),
        dict(brand='Sierra', model_name='MatchKing 185gr HPBT .30 cal', weight_gr='185',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.544', bc_g7='0.279'),
        dict(brand='Sierra', model_name='MatchKing 140gr HPBT 6.5mm', weight_gr='140',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.535', bc_g7='0.267'),
        dict(brand='Sierra', model_name='Tipped MatchKing 175gr .30 cal', weight_gr='175',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.530', bc_g7='0.271'),
        dict(brand='Sierra', model_name='Tipped MatchKing 140gr 6.5mm', weight_gr='140',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.562', bc_g7='0.289'),
        dict(brand='Sierra', model_name='MatchKing 300gr HPBT .338 cal', weight_gr='300',
             bullet_type='HPBT', diameter_mm='8.58', bc_g1='0.768', bc_g7='0.388'),
        dict(brand='Hornady', model_name='ELD-M 168gr .30 cal', weight_gr='168',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.475', bc_g7='0.243'),
        dict(brand='Hornady', model_name='ELD-M 178gr .30 cal', weight_gr='178',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.536', bc_g7='0.274'),
        dict(brand='Hornady', model_name='ELD-M 147gr 6.5mm', weight_gr='147',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.697', bc_g7='0.353'),
        dict(brand='Hornady', model_name='ELD-M 140gr 6.5mm', weight_gr='140',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.646', bc_g7='0.326'),
        dict(brand='Hornady', model_name='A-Tip 230gr .30 cal', weight_gr='230',
             bullet_type='A_TIP', diameter_mm='7.82', bc_g1='0.818', bc_g7='0.414'),
        dict(brand='Hornady', model_name='A-Tip 153.5gr 6.5mm', weight_gr='153.5',
             bullet_type='A_TIP', diameter_mm='6.71', bc_g1='0.756', bc_g7='0.381'),
        dict(brand='Hornady', model_name='HAP 124gr 9mm', weight_gr='124',
             bullet_type='HPBT', diameter_mm='9.02'),
        dict(brand='Berger', model_name='Hybrid OTM Tactical 185gr .30 cal', weight_gr='185',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.566', bc_g7='0.289'),
        dict(brand='Berger', model_name='Hybrid OTM Tactical 215gr .30 cal', weight_gr='215',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.730', bc_g7='0.370'),
        dict(brand='Berger', model_name='Hybrid OTM 130gr 6.5mm', weight_gr='130',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.564', bc_g7='0.279'),
        dict(brand='Berger', model_name='Hybrid OTM 140gr 6.5mm', weight_gr='140',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.620', bc_g7='0.315'),
        dict(brand='Berger', model_name='VLD Target 168gr .30 cal', weight_gr='168',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.500', bc_g7='0.252'),
        dict(brand='Lapua', model_name='Scenar-L 155gr .30 cal', weight_gr='155',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.508', bc_g7='0.258'),
        dict(brand='Lapua', model_name='Scenar-L 175gr .30 cal', weight_gr='175',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.528', bc_g7='0.268'),
        dict(brand='Lapua', model_name='Scenar-L 136gr 6.5mm', weight_gr='136',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.547', bc_g7='0.276'),
        dict(brand='Lapua', model_name='Scenar-L 250gr .338 cal', weight_gr='250',
             bullet_type='HPBT', diameter_mm='8.58', bc_g1='0.683', bc_g7='0.344'),
        dict(brand='Nosler', model_name='RDF 140gr 6.5mm', weight_gr='140',
             bullet_type='HPBT', diameter_mm='6.71', bc_g1='0.610', bc_g7='0.310'),
        dict(brand='Nosler', model_name='RDF 168gr .30 cal', weight_gr='168',
             bullet_type='HPBT', diameter_mm='7.82', bc_g1='0.534', bc_g7='0.271'),
        dict(brand='Speer', model_name='Gold Dot 124gr 9mm HP', weight_gr='124',
             bullet_type='HP', diameter_mm='9.02'),
        dict(brand='Berry', model_name='Plated RN 124gr 9mm', weight_gr='124',
             bullet_type='FMJ', diameter_mm='9.02'),
    ]

    for data in bullets:
        Bullet.objects.get_or_create(
            brand=data['brand'],
            model_name=data['model_name'],
            weight_gr=data['weight_gr'],
            defaults=data,
        )

    # ── Powders ───────────────────────────────────────────────────────────────
    powders = [
        dict(brand='Hodgdon', name='Varget', powder_type='EXTRUDED', burn_rate_index=160),
        dict(brand='Hodgdon', name='H4350', powder_type='EXTRUDED', burn_rate_index=200),
        dict(brand='Hodgdon', name='H4895', powder_type='EXTRUDED', burn_rate_index=145),
        dict(brand='Hodgdon', name='H1000', powder_type='EXTRUDED', burn_rate_index=250),
        dict(brand='Hodgdon', name='Retumbo', powder_type='EXTRUDED', burn_rate_index=280),
        dict(brand='Hodgdon', name='H380', powder_type='BALL', burn_rate_index=170),
        dict(brand='Hodgdon', name='CFE 223', powder_type='BALL', burn_rate_index=130),
        dict(brand='Hodgdon', name='CFE Pistol', powder_type='BALL', burn_rate_index=60),
        dict(brand='Hodgdon', name='Titegroup', powder_type='BALL', burn_rate_index=30),
        dict(brand='Hodgdon', name='HS-6', powder_type='BALL', burn_rate_index=70),
        dict(brand='Hodgdon', name='Lil Gun', powder_type='BALL', burn_rate_index=75),
        dict(brand='IMR', name='4064', powder_type='EXTRUDED', burn_rate_index=155),
        dict(brand='IMR', name='4350', powder_type='EXTRUDED', burn_rate_index=198),
        dict(brand='IMR', name='4166 Enduron', powder_type='EXTRUDED', burn_rate_index=162),
        dict(brand='IMR', name='7977', powder_type='EXTRUDED', burn_rate_index=270),
        dict(brand='IMR', name='4451 Enduron', powder_type='EXTRUDED', burn_rate_index=205),
        dict(brand='IMR', name='4955', powder_type='EXTRUDED', burn_rate_index=230),
        dict(brand='Vihtavuori', name='N140', powder_type='EXTRUDED', burn_rate_index=152),
        dict(brand='Vihtavuori', name='N150', powder_type='EXTRUDED', burn_rate_index=185),
        dict(brand='Vihtavuori', name='N160', powder_type='EXTRUDED', burn_rate_index=230),
        dict(brand='Vihtavuori', name='N165', powder_type='EXTRUDED', burn_rate_index=255),
        dict(brand='Vihtavuori', name='N170', powder_type='EXTRUDED', burn_rate_index=280),
        dict(brand='Vihtavuori', name='N540', powder_type='BALL', burn_rate_index=130),
        dict(brand='Vihtavuori', name='N560', powder_type='BALL', burn_rate_index=215),
        dict(brand='Vihtavuori', name='3N37', powder_type='BALL', burn_rate_index=65),
        dict(brand='Vihtavuori', name='N320', powder_type='FLAKE', burn_rate_index=40),
        dict(brand='Vihtavuori', name='N330', powder_type='BALL', burn_rate_index=50),
        dict(brand='Alliant', name='Reloder 16', powder_type='EXTRUDED', burn_rate_index=170),
        dict(brand='Alliant', name='Reloder 26', powder_type='EXTRUDED', burn_rate_index=240),
        dict(brand='Alliant', name='Reloder 33', powder_type='EXTRUDED', burn_rate_index=300),
        dict(brand='Alliant', name='Reloder 17', powder_type='EXTRUDED', burn_rate_index=195),
        dict(brand='Alliant', name='AR-Comp', powder_type='BALL', burn_rate_index=125),
        dict(brand='Alliant', name='Power Pistol', powder_type='FLAKE', burn_rate_index=75),
        dict(brand='Alliant', name='Unique', powder_type='FLAKE', burn_rate_index=55),
        dict(brand='Norma', name='MRP', powder_type='EXTRUDED', burn_rate_index=235),
        dict(brand='Norma', name='203-B', powder_type='EXTRUDED', burn_rate_index=175),
        dict(brand='Norma', name='R1', powder_type='BALL', burn_rate_index=190),
        dict(brand='Norma', name='URP', powder_type='EXTRUDED', burn_rate_index=195),
        dict(brand='Accurate', name='2230', powder_type='BALL', burn_rate_index=120),
        dict(brand='Accurate', name='2520', powder_type='BALL', burn_rate_index=148),
        dict(brand='Accurate', name='4350', powder_type='BALL', burn_rate_index=197),
        dict(brand='Accurate', name='LT-32', powder_type='BALL', burn_rate_index=135),
        dict(brand='Winchester', name='748', powder_type='BALL', burn_rate_index=143),
        dict(brand='Winchester', name='760', powder_type='BALL', burn_rate_index=186),
        dict(brand='Winchester', name='AutoComp', powder_type='BALL', burn_rate_index=55),
        dict(brand='Ramshot', name='Hunter', powder_type='BALL', burn_rate_index=212),
        dict(brand='Ramshot', name='Magnum', powder_type='BALL', burn_rate_index=265),
        dict(brand='Ramshot', name='TAC', powder_type='BALL', burn_rate_index=135),
    ]

    for data in powders:
        Powder.objects.get_or_create(brand=data['brand'], name=data['name'], defaults=data)


def populate_all(apps, schema_editor):
    populate_firearms(apps, schema_editor)
    populate_scopes(apps, schema_editor)
    populate_suppressors(apps, schema_editor)
    populate_bipods(apps, schema_editor)
    populate_magazines(apps, schema_editor)
    populate_ammo(apps, schema_editor)
    populate_reloading_components(apps, schema_editor)


def reverse_noop(apps, schema_editor):
    """Catalog data is safe to leave behind on reversal."""
    pass


class Migration(migrations.Migration):

    dependencies = [
        ('gears', '0003_ammo_brass_bullet_powder_primer_alter_bipod_options_and_more'),
    ]

    operations = [
        migrations.RunPython(populate_all, reverse_noop),
    ]
