def config_load(file):
    """
    Load wgctl.json and output KEY=value pairs for all config fields.
    Automatically handles nested sections — add fields to JSON, they appear here.
    """
    import os
    if not os.path.exists(file):
        return
    try:
        with open(file) as f:
            d = json.load(f)

        def emit(key, val):
            if val is not None and val != '':
                print(f"{key}={val}")

        wg  = d.get('wireguard', {})
        dns = d.get('dns', {})
        hs  = d.get('handshake', {})
        act = d.get('activity', {})
        dis = d.get('display', {})

        emit('WG_INTERFACE',              wg.get('interface'))
        emit('WG_ENDPOINT',               wg.get('endpoint'))
        emit('WG_PORT',                   wg.get('port'))
        emit('WG_SUBNET',                 wg.get('subnet'))
        emit('WG_LAN',                    wg.get('lan'))
        emit('WG_DNS',                    dns.get('primary'))
        # fallback: join array to comma-separated string
        fb = dns.get('fallback', [])
        if fb: emit('WG_DNS_FALLBACK', ', '.join(str(x) for x in fb))
        emit('WG_HANDSHAKE_CHECK_TIME_SEC', hs.get('check_interval_sec'))
        emit('DATE_FORMAT',               dis.get('date_format'))

        atot = act.get('total', {})
        acur = act.get('current', {})
        emit('ACTIVITY_TOTAL_LOW_BYTES',    atot.get('low'))
        emit('ACTIVITY_TOTAL_MED_BYTES',    atot.get('medium'))
        emit('ACTIVITY_TOTAL_HIGH_BYTES',   atot.get('high'))
        emit('ACTIVITY_CURRENT_LOW_BYTES',  acur.get('low'))
        emit('ACTIVITY_CURRENT_MED_BYTES',  acur.get('medium'))
        emit('ACTIVITY_CURRENT_HIGH_BYTES', acur.get('high'))
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)