;; Events container-nav fragment handler
;; returns: sx
;;
;; Renders calendar entry nav items + calendar link nav items
;; for the scrollable navigation panel on blog post pages.
;;
;; Params (from request.args):
;;   container_type  — "page" (default)
;;   container_id    — int
;;   post_slug       — string
;;   paginate_url    — base URL for infinite scroll
;;   page            — current page (default 1)
;;   exclude         — comma-separated exclusion prefixes
;;   current_calendar — currently selected calendar slug

(defhandler container-nav
  (&key container_type container_id post_slug paginate_url page exclude current_calendar)

  (let ((ct          (or container_type "page"))
        (cid         (parse-int (or container_id "0")))
        (slug        (or post_slug ""))
        (purl        (or paginate_url ""))
        (pg          (parse-int (or page "1")))
        (excl-raw    (or exclude ""))
        (cur-cal     (or current_calendar ""))
        (excludes    (filter (fn (e) (not (empty? e)))
                       (map trim (split excl-raw ","))))
        (has-cal-excl (not (empty? (filter (fn (e) (starts-with? e "calendar"))
                                     excludes))))
        (styles      (or (jinja-global "styles") (dict)))
        (nav-class   (or (get styles "nav_button") ""))
        (sel-colours (or (jinja-global "select_colours") "")))

    ;; Only render if no calendar-* exclusion
    (when (not has-cal-excl)
      (let ((result   (service "calendar" "associated-entries"
                        :content-type ct :content-id cid :page pg))
            (entries  (first result))
            (has-more (nth result 1))
            (calendars (service "calendar" "calendars-for-container"
                         :container-type ct :container-id cid)))

        (<>
          ;; Calendar entry nav items
          (map (fn (entry)
            (let ((entry-path (str "/" slug "/"
                                   (get entry "calendar_slug") "/"
                                   (get entry "start_at_year") "/"
                                   (get entry "start_at_month") "/"
                                   (get entry "start_at_day")
                                   "/entries/" (get entry "id") "/"))
                  (date-str (str (format-date (get entry "start_at") "%b %d, %Y at %H:%M")
                                 (if (get entry "end_at")
                                   (str " – " (format-date (get entry "end_at") "%H:%M"))
                                   ""))))
              (~calendar-entry-nav
                :href (app-url "events" entry-path)
                :name (get entry "name")
                :date-str date-str
                :nav-class nav-class))) entries)

          ;; Infinite scroll sentinel
          (when (and has-more (not (empty? purl)))
            (~htmx-sentinel
              :id (str "entries-load-sentinel-" pg)
              :hx-get (str purl "?page=" (+ pg 1))
              :hx-trigger "intersect once"
              :hx-swap "beforebegin"
              :class "flex-shrink-0 w-1"))

          ;; Calendar link nav items
          (map (fn (cal)
            (let ((href (app-url "events" (str "/" slug "/" (get cal "slug") "/")))
                  (is-selected (if (not (empty? cur-cal))
                                 (= (get cal "slug") cur-cal)
                                 false)))
              (~calendar-link-nav
                :href href
                :name (get cal "name")
                :nav-class nav-class
                :is-selected is-selected
                :select-colours sel-colours))) calendars))))))
