In this work, I often see interfaces that matches the whole classes public interface (in the way we end up with a class X implementing an interface IX, which contains every single public method of X).
This is because such a class usually exists specifically to provide a concrete implementation of said interface, and tends not to have any unrelated implementations as they wouldn't be accessible if not part of the interface.
It's also not quite correct that such a class has no additional features. One major part is that the selection of which dependencies need to be injected are solely decided by the concrete class, not the interface.
Sufficiently complex operations will also likely lead to several private submethods in that class; when relevant.
When I asked the devs about why they did that that way -- as to me it seems to only increase complexity of the code by adding seemingly unnecessary lines of code
There is a very important to make here. I'm bolding it because it is an essential guideline to remember across your entire career as a software developer.
Complexity is not measured in lines of code.
A properly abstracted codebase will contain significantly more lines of code than a monolithic god class, but it will be easier to read and maintain, because it has been broken down into separate small bite-sized and easily digestible chunks of logic. This makes it much easier to look up a specific behavior or change a specific thing without affecting other things in your codebase.
When you build a codebase from scratch, there is a bit of effort that goes into how you structure and relate all these individual components. It's easy (and understandable) to find this needlessly complicated when you're not familiar with this approach.
However, that structure is generally a build-once effort. When your application is past the architectural setup stage, and you're in the latter stages of development or code maintenance, your focus will shift from how these components relate to one another to what is in each specific component (i.e. the actual implementation of the business requirements).
The initial cost of properly separating your problem domain into neat compartmentalized components will pay significant dividends in the long run, in terms of readability and maintanability of the code, (unit) testability of the behavior, and subsequently the ability to protect against the introduction of bugs and mistakes in your codebase. The larger a codebase gets, the easier it is to cause an unintended effect in another part of your codebase whenever you make a change. The cleaner your approach, the lower this chance is.
If you'll allow an analogy, your point of view is not unlike a medieval builder wondering why modern day builders spend so much time digging a hole instead of just starting to build the house that they're supposed to build. This is because medieval builders are not familiar with foundations (nor concrete), and they don't quite understand why you'd go to all this effort, because they don't see the benefits.
However, as you keep building a bigger and bigger house, the medieval builder's house would start to become unmanageable because its earthen foundation cannot reasonably support the kinds of skyscrapers that modern day builders build.
The problem is that to avoid this problem, you need to have laid a concrete foundation before you get to the stage where the problem of having a too large building becomes apparent. You cannot just slap a house together and fix the foundation only when the house becomes too big.
Right now, you're not seeing into the future far enough to see the problems that this interface segregation will prevent (or significantly suppress). You really should trust more senior developers on this. When you complete this project, you will see how the interfaces helped you along the way, and when you start the next project, you'll understand why you're implementing all these additional steps that today look unneccessary to you.