;; Test dashboard components

(defcomp ~dashboard/test-status-badge (&key status)
  (span :class (str "inline-flex items-center rounded-full border px-3 py-1 text-sm font-medium "
                (if (= status "running") "border-amber-300 bg-amber-50 text-amber-700 animate-pulse"
                (if (= status "passed") "border-emerald-300 bg-emerald-50 text-emerald-700"
                (if (= status "failed") "border-rose-300 bg-rose-50 text-rose-700"
                "border-stone-300 bg-stone-50 text-stone-700"))))
    status))

(defcomp ~dashboard/test-run-button (&key running csrf)
  (form :method "POST" :action "/run" :class "inline"
    (input :type "hidden" :name "csrf_token" :value csrf)
    (button :type "submit"
      :class (str "rounded bg-stone-800 px-4 py-2 text-sm font-medium text-white hover:bg-stone-700 "
              "disabled:opacity-50 disabled:cursor-not-allowed transition-colors")
      :disabled (if running "true" nil)
      (if running "Running..." "Run Tests"))))

(defcomp ~dashboard/test-filter-card (&key href label count colour-border colour-bg colour-text active)
  (a :href href
     :sx-get href
     :sx-target "#main-panel"
     :sx-select "#main-panel"
     :sx-swap "outerHTML"
     :sx-push-url "true"
     :class (str "block rounded border p-3 text-center transition-colors no-underline hover:opacity-80 "
                 colour-border " " colour-bg " "
                 (if active "ring-2 ring-offset-1 ring-stone-500 " ""))
    (div :class (str "text-3xl font-bold " colour-text) count)
    (div :class (str "text-sm " colour-text) label)))

(defcomp ~dashboard/test-summary (&key status passed failed errors skipped total duration last-run running csrf active-filter)
  (div :class "space-y-4"
    (div :class "flex items-center justify-between flex-wrap gap-3"
      (div :class "flex items-center gap-3"
        (h2 :class "text-2xl font-semibold text-stone-800" "Test Results")
        (when status (~dashboard/test-status-badge :status status)))
      (~dashboard/test-run-button :running running :csrf csrf))
    (when status
      (div :class "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 gap-3"
        (~dashboard/test-filter-card :href "/" :label "Total" :count total
          :colour-border "border-stone-200" :colour-bg "bg-white"
          :colour-text "text-stone-800"
          :active (if (= active-filter nil) "true" nil))
        (~dashboard/test-filter-card :href "/?filter=passed" :label "Passed" :count passed
          :colour-border "border-emerald-200" :colour-bg "bg-emerald-50"
          :colour-text "text-emerald-700"
          :active (if (= active-filter "passed") "true" nil))
        (~dashboard/test-filter-card :href "/?filter=failed" :label "Failed" :count failed
          :colour-border "border-rose-200" :colour-bg "bg-rose-50"
          :colour-text "text-rose-700"
          :active (if (= active-filter "failed") "true" nil))
        (~dashboard/test-filter-card :href "/?filter=errors" :label "Errors" :count errors
          :colour-border "border-orange-200" :colour-bg "bg-orange-50"
          :colour-text "text-orange-700"
          :active (if (= active-filter "errors") "true" nil))
        (~dashboard/test-filter-card :href "/?filter=skipped" :label "Skipped" :count skipped
          :colour-border "border-sky-200" :colour-bg "bg-sky-50"
          :colour-text "text-sky-700"
          :active (if (= active-filter "skipped") "true" nil))
        (~dashboard/test-filter-card :href "/" :label "Duration" :count (str duration "s")
          :colour-border "border-stone-200" :colour-bg "bg-white"
          :colour-text "text-stone-800" :active nil))
      (div :class "text-sm text-stone-400" (str "Last run: " last-run)))))

(defcomp ~dashboard/test-service-header (&key service total passed failed)
  (tr :class "border-b-2 border-stone-300 bg-stone-100"
    (td :class "px-3 py-2 text-sm font-bold text-stone-700" :colspan "4"
      (span service)
      (span :class "ml-2 text-xs font-normal text-stone-500"
        (str total " tests, " passed " passed, " failed " failed")))))

