;; Test service composition defcomps — replaces Python string concatenation
;; in test/sxc/pages/__init__.py.

;; Service filter nav links
(defcomp ~components/test-service-nav (&key services active-service)
  (<>
    (~shared:layout/nav-link :href "/" :label "all"
      :is-selected (if (not active-service) "true" nil)
      :select-colours "aria-selected:bg-sky-200 aria-selected:text-sky-900")
    (map (lambda (svc)
      (~shared:layout/nav-link :href (str "/?service=" svc) :label svc
        :is-selected (if (= active-service svc) "true" nil)
        :select-colours "aria-selected:bg-sky-200 aria-selected:text-sky-900"))
      services)))

;; Test header menu row
(defcomp ~components/test-header-row (&key services active-service)
  (~shared:layout/menu-row-sx :id "test-row" :level 1 :colour "sky"
    :link-href "/" :link-label "Tests" :icon "fa fa-flask"
    :nav (~components/test-service-nav :services services :active-service active-service)
    :child-id "test-header-child"))

;; Layout: full page header stack (standalone — no root-header-auto)
(defcomp ~components/test-layout-full (&key services active-service)
  (~components/test-header-row :services services :active-service active-service))

;; Map test dicts to test-row components
(defcomp ~components/test-rows (&key tests)
  (<> (map (lambda (t)
    (~test-row
      :nodeid (get t "nodeid")
      :outcome (get t "outcome")
      :duration (str (get t "duration"))
      :longrepr (or (get t "longrepr") "")))
    tests)))

;; Grouped test rows with service headers
(defcomp ~components/test-grouped-rows (&key sections)
  (<> (map (lambda (sec)
    (<> (~test-service-header
          :service (get sec "service")
          :total (str (get sec "total"))
          :passed (str (get sec "passed"))
          :failed (str (get sec "failed")))
        (~components/test-rows :tests (get sec "tests"))))
    sections)))

;; Results partial: conditional rendering based on running/result state
(defcomp ~components/test-results-partial (&key status summary-data tests sections has-failures)
  (let* ((state (get summary-data "state")))
    (<>
      (~test-summary
        :status (get summary-data "status")
        :passed (get summary-data "passed")
        :failed (get summary-data "failed")
        :errors (get summary-data "errors")
        :skipped (get summary-data "skipped")
        :total (get summary-data "total")
        :duration (get summary-data "duration")
        :last-run (get summary-data "last_run")
        :running (get summary-data "running")
        :csrf (get summary-data "csrf")
        :active-filter (get summary-data "active_filter"))
      (cond
        ((= state "running") (~test-running-indicator))
        ((= state "no-results") (~test-no-results))
        ((= state "empty-filtered") (~test-no-results))
        (true (~test-results-table
                :rows (~components/test-grouped-rows :sections sections)
                :has-failures has-failures))))))

;; Wrap results in a div with optional HTMX polling
(defcomp ~components/test-results-wrap (&key running inner)
  (div :id "test-results" :class "space-y-6 p-4"
    :sx-get (when running "/results")
    :sx-trigger (when running "every 2s")
    :sx-swap (when running "outerHTML")
    inner))

;; Test detail section wrapper
(defcomp ~components/test-detail-section (&key test)
  (section :id "main-panel"
    :class "flex-1 md:h-full md:min-h-0 overflow-y-auto overscroll-contain js-grid-viewport"
    (~test-detail
      :nodeid (get test "nodeid")
      :outcome (get test "outcome")
      :duration (str (get test "duration"))
      :longrepr (or (get test "longrepr") ""))))

;; Detail page header stack (standalone — no root-header-auto)
(defcomp ~components/test-detail-layout-full (&key services test-nodeid test-label)
  (<> (~components/test-header-row :services services)
    (~shared:layout/menu-row-sx :id "test-detail-row" :level 2 :colour "sky"
      :link-href (str "/test/" test-nodeid)
      :link-label test-label)))
