;; lib/commerce/tests/refund.sx — refund 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 (refund-make-env))
(define b (persist/mem-backend))
(define q1 {:codes (list) :subtotal 1000 :discount 0 :total 1200 :tax 200})

;; a paid, fulfilled order to refund (set up directly via the ledger)
(define _c (order-create b "O1" 1 q1))
(define _p (order-pay b "O1" "pay-1" 2 1200))
(commerce-test "setup-recon-ok" (order-recon b "O1") :ok)

;; --- happy path: request -> approve -> settle ---

(define rid (refund-begin! env b "O1" "rf-1" 10 500))

(commerce-test "begin-waiting-approve" (order-flow-waiting env rid) "approve")
(commerce-test
  "begin-not-yet-refunded"
  (order-refunded-amount-of (order-events b "O1"))
  0)
(commerce-test "begin-recon-unchanged" (order-recon b "O1") :ok)

(define a1 (refund-approve! env rid))
(commerce-test "approve-result" a1 :approved)
(commerce-test "approve-waiting-settle" (order-flow-waiting env rid) "settle")

(define s1 (refund-settle! env b rid "O1" "rf-1" 11 500))
(commerce-test "settle-result" s1 :settled)
(commerce-test "settle-flow-done" (order-flow-status env rid) "done")
(commerce-test
  "settle-refunded-amount"
  (order-refunded-amount-of (order-events b "O1"))
  500)
;; net 1200 - 500 = 700 < total 1200 -> underpaid (partial refund)
(commerce-test "settle-recon-underpaid" (order-recon b "O1") :underpaid)

;; --- idempotent settle: replayed provider callback is a no-op ---

(define s1b (refund-settle! env b rid "O1" "rf-1" 11 500))
(commerce-test "replay-already-settled" s1b :already-settled)
(commerce-test
  "replay-refunded-once"
  (order-refunded-amount-of (order-events b "O1"))
  500)

;; --- reject path: approval denied, books untouched ---

(define _c2 (order-create b "O2" 1 q1))
(define _p2 (order-pay b "O2" "pay-2" 2 1200))

(define rid2 (refund-begin! env b "O2" "rf-2" 20 1200))
(commerce-test
  "reject-waiting-approve"
  (order-flow-waiting env rid2)
  "approve")

(define j2 (refund-reject! env b "O2" rid2 21 "policy"))
(commerce-test "reject-result" j2 :rejected)
(commerce-test "reject-flow-not-waiting" (order-flow-waiting env rid2) nil)
(commerce-test
  "reject-no-refund"
  (order-refunded-amount-of (order-events b "O2"))
  0)
(commerce-test "reject-recon-ok" (order-recon b "O2") :ok)

;; settling a rejected/cancelled refund does nothing
(define s2 (refund-settle! env b rid2 "O2" "rf-2" 22 1200))
(commerce-test "reject-then-settle-noop" s2 :already-settled)
(commerce-test
  "reject-still-no-refund"
  (order-refunded-amount-of (order-events b "O2"))
  0)

;; --- distinct flow ids ---

(commerce-test "distinct-refund-ids" (not (= rid rid2)) true)
