;; Blog card components — pure data, no HTML injection

(defcomp ~blog-like-button (&key like-url hx-headers heart)
  (div :class "absolute top-20 right-2 z-10 text-6xl md:text-4xl"
    (button :sx-post like-url :sx-swap "outerHTML"
      :sx-headers hx-headers :class "cursor-pointer" heart)))

(defcomp ~blog-draft-status (&key publish-requested timestamp)
  (<> (div :class "flex justify-center gap-2 mt-1"
    (span :class "inline-block px-2 py-0.5 rounded-full text-xs font-semibold bg-amber-100 text-amber-800" "Draft")
    (when publish-requested (span :class "inline-block px-2 py-0.5 rounded-full text-xs font-semibold bg-blue-100 text-blue-800" "Publish requested")))
    (when timestamp (p :class "text-sm text-stone-500" (str "Updated: " timestamp)))))

(defcomp ~blog-published-status (&key timestamp)
  (p :class "text-sm text-stone-500" (str "Published: " timestamp)))

;; Tag components — accept data, not HTML
(defcomp ~blog-tag-icon (&key src name initial)
  (if src
    (img :src src :alt name :class "h-4 w-4 rounded-full object-cover border border-stone-300 flex-shrink-0")
    (div :class "h-4 w-4 rounded-full text-[8px] font-semibold flex items-center justify-center border border-stone-300 flex-shrink-0 bg-stone-200 text-stone-600" initial)))

(defcomp ~blog-tag-item (&key src name initial)
  (li (a :class "flex items-center gap-1"
    (~blog-tag-icon :src src :name name :initial initial)
    (span :class "inline-block rounded-full bg-stone-100 text-stone-600 px-2 py-1 text-sm font-medium border border-stone-200" name))))

;; At-bar — tags + authors row for detail pages
(defcomp ~blog-at-bar (&key tags authors)
  (when (or tags authors)
    (div :class "flex flex-row justify-center gap-3"
      (when tags
        (div :class "mt-4 flex items-center gap-2" (div "in")
          (ul :class "flex flex-wrap gap-2 text-sm"
            (map (lambda (t) (~blog-tag-item :src (get t "src") :name (get t "name") :initial (get t "initial"))) tags))))
      (div)
      (when authors
        (div :class "mt-4 flex items-center gap-2" (div "by")
          (ul :class "flex flex-wrap gap-2 text-sm"
            (map (lambda (a) (~blog-author-item :image (get a "image") :name (get a "name"))) authors)))))))

;; Author components
(defcomp ~blog-author-item (&key image name)
  (li :class "flex items-center gap-1"
    (when image (img :src image :alt name :class "h-5 w-5 rounded-full object-cover"))
    (span :class "text-stone-700" name)))

;; Card — accepts pure data
(defcomp ~blog-card (&key slug href hx-select title
                          feature-image excerpt
                          status is-draft publish-requested status-timestamp
                          liked like-url csrf-token
                          has-like
                          tags authors widget)
  (article :class "border-b pb-6 last:border-b-0 relative"
    (when has-like
      (~blog-like-button
        :like-url like-url
        :sx-headers (str "{\"X-CSRFToken\": \"" csrf-token "\"}")
        :heart (if liked "❤️" "🤍")))
    (a :href href :sx-get href :sx-target "#main-panel"
      :sx-select (or hx-select "#main-panel") :sx-swap "outerHTML" :sx-push-url "true"
      :class "block rounded-xl bg-white shadow hover:shadow-md transition overflow-hidden"
      (header :class "mb-2 text-center"
        (h2 :class "text-4xl font-bold text-stone-900" title)
        (if is-draft
          (~blog-draft-status :publish-requested publish-requested :timestamp status-timestamp)
          (when status-timestamp (~blog-published-status :timestamp status-timestamp))))
      (when feature-image (div :class "mb-4" (img :src feature-image :alt "" :class "rounded-lg w-full object-cover")))
      (when excerpt (p :class "text-stone-700 text-lg leading-relaxed text-center" excerpt)))
    widget
    (when (or tags authors)
      (div :class "flex flex-row justify-center gap-3"
        (when tags
          (div :class "mt-4 flex items-center gap-2" (div "in")
            (ul :class "flex flex-wrap gap-2 text-sm"
              (map (lambda (t) (~blog-tag-item :src (get t "src") :name (get t "name") :initial (get t "initial"))) tags))))
        (div)
        (when authors
          (div :class "mt-4 flex items-center gap-2" (div "by")
            (ul :class "flex flex-wrap gap-2 text-sm"
              (map (lambda (a) (~blog-author-item :image (get a "image") :name (get a "name"))) authors))))))))

