;; lib/commerce/quote.sx — the final priced quote: price + promo + stacking.
;;
;; A quote is the deterministic composition of the pricing pipeline for a
;; (context, cart, ruleset, exclusions) tuple:
;;   {:subtotal S :discount D :tax T :total (S - D + T) :codes (...)}
;;
;; Tax policy (explicit, for the determinism contract): tax is computed on the
;; GROSS per-line amounts (pre-discount), via price.sx cart-tax. The best
;; promo stacking reduces the payable total but not the tax base. Same inputs
;; always yield the same quote — this is the value the order flow carries.

(define
  cart-quote
  (fn
    (ctx cart ruleset exclusions)
    (let
      ((cat (ctx-catalog ctx)))
      (let
        ((sub (cart-subtotal cat cart))
          (disc (best-promo-discount ctx cart ruleset exclusions))
          (tax (cart-tax ctx cart))
          (codes (best-promo-codes ctx cart ruleset exclusions)))
        {:codes codes :subtotal sub :discount disc :total (+ (- sub disc) tax) :tax tax}))))

(define quote-subtotal (fn (q) (get q :subtotal)))
(define quote-discount (fn (q) (get q :discount)))
(define quote-tax (fn (q) (get q :tax)))
(define quote-total (fn (q) (get q :total)))
(define quote-codes (fn (q) (get q :codes)))

;; Session-level convenience (a session is {:ctx :cart}).
(define
  session-quote
  (fn
    (sess ruleset exclusions)
    (cart-quote (get sess :ctx) (get sess :cart) ruleset exclusions)))
