This line should be in the fragment shader.
vec3 invertedNormals = a_normals + (u_normals.x < 0.0 ? calculateOffset(u_normals) * 2.0 - 1.0 : vec3(0.0));
Which requires some refactors to the vertex shader.
This will apply the normal texture on a per fragment basis versus a per vertex basis, which makes a lot more sense for textures.
TLDR: If you don't have enough vertices it looks like this:

When it should look like this:
