;; lib/commerce/tests/quote.sx — composed priced quote (price+promo+stacking).
;; Uses (commerce-test name got expected) provided by conformance.sh.

(define
  pcat
  (make-catalog
    (list
      (list "widget" 1000 :standard)
      (list "book" 800 :zero-rated)
      (list "tea" 1000 :reduced))
    (list)
    (list)))

(define
  tax-rules
  (list
    (list :uk :standard :guest 2000)
    (list :uk :reduced :guest 500)
    (list :uk :zero-rated :guest 0)
    (list :uk :standard :member 2000)
    (list :uk :reduced :member 500)
    (list :uk :zero-rated :member 0)))

(define gctx (make-pricing-context pcat tax-rules :uk :guest))
(define mctx (make-pricing-context pcat tax-rules :uk :member))

(define
  cart
  (list
    (list "widget" :none 3)
    (list "book" :none 1)
    (list "tea" :none 6)))

(define
  ruleset
  (list
    (list :percent "TEN" :standard 1000)
    (list :percent "TWENTY" :standard 2000)
    (list :fixed "FIVER" 5000 500)
    (list :bundle "B3T" "tea" 3)
    (list :member "MEM" :standard 2500)))

(define
  exclusions
  (list (list "TEN" "TWENTY") (list "TEN" "MEM") (list "TWENTY" "MEM")))

;; subtotal: 3000 + 800 + 6000 = 9800
;; tax (gross): widget 600 + tea 300 + book 0 = 900
;; guest discount: TWENTY 600 + FIVER 500 + B3T 2000 = 3100
;; guest total: 9800 - 3100 + 900 = 7600

(define gq (cart-quote gctx cart ruleset exclusions))

(commerce-test "quote-subtotal" (quote-subtotal gq) 9800)
(commerce-test "quote-tax" (quote-tax gq) 900)
(commerce-test "quote-discount-guest" (quote-discount gq) 3100)
(commerce-test "quote-total-guest" (quote-total gq) 7600)
(commerce-test
  "quote-codes-guest"
  (quote-codes gq)
  (list "TWENTY" "FIVER" "B3T"))

(commerce-test "quote-full-guest" gq {:codes (list "TWENTY" "FIVER" "B3T") :subtotal 9800 :discount 3100 :total 7600 :tax 900})

;; member discount: MEM 750 + FIVER 500 + B3T 2000 = 3250
;; member total: 9800 - 3250 + 900 = 7450
(define mq (cart-quote mctx cart ruleset exclusions))

(commerce-test "quote-discount-member" (quote-discount mq) 3250)
(commerce-test "quote-total-member" (quote-total mq) 7450)
(commerce-test
  "quote-codes-member"
  (quote-codes mq)
  (list "FIVER" "B3T" "MEM"))

;; --- determinism: same inputs, identical quote ---

(commerce-test
  "quote-deterministic"
  (=
    (cart-quote gctx cart ruleset exclusions)
    (cart-quote gctx cart ruleset exclusions))
  true)

;; --- no promos: discount 0, total = subtotal + tax ---

(commerce-test
  "quote-no-promos"
  (cart-quote gctx cart (list) (list))
  {:codes (list) :subtotal 9800 :discount 0 :total 10700 :tax 900})

;; --- empty cart ---

(commerce-test
  "quote-empty"
  (cart-quote gctx empty-cart ruleset exclusions)
  {:codes (list) :subtotal 0 :discount 0 :total 0 :tax 0})

;; --- session convenience ---

(define
  sess
  (commerce-add (commerce-session gctx) "widget" :none 3))

(commerce-test
  "session-quote"
  (quote-total (session-quote sess ruleset exclusions))
  3000)
