Design and implement an in-memory banking payment component with the following APIs:
(
-
schedulePayment(payerId, payeeId, amount, executeAt) -> paymentId: create a pending outgoing payment scheduled for executeAt.
(
-
cancelPayment(paymentId) -> boolean: cancel only if still pending.
(
-
removePayment(paymentId) -> boolean: allow deletion only if the payment is CANCELED or FAILED; successful payments cannot be removed.
(
-
processDuePayments(now): execute all pending payments with executeAt <= now; mark each as SUCCESS if funds are sufficient, otherwise FAILED; only successful payments contribute to outgoing totals.
(
-
getTopKByOutgoingTotal(k) -> list
<accountId>
: return accountIds sorted by descending total outgoing amount from successful payments only; break ties by smaller accountId. Requirements: support only outgoing flow tracking (no incoming totals). Define the data structures to support efficient scheduling, cancellation, removal, and top-k queries; provide the time and space complexity of each API. Describe how you handle edge cases such as canceling an already executed payment, repeated cancellations, removing non-existent or ineligible payments, and ensuring that canceled payments are not executed.