The glib answer is that mutability is necessary, because software that doesn't change anything is kind of pointless. Ultimately, at least some of your data is going to be mutable - even if it is just the input and output of the process.
Really, though, you are asking why you would choose to use immutable rather than mutable data in various parts of your program, and the answer to that is complexity.
Complexity is the thing that makes software difficult. Mutable data is inherently complex, because it can change.
Complexity is what makes software difficult, because it makes doing anything with it hard. It could be the complexity of doing the right thing in the face of all your state, or the complexity of concurrency, or the complexity of changing code to meet new requirements.
Ultimately, though, the simpler software is the easier it is to keep working, and to improve, over time. There is a lot of education, experience, and related discussion that most of the cost of software is really keeping it working over the full life of the software.
The reason that mutable data makes software more complex is fairly simple, if you contrast the thinking you need to do about the data:
If the data is immutable you need to know what it means, where it was first assigned, and perhaps how it is used here.
If the data is mutable you need to know what it means, where it was first assigned, where it can be changed, when it can be changed, if those changes can happen concurrently and require locks, what sequence locks need to be acquired in, if changing the data needs coordination with others, and if it is actually changed here.
There are other advantages to immutable data, such as garbage collection efficiency, lock-free operation, efficient substructure sharing, and so forth, but they are technical choices - and while they are becoming more important as multi-core processing becomes more common, they are not the heart of the advantage.
Finally, to the implicit question of why you found it so challenging in your learning the language... Obviously, I can only speculate, but in my experience there are two causes for this in people learning programming, programming languages, and programming paradigms:
The first is that most teaching problems are great tools for learning, but have very little to do with the "real world" of software engineering. At the scale of a teaching problem you probably know the entire codebase, end to end, and it is small enough you can hold a picture in your head of how it all works.
When you are working with a team of five, or ten, or fifty, or five hundred people on a codebase with a half million lines of code, where you have never even seen most of the code around what you are working on - well, then you start to appreciate immutable data, because you need to know so much less.
The second is that your comment on "added lots of complexity" mirrors what a bunch of other people have said to me. Generally, they felt it added a lot of complexity because they just wanted to write code until something worked without spending a lot of time thinking about the bigger picture of the problem.
Now, I have no idea if this is true of you or not - I never met you - but maybe it is the same thing.
Mutable data is an easy solution to "I need X to change so that Y happens" when you are in a random part of the code and need to trigger some distant effect.
That adds complexity. Not local complexity, sure, because you can more easily change the value and all. Remote complexity. Invisible complexity.
It spreads out the details of where change happens, and of where the behaviour of the system is defined. As you go down this path, and grow the size of the system, you rediscover the problems that Object Oriented analysis and design came about to combat.
Again, I don't know you, and that may have nothing to do with why you found it "added complexity", but it is the most common pattern in my experience of folks saying the same thing.