package health

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

	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// Handler provides HTTP endpoints for health checks
type Handler struct {
	checker *Checker
}

// NewHandler creates a new HTTP handler for health checks
func NewHandler(checker *Checker) *Handler {
	return &Handler{
		checker: checker,
	}
}

// RegisterRoutes registers health check routes on a mux
func (h *Handler) RegisterRoutes(mux *http.ServeMux) {
	mux.HandleFunc("/health", h.handleHealth)
	mux.HandleFunc("/health/live", h.handleLive)
	mux.HandleFunc("/health/ready", h.handleReady)
	// Prometheus metrics endpoint
	mux.Handle("/metrics", promhttp.Handler())
}

// handleHealth returns full health report
func (h *Handler) handleHealth(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	report := h.checker.Check(r.Context())
	w.Header().Set("Content-Type", "application/json")

	// Return 200 if healthy, 503 if unhealthy
	if report.Status != StatusHealthy {
		w.WriteHeader(http.StatusServiceUnavailable)
	}

	json.NewEncoder(w).Encode(report)
}

// handleLive is Kubernetes liveness probe endpoint
// Returns 200 if the service is running, 503 otherwise
func (h *Handler) handleLive(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	if h.checker.temporalClient == nil {
		w.WriteHeader(http.StatusServiceUnavailable)
		w.Write([]byte("service not initialized"))
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Write([]byte("alive"))
}

// handleReady is Kubernetes readiness probe endpoint
// Returns 200 if the service is ready to accept traffic, 503 otherwise
func (h *Handler) handleReady(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	report := h.checker.Check(r.Context())

	w.Header().Set("Content-Type", "application/json")

	// Service is ready only if healthy
	if report.Status != StatusHealthy {
		w.WriteHeader(http.StatusServiceUnavailable)
	}

	json.NewEncoder(w).Encode(map[string]interface{}{
		"ready":      report.Status == StatusHealthy,
		"components": report.Components,
	})
}