(defcomp ~blog-card-tile (&key href hx-select feature-image title
                                is-draft publish-requested status-timestamp
                                excerpt tags authors)
  (article :class "relative"
    (a :href href :sx-get href :sx-target "#main-panel"
      :sx-select (or hx-select "#main-panel") :sx-swap "outerHTML" :sx-push-url "true"
      :class "block rounded-xl bg-white shadow hover:shadow-md transition overflow-hidden"
      (when feature-image (div (img :src feature-image :alt "" :class "w-full aspect-video object-cover")))
      (div :class "p-3 text-center"
        (h2 :class "text-lg font-bold text-stone-900" title)
        (if is-draft
          (~blog-draft-status :publish-requested publish-requested :timestamp status-timestamp)
          (when status-timestamp (~blog-published-status :timestamp status-timestamp)))
        (when excerpt (p :class "text-stone-700 text-sm leading-relaxed line-clamp-3 mt-1" excerpt))))
    (when (or tags authors)
      (div :class "flex flex-row justify-center gap-3"
        (when tags
          (div :class "mt-4 flex items-center gap-2" (div "in")
            (ul :class "flex flex-wrap gap-2 text-sm"
              (map (lambda (t) (~blog-tag-item :src (get t "src") :name (get t "name") :initial (get t "initial"))) tags))))
        (div)
        (when authors
          (div :class "mt-4 flex items-center gap-2" (div "by")
            (ul :class "flex flex-wrap gap-2 text-sm"
              (map (lambda (a) (~blog-author-item :image (get a "image") :name (get a "name"))) authors))))))))

;; Data-driven blog cards list (replaces Python _blog_cards_sx loop)
(defcomp ~blog-cards-from-data (&key posts view sentinel)
  (<>
    (map (lambda (p)
      (if (= view "tile")
        (~blog-card-tile
          :href (get p "href") :hx-select (get p "hx_select")
          :feature-image (get p "feature_image") :title (get p "title")
          :is-draft (get p "is_draft") :publish-requested (get p "publish_requested")
          :status-timestamp (get p "status_timestamp")
          :excerpt (get p "excerpt") :tags (get p "tags") :authors (get p "authors"))
        (~blog-card
          :slug (get p "slug") :href (get p "href") :hx-select (get p "hx_select")
          :title (get p "title") :feature-image (get p "feature_image")
          :excerpt (get p "excerpt") :is-draft (get p "is_draft")
          :publish-requested (get p "publish_requested")
          :status-timestamp (get p "status_timestamp")
          :has-like (get p "has_like") :liked (get p "liked")
          :like-url (get p "like_url") :csrf-token (get p "csrf_token")
          :tags (get p "tags") :authors (get p "authors")
          :widget (when (get p "widget") (~rich-text :html (get p "widget"))))))
      (or posts (list)))
    sentinel))

;; Data-driven page cards list (replaces Python _page_cards_sx loop)
(defcomp ~page-cards-from-data (&key pages sentinel)
  (<>
    (map (lambda (pg)
      (~blog-page-card
        :href (get pg "href") :hx-select (get pg "hx_select")
        :title (get pg "title")
        :has-calendar (get pg "has_calendar") :has-market (get pg "has_market")
        :pub-timestamp (get pg "pub_timestamp")
        :feature-image (get pg "feature_image") :excerpt (get pg "excerpt")))
      (or pages (list)))
    sentinel))

(defcomp ~blog-page-badges (&key has-calendar has-market)
  (div :class "flex justify-center gap-2 mt-2"
    (when has-calendar (span :class "inline-block px-2 py-0.5 rounded-full text-xs font-semibold bg-blue-100 text-blue-800"
      (i :class "fa fa-calendar mr-1") "Calendar"))
    (when has-market (span :class "inline-block px-2 py-0.5 rounded-full text-xs font-semibold bg-green-100 text-green-800"
      (i :class "fa fa-shopping-bag mr-1") "Market"))))

(defcomp ~blog-page-card (&key href hx-select title has-calendar has-market pub-timestamp feature-image excerpt)
  (article :class "border-b pb-6 last:border-b-0 relative"
    (a :href href :sx-get href :sx-target "#main-panel"
      :sx-select (or hx-select "#main-panel") :sx-swap "outerHTML" :sx-push-url "true"
      :class "block rounded-xl bg-white shadow hover:shadow-md transition overflow-hidden"
      (header :class "mb-2 text-center"
        (h2 :class "text-4xl font-bold text-stone-900" title)
        (~blog-page-badges :has-calendar has-calendar :has-market has-market)
        (when pub-timestamp (~blog-published-status :timestamp pub-timestamp)))
      (when feature-image (div :class "mb-4" (img :src feature-image :alt "" :class "rounded-lg w-full object-cover")))
      (when excerpt (p :class "text-stone-700 text-lg leading-relaxed text-center" excerpt)))))
