Is it really the worst possible option? It’s often a pretty good guess, and accept-language is similarly unreliably set and can be fiddled with by intermediaries. Navigator.language doesn’t help you until you’ve already served and run JavaScript.
The right solution I think is to make a reasonable guess and then allow the user to control it. None of these guesses are going to work for everybody on their own.
I'm unaware of any intermediaries that fiddle with accept-language, so I can't really speak to how reliable it is. I can say that due to the ISP I use geolocation typically gets my location wrong by somewhere between 650 - 1600 km (400 and 1000 miles).
The right solution I think is to make a reasonable guess and then allow the user to control it. None of these guesses are going to work for everybody on their own.