;; Extension — global find/replace across every text-bearing field.

(st-bootstrap-classes!)
(content/bootstrap!)
(content-bootstrap-section!)
(content-bootstrap-callout!)
(content-bootstrap-table!)

(define
  d
  (doc-append
    (doc-append
      (doc-append (doc-empty "d") (mk-heading "h" 1 "Foo title"))
      (mk-text "p" "the Foo is here"))
    (mk-section
      "s"
      (list (mk-text "n" "nested Foo") (mk-image "img" "/foo.png" "Foo alt")))))

(define r (content/find-replace d "Foo" "Bar"))

;; ── replaces in heading + text ──
(content-test
  "replace heading"
  (str (blk-send (doc-deep-find r "h") "text"))
  "Bar title")
(content-test
  "replace text"
  (str (blk-send (doc-deep-find r "p") "text"))
  "the Bar is here")
(content-test
  "replace nested text"
  (str (blk-send (doc-deep-find r "n") "text"))
  "nested Bar")

;; ── image alt IS a text field (asText ^ alt), so it is rewritten ──
(content-test
  "image alt replaced"
  (str (blk-send (doc-deep-find r "img") "alt"))
  "Bar alt")
;; ── but src is a URL, not prose, so it stays put ──
(content-test
  "image src untouched"
  (str (blk-send (doc-deep-find r "img") "src"))
  "/foo.png")

;; ── immutable ──
(content-test
  "original unchanged"
  (str (blk-send (doc-deep-find d "p") "text"))
  "the Foo is here")

;; ── multiple occurrences in one block ──
(content-test
  "all occurrences"
  (str
    (blk-send
      (doc-find
        (content/find-replace
          (doc-append (doc-empty "d") (mk-text "p" "a a a"))
          "a"
          "b")
        "p")
      "text"))
  "b b b")

;; ── code + quote text replaced ──
(define
  d2
  (doc-append
    (doc-append (doc-empty "d") (mk-code "c" "sx" "(old)"))
    (mk-quote "q" "src" "old saying")))
(define r2 (content/find-replace d2 "old" "new"))
(content-test
  "replace code"
  (str (blk-send (doc-find r2 "c") "text"))
  "(new)")
(content-test
  "replace quote"
  (str (blk-send (doc-find r2 "q") "text"))
  "new saying")

;; ── callout text is covered (consistency with asText/stats/summary) ──
(content-test
  "replace callout text"
  (str
    (blk-send
      (doc-find
        (content/find-replace
          (doc-append (doc-empty "d") (mk-callout "co" "note" "Foo here"))
          "Foo"
          "Bar")
        "co")
      "text"))
  "Bar here")
(content-test
  "callout kind untouched by text replace"
  (str
    (blk-send
      (doc-find
        (content/find-replace
          (doc-append (doc-empty "d") (mk-callout "co" "note" "x"))
          "note"
          "X")
        "co")
      "kind"))
  "note")

;; ── list items are rewritten (asText folds items) ──
(define
  rl
  (content/find-replace
    (doc-append
      (doc-empty "d")
      (mk-list "l" false (list "Foo one" "two Foo")))
    "Foo"
    "Bar"))
(content-test
  "replace first list item"
  (str (first (blk-send (doc-find rl "l") "items")))
  "Bar one")
(content-test
  "replace second list item"
  (str (first (rest (blk-send (doc-find rl "l") "items"))))
  "two Bar")

;; ── table headers + cells are rewritten (asText folds rows) ──
(define
  rt
  (content/find-replace
    (doc-append
      (doc-empty "d")
      (mk-table "t" (list "Foo head") (list (list "a Foo" "b"))))
    "Foo"
    "Bar"))
(content-test
  "replace table header"
  (str (first (table-headers (doc-find rt "t"))))
  "Bar head")
(content-test
  "replace table cell"
  (str (first (first (table-rows (doc-find rt "t")))))
  "a Bar")

;; ── no match → unchanged render ──
(content-test
  "no match"
  (asHTML (content/find-replace d "zzz" "qqq"))
  (asHTML d))
