This is a pretty complex subject, and there's a lot of advice that could be given. Being a software engineer by trade, I can give a few tips. Abstraction is your friend, as is the separation of logical systems. Smart use of things like families and generalized functions aid the former, while the use of separate event sheets/groups are good for the latter. The key is to not let a single system get too complicated. If a system -- such as an inventory, for example -- begins to get too complicated, you should step back and see if it can be broken up into multiple connected systems instead of one monolithic one.
Remember: complex is better than complicated.