;; htmx demo API handlers — return HTML fragments for hx-* demos

;; Click to load
(defhandler
  ex-click
  :path "/sx/(applications.(htmx.(api.click)))"
  :method :get
  :returns "element"
  (&key)
  (div
    (~tw :tokens "space-y-2")
    (p (~tw :tokens "text-stone-800 font-medium") "Content loaded!")
    (p
      (~tw :tokens "text-stone-500 text-sm")
      "Fetched from the server via hx-get")))

;; Active search
(defhandler
  ex-search
  :path "/sx/(applications.(htmx.(api.search)))"
  :method :get
  :returns "element"
  (&key q)
  (let
    ((query (or q "")))
    (let
      ((items (list {:desc "GET request" :name "hx-get"} {:desc "POST request" :name "hx-post"} {:desc "Swap strategy" :name "hx-swap"} {:desc "Target element" :name "hx-target"} {:desc "Event trigger" :name "hx-trigger"} {:desc "Confirm dialog" :name "hx-confirm"} {:desc "Progressive enhancement" :name "hx-boost"} {:desc "CSS selector filter" :name "hx-select"})))
      (let
        ((filtered (if (= query "") (list) (filter (fn (item) (contains? (downcase (get item :name)) (downcase query))) items))))
        (if
          (empty? filtered)
          (p
            (~tw :tokens "text-gray-400 italic py-2")
            (str "No results for \"" query "\""))
          (ul
            (~tw :tokens "divide-y divide-gray-100")
            (map
              (fn
                (item)
                (li
                  (~tw :tokens "py-2 px-1")
                  (span
                    (~tw :tokens "font-medium text-gray-800")
                    (get item :name))
                  (span
                    (~tw :tokens "text-sm text-gray-500 ml-2")
                    (get item :desc))))
              filtered)))))))

;; Tabs
(defhandler
  ex-tab
  :path "/sx/(applications.(htmx.(api.tab)))"
  :method :get
  :returns "element"
  (&key tab)
  (let
    ((tab (or tab "overview")))
    (cond
      (= tab "overview")
      (div
        (~tw :tokens "p-4 space-y-2")
        (h3 (~tw :tokens "font-semibold text-stone-800") "Overview")
        (p
          (~tw :tokens "text-stone-600 text-sm")
          "htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes."))
      (= tab "features")
      (div
        (~tw :tokens "p-4 space-y-2")
        (h3 (~tw :tokens "font-semibold text-stone-800") "Features")
        (ul
          (~tw
            :tokens "list-disc list-inside text-sm text-stone-600 space-y-1")
          (li "Any element, any event")
          (li "Multiple swap strategies")
          (li "CSS transition support")
          (li "Out-of-band swaps")))
      (= tab "code")
      (div
        (~tw :tokens "p-4")
        (pre
          (~tw :tokens "text-sm bg-stone-100 rounded p-3")
          (code "(button :hx-get \"/api\" :hx-target \"#out\"\n  \"Load\")")))
      true
      (div (~tw :tokens "p-4 text-stone-400") "Unknown tab"))))

;; Delete item — returns empty fragment to remove the element
(defhandler
  ex-delete
  :path "/sx/(applications.(htmx.(api.delete)))"
  :method :delete
  :csrf false
  :returns "element"
  (&key)
  (<>))

;; Form submission
(defhandler
  ex-form
  :path "/sx/(applications.(htmx.(api.form)))"
  :method :post
  :csrf false
  :returns "element"
  (&key name email)
  (div
    (~tw :tokens "p-4 bg-green-50 border border-green-200 rounded-lg")
    (p
      (~tw :tokens "text-green-800 font-medium")
      (str "Hello, " (or name "stranger") "!"))
    (p
      (~tw :tokens "text-sm text-green-600 mt-1")
      (str "Email: " (or email "not provided")))))

;; Slow endpoint for indicator demo
(defhandler
  ex-slow
  :path "/sx/(applications.(htmx.(api.slow)))"
  :method :get
  :returns "element"
  (&key)
  (div
    (~tw :tokens "p-4 bg-amber-50 border border-amber-200 rounded-lg")
    (p (~tw :tokens "text-amber-800 font-medium") "Slow response received")
    (p
      (~tw :tokens "text-sm text-amber-600 mt-1")
      "This response was delayed")))

;; Append item (beforeend swap demo)
(defhandler
  ex-append
  :path "/sx/(applications.(htmx.(api.append)))"
  :method :post
  :csrf false
  :returns "element"
  (&key)
  (div
    (~tw :tokens "p-2 border-b border-gray-100 text-sm text-stone-700")
    "New item appended"))
