When you say "add complexity", I think you mean "add difficulty". Because for example, a language that has
only one-argument functions, and builds multi-arg functions on top is a simpler one than one that has multi-arg functions built-in.
Simplicity is hard -- and pure functional programming is a lot about simplicity, which does make it hard -- hard to learn, and hard to figure out how to tackle various problems.
But the simplicity has many rewards. Mathematical simplicity makes a lot of mathematical deductions tractable -- this is what is typically referred to as "ease of reasoning" about code.
Referential transparency adds a whole lot of ease to the reasoning process.
The pure functional approach also means that type safety goes much further. If you forget to hook up your functions together properly (forget an input, ignore an output) you're likely to get warnings/errors. In the imperative approach, if you forget a side-effecting statement that adds another input to some code, the compiler cannot help you.
Imagine testing -- imperative code requires tests to build up a mock world as input for the code, and then inspect the mock world that results as an output from the code.
Testing a referentially transparent function requires just calling it with differing inputs. It makes property-testing possible, too!
Imagine composition -- pure function composition of two functions composes the meanings of those functions. If those two functions work, so will the composed one.
Try to combine two pieces of imperative code -- that's not necessarily true at all, one might mutate data that's in use by the other. Aliasing issues may arise, etc.
So functional code is easier to reason about, more composable, easier to test, and gets more safety from type checking. It is harder to learn to use, and harder to figure out how to use it to solve certain problems. With time, however, more and more problems yield to the pure functional programming approaches.