;; Social navigation, header, post cards, timeline, compose

;; --- Navigation ---

(defcomp ~federation-nav-choose-username (&key url)
  (nav :class "flex gap-3 text-sm items-center"
    (a :href url :class "px-2 py-1 rounded hover:bg-stone-200 font-bold" "Choose username")))

(defcomp ~federation-nav-notification-link (&key href cls count-url)
  (a :href href :class cls "Notifications"
    (span :sx-get count-url :sx-trigger "load, every 30s" :sx-swap "innerHTML"
      :class "absolute -top-2 -right-3 text-xs bg-red-500 text-white rounded-full px-1 empty:hidden")))

(defcomp ~federation-nav-bar (&key items)
  (nav :class "flex gap-3 text-sm items-center flex-wrap" items))

(defcomp ~federation-social-header (&key nav)
  (div :id "social-row" :class "flex flex-col items-center md:flex-row justify-center md:justify-between w-full p-1 bg-sky-400"
    (div :class "w-full flex flex-row items-center gap-2 flex-wrap" nav)))

;; --- Post card ---

(defcomp ~federation-boost-label (&key name)
  (div :class "text-sm text-stone-500 mb-2" "Boosted by " name))

;; Aliases — delegate to shared ~avatar
(defcomp ~federation-avatar-img (&key src cls)
  (~avatar :src src :cls cls))

(defcomp ~federation-avatar-placeholder (&key cls initial)
  (~avatar :cls cls :initial initial))

(defcomp ~federation-content (&key content summary)
  (if summary
    (details :class "mt-2"
      (summary :class "text-stone-500 cursor-pointer" "CW: " (~rich-text :html summary))
      (div :class "mt-2 prose prose-sm prose-stone max-w-none" (~rich-text :html content)))
    (div :class "mt-2 prose prose-sm prose-stone max-w-none" (~rich-text :html content))))

(defcomp ~federation-original-link (&key url)
  (a :href url :target "_blank" :rel "noopener"
    :class "text-sm text-stone-400 hover:underline mt-1 inline-block" "original"))

(defcomp ~federation-post-card (&key boost avatar actor-name actor-username domain time content original interactions)
  (article :class "bg-white rounded-lg shadow-sm border border-stone-200 p-4 mb-4"
    boost
    (div :class "flex items-start gap-3"
      avatar
      (div :class "flex-1 min-w-0"
        (div :class "flex items-baseline gap-2"
          (span :class "font-semibold text-stone-900" actor-name)
          (span :class "text-sm text-stone-500" "@" actor-username domain)
          (span :class "text-sm text-stone-400 ml-auto" time))
        content original interactions))))

;; --- Interaction buttons ---

(defcomp ~federation-reply-link (&key url)
  (a :href url :class "hover:text-stone-700" "Reply"))

(defcomp ~federation-like-form (&key action target oid ainbox csrf cls icon count)
  (form :sx-post action :sx-target target :sx-swap "innerHTML"
    (input :type "hidden" :name "object_id" :value oid)
    (input :type "hidden" :name "author_inbox" :value ainbox)
    (input :type "hidden" :name "csrf_token" :value csrf)
    (button :type "submit" :class cls (span icon) " " count)))

(defcomp ~federation-boost-form (&key action target oid ainbox csrf cls count)
  (form :sx-post action :sx-target target :sx-swap "innerHTML"
    (input :type "hidden" :name "object_id" :value oid)
    (input :type "hidden" :name "author_inbox" :value ainbox)
    (input :type "hidden" :name "csrf_token" :value csrf)
    (button :type "submit" :class cls (span "\u21bb") " " count)))

(defcomp ~federation-interaction-buttons (&key like boost reply)
  (div :class "flex items-center gap-4 mt-3 text-sm text-stone-500"
    like boost reply))

;; --- Timeline ---

(defcomp ~federation-scroll-sentinel (&key url)
  (div :sx-get url :sx-trigger "revealed" :sx-swap "outerHTML"))

(defcomp ~federation-compose-button (&key url)
  (a :href url :class "bg-stone-800 text-white px-4 py-2 rounded hover:bg-stone-700" "Compose"))

(defcomp ~federation-timeline-page (&key label compose timeline)
  (div :class "flex items-center justify-between mb-6"
    (h1 :class "text-2xl font-bold" label " Timeline")
    compose)
  (div :id "timeline" timeline))

;; --- Data-driven post card (replaces Python _post_card_sx loop) ---

(defcomp ~federation-post-card-from-data (&key d has-actor csrf
                                               like-url unlike-url
                                               boost-url unboost-url)
  (let* ((boosted-by (get d "boosted_by"))
         (actor-icon (get d "actor_icon"))
         (actor-name (get d "actor_name"))
         (initial (or (get d "initial") "?"))
         (avatar (~avatar
           :src actor-icon
           :cls (if actor-icon "w-10 h-10 rounded-full"
                  "w-10 h-10 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-sm")
           :initial (when (not actor-icon) initial)))
         (boost (when boosted-by (~federation-boost-label :name boosted-by)))
         (content-sx (if (get d "summary")
           (~federation-content :content (get d "content") :summary (get d "summary"))
           (~federation-content :content (get d "content"))))
         (original (when (get d "original_url")
           (~federation-original-link :url (get d "original_url"))))
         (safe-id (get d "safe_id"))
         (interactions (when has-actor
           (let* ((oid (get d "object_id"))
                  (ainbox (get d "author_inbox"))
                  (target (str "#interactions-" safe-id))
                  (liked (get d "liked_by_me"))
                  (boosted-me (get d "boosted_by_me"))
                  (l-action (if liked unlike-url like-url))
                  (l-cls (str "flex items-center gap-1 " (if liked "text-red-500 hover:text-red-600" "hover:text-red-500")))
                  (l-icon (if liked "\u2665" "\u2661"))
                  (b-action (if boosted-me unboost-url boost-url))
                  (b-cls (str "flex items-center gap-1 " (if boosted-me "text-green-600 hover:text-green-700" "hover:text-green-600")))
                  (reply-url (get d "reply_url"))
                  (reply (when reply-url (~federation-reply-link :url reply-url)))
                  (like-form (~federation-like-form
                    :action l-action :target target :oid oid :ainbox ainbox
                    :csrf csrf :cls l-cls :icon l-icon :count (get d "like_count")))
                  (boost-form (~federation-boost-form
                    :action b-action :target target :oid oid :ainbox ainbox
                    :csrf csrf :cls b-cls :count (get d "boost_count"))))
             (div :id (str "interactions-" safe-id)
               (~federation-interaction-buttons :like like-form :boost boost-form :reply reply))))))
    (~federation-post-card
      :boost boost :avatar avatar
      :actor-name actor-name :actor-username (get d "actor_username")
      :domain (get d "domain") :time (get d "time")
      :content content-sx :original original
      :interactions interactions)))

;; Data-driven timeline items (replaces Python _timeline_items_sx loop)
(defcomp ~federation-timeline-items-from-data (&key items next-url has-actor csrf
                                                    like-url unlike-url boost-url unboost-url)
  (<>
    (map (lambda (d)
      (~federation-post-card-from-data :d d :has-actor has-actor :csrf csrf
        :like-url like-url :unlike-url unlike-url :boost-url boost-url :unboost-url unboost-url))
      (or items (list)))
    (when next-url (~federation-scroll-sentinel :url next-url))))

;; --- Compose ---

(defcomp ~federation-compose-reply (&key reply-to)
  (input :type "hidden" :name "in_reply_to" :value reply-to)
  (div :class "text-sm text-stone-500" "Replying to " (span :class "font-mono" reply-to)))

(defcomp ~federation-compose-form (&key action csrf reply)
  (h1 :class "text-2xl font-bold mb-6" "Compose")
  (form :method "post" :action action :class "space-y-4"
    (input :type "hidden" :name "csrf_token" :value csrf)
    reply
    (textarea :name "content" :rows "6" :maxlength "5000" :required true
      :class "w-full border border-stone-300 rounded-lg p-3 focus:outline-none focus:ring-2 focus:ring-stone-500"
      :placeholder "What's on your mind?")
    (div :class "flex items-center justify-between"
      (select :name "visibility" :class "border border-stone-300 rounded px-3 py-1.5 text-sm"
        (option :value "public" "Public")
        (option :value "unlisted" "Unlisted")
        (option :value "followers" "Followers only"))
      (button :type "submit" :class "bg-stone-800 text-white px-6 py-2 rounded hover:bg-stone-700" "Publish"))))
