package web

import (
	"context"
	"encoding/json"
	"net/http"
	"time"

	"backend/templates"
)

// HealthzHandler returns a pure liveness probe handler (D-12). It responds
// immediately with 200 + `{"status":"ok"}` and never contacts the database.
// Use /readyz for a DB-aware readiness probe.
func HealthzHandler() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		_ = json.NewEncoder(w).Encode(map[string]string{
			"status": "ok",
		})
	}
}

// ReadyzHandler returns an HTTP handler that probes the supplied Pinger with a
// 2-second timeout and responds per CONTEXT D-13: 200 + JSON
// `{"status":"ok","db":"ok"}` when reachable, 503 + JSON
// `{"status":"degraded","db":"down"}` otherwise.
func ReadyzHandler(pinger Pinger) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
		defer cancel()
		w.Header().Set("Content-Type", "application/json")
		if err := pinger.Ping(ctx); err != nil {
			w.WriteHeader(http.StatusServiceUnavailable)
			_ = json.NewEncoder(w).Encode(map[string]string{
				"status": "degraded",
				"db":     "down",
			})
			return
		}
		w.WriteHeader(http.StatusOK)
		_ = json.NewEncoder(w).Encode(map[string]string{
			"status": "ok",
			"db":     "ok",
		})
	}
}

// DemoTimeHandler renders the HTMX fragment for /demo/time. The `now` clock
// is injected so tests can substitute a deterministic time source; production
// passes time.Now.
func DemoTimeHandler(now func() time.Time) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		_ = templates.TimeFragment(now()).Render(r.Context(), w)
	}
}
