(ns ajet.chat.api.handlers.health
  "Health check handler.

   Checks connectivity to DB, NATS, and MinIO. Returns 200 if all healthy,
   503 if any check fails (degraded mode)."
  (:require [clojure.tools.logging :as log]
            [ajet.chat.shared.db :as db]
            [ajet.chat.shared.eventbus :as eventbus]
            [ajet.chat.api.middleware :as mw])
  (:import [software.amazon.awssdk.services.s3 S3Client]
           [software.amazon.awssdk.services.s3.model HeadBucketRequest]))

;;; ---------------------------------------------------------------------------
;;; Health Checks
;;; ---------------------------------------------------------------------------

(defn- check-db
  "Test database connectivity with a simple query."
  [ds]
  (try
    (db/execute-sql! ds ["SELECT 1"])
    "ok"
    (catch Exception e
      (log/error e "DB health check failed")
      "error")))

(defn- check-nats
  "Test NATS connection status."
  [nats]
  (try
    (if (and nats (eventbus/connected? nats))
      "ok"
      "error")
    (catch Exception e
      (log/error e "NATS health check failed")
      "error")))

(defn- check-minio
  "Test MinIO/S3 connectivity by checking if the bucket exists."
  [^S3Client s3 bucket]
  (try
    (.headBucket s3 (-> (HeadBucketRequest/builder)
                        (.bucket bucket)
                        (.build)))
    "ok"
    (catch Exception e
      (log/error e "MinIO health check failed")
      "error")))

;;; ---------------------------------------------------------------------------
;;; Handler
;;; ---------------------------------------------------------------------------

(defn health-check
  "GET /api/health
   Returns health status for all dependencies.
   200 = all ok, 503 = at least one check failed."
  [request]
  (let [ds     (get-in request [:system :ds])
        nats   (get-in request [:system :nats])
        s3     (get-in request [:system :s3])
        bucket (get-in request [:system :bucket])

        db-status    (check-db ds)
        nats-status  (check-nats nats)
        minio-status (check-minio s3 bucket)

        checks  {:db db-status :nats nats-status :minio minio-status}
        all-ok  (every? #(= "ok" %) (vals checks))
        status  (if all-ok "ok" "degraded")
        code    (if all-ok 200 503)]

    (mw/json-response code {:status status :checks checks})))
