Step 1: Build a proverbial "ball of mud", adding things left and right until all the shifting requirements are met.
Step 2: Write a minimal description of all the logic from scratch, by surveying the existing code, and then, essentially, write an interpreter for it.
If I got to step 2, and did a good job, future projects would become much easier.
if a
if b
...
else
...
end
else
case c
...
when y
...
when z
...
else
...
end
end
Rather than understand how everything works and literally 'factor' out a new aspect, any structure can, without understanding, be incrementally be amended by changing all the relevant leaves with additional, duplicated substructures. Of course it looks clear and obvious here, but usually the structure is distributed across many classes, methods, and strategy patterns, etc. The 'factoring' work that needs to be continually done is at a higher conceptual level rather than the mindless 'deduplicating' refactorings that tend to get done.