;; lib/commerce/tests/order.sx — order lifecycle as a flow-on-sx flow.
;; Uses (commerce-test name got expected) provided by conformance.sh.
;; Builds the (expensive) flow env once; all assertions share it.

(define env (order-make-env))
(define b (persist/mem-backend))
(define q1 {:codes (list) :subtotal 1000 :discount 0 :total 1200 :tax 200})

;; --- happy path: begin suspends at payment ---

(define id1 (order-begin! env b "O1" 100 q1))

(commerce-test "begin-status-reserved" (order-status b "O1") :reserved)
(commerce-test "begin-waiting-payment" (order-flow-waiting env id1) "payment")
(commerce-test "begin-not-yet-paid" (order-paid b "O1") 0)

;; --- settle: payment webhook drives fulfilment ---

(define s1 (order-settle! env b id1 "O1" "ref-1" 102 1200))

(commerce-test "settle-result" s1 :settled)
(commerce-test "settle-status-fulfilled" (order-status b "O1") :fulfilled)
(commerce-test "settle-flow-done" (order-flow-status env id1) "done")
(commerce-test "settle-recon-ok" (order-recon b "O1") :ok)
(commerce-test "settle-event-count" (len (order-events b "O1")) 4)

;; --- webhook replay: a second settle is a no-op ---

(define s1b (order-settle! env b id1 "O1" "ref-1" 102 1200))

(commerce-test "replay-already-settled" s1b :already-settled)
(commerce-test
  "replay-no-extra-events"
  (len (order-events b "O1"))
  4)
(commerce-test "replay-recon-still-ok" (order-recon b "O1") :ok)

;; --- a second order gets its own flow id and suspends independently ---

(define id2 (order-begin! env b "O2" 200 q1))

(commerce-test "second-distinct-id" (not (= id1 id2)) true)
(commerce-test
  "second-waiting-payment"
  (order-flow-waiting env id2)
  "payment")
(commerce-test "first-unaffected" (order-status b "O1") :fulfilled)

;; --- durability: a suspended order survives a process restart ---

(define id3 (order-begin! env b "O3" 300 q1))
(commerce-test "pre-restart-waiting" (order-flow-waiting env id3) "payment")

(define _restart (order-flow-restart! env))

(commerce-test
  "post-restart-still-waiting"
  (order-flow-waiting env id3)
  "payment")
(commerce-test "post-restart-ledger-intact" (order-status b "O3") :reserved)

(define s3 (order-settle! env b id3 "O3" "ref-3" 302 1200))

(commerce-test "post-restart-settled" s3 :settled)
(commerce-test "post-restart-status" (order-status b "O3") :fulfilled)
(commerce-test "post-restart-recon-ok" (order-recon b "O3") :ok)
(commerce-test "post-restart-flow-done" (order-flow-status env id3) "done")

;; --- payment-request envelope (provider-neutral) for the still-suspended O2 ---

(commerce-test
  "pending-payments-lists-suspended"
  (pending-payments env b :GBP "https://shop/return")
  (list {:id id2 :request {:order "O2" :amount 1200 :return-url "https://shop/return" :currency :GBP}}))