(defcomp ~dashboard/test-row (&key nodeid outcome duration longrepr)
  (tr :class (str "border-b border-stone-100 "
              (if (= outcome "passed") "bg-white"
              (if (= outcome "failed") "bg-rose-50"
              (if (= outcome "skipped") "bg-sky-50"
              "bg-orange-50"))))
    (td :class "px-3 py-2 text-sm font-mono text-stone-700 max-w-0 truncate" :title nodeid
      (a :href (str "/test/" nodeid)
         :sx-get (str "/test/" nodeid)
         :sx-target "#main-panel"
         :sx-select "#main-panel"
         :sx-swap "outerHTML"
         :sx-push-url "true"
         :class "hover:underline hover:text-sky-600"
        nodeid))
    (td :class "px-3 py-2 text-center"
      (span :class (str "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium "
                    (if (= outcome "passed") "border-emerald-300 bg-emerald-50 text-emerald-700"
                    (if (= outcome "failed") "border-rose-300 bg-rose-50 text-rose-700"
                    (if (= outcome "skipped") "border-sky-300 bg-sky-50 text-sky-700"
                    "border-orange-300 bg-orange-50 text-orange-700"))))
        outcome))
    (td :class "px-3 py-2 text-right text-sm text-stone-500 tabular-nums" (str duration "s"))
    (td :class "px-3 py-2 text-sm text-rose-600 font-mono max-w-xs truncate" :title longrepr
      (when longrepr longrepr))))

(defcomp ~dashboard/test-results-table (&key rows has-failures)
  (div :class "overflow-x-auto rounded border border-stone-200 bg-white"
    (table :class "w-full text-left"
      (thead
        (tr :class "border-b border-stone-200 bg-stone-50"
          (th :class "px-3 py-2 text-sm font-medium text-stone-600" "Test")
          (th :class "px-3 py-2 text-xs font-medium text-stone-600 text-center w-24" "Status")
          (th :class "px-3 py-2 text-xs font-medium text-stone-600 text-right w-20" "Time")
          (th :class "px-3 py-2 text-xs font-medium text-stone-600 w-48" "Error")))
      (tbody (when rows rows)))))

(defcomp ~dashboard/test-running-indicator ()
  (div :class "flex items-center justify-center py-12 text-stone-500"
    (div :class "flex items-center gap-3"
      (div :class "animate-spin h-6 w-6 border-2 border-stone-300 border-t-stone-600 rounded-full")
      (span :class "text-sm" "Running tests..."))))

(defcomp ~dashboard/test-no-results ()
  (div :class "flex items-center justify-center py-12 text-stone-400"
    (div :class "text-center"
      (div :class "text-4xl mb-2" "?")
      (div :class "text-sm" "No test results yet. Click Run Tests to start."))))

(defcomp ~dashboard/test-detail (&key nodeid outcome duration longrepr)
  (div :class "space-y-6 p-4"
    (div :class "flex items-center gap-3"
      (a :href "/"
         :sx-get "/"
         :sx-target "#main-panel"
         :sx-select "#main-panel"
         :sx-swap "outerHTML"
         :sx-push-url "true"
         :class "text-sky-600 hover:text-sky-800 text-sm"
        "← Back to results")
      (span :class (str "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium "
                    (if (= outcome "passed") "border-emerald-300 bg-emerald-50 text-emerald-700"
                    (if (= outcome "failed") "border-rose-300 bg-rose-50 text-rose-700"
                    (if (= outcome "skipped") "border-sky-300 bg-sky-50 text-sky-700"
                    "border-orange-300 bg-orange-50 text-orange-700"))))
        outcome))
    (div :class "rounded border border-stone-200 bg-white p-4 space-y-3"
      (h2 :class "text-lg font-mono font-semibold text-stone-800 break-all" nodeid)
      (div :class "flex gap-4 text-sm text-stone-500"
        (span (str "Duration: " duration "s")))
      (when longrepr
        (div :class "mt-4"
          (h3 :class "text-sm font-semibold text-rose-700 mb-2" "Error Output")
          (pre :class "bg-stone-50 border border-stone-200 rounded p-3 text-xs text-stone-700 overflow-x-auto whitespace-pre-wrap"
            longrepr))))))
