// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/observability/metrics.go
package observability

import (
	"fmt"
	"net/http"
	"runtime"
	"time"

	"go.uber.org/zap"
)

// MetricsServer provides basic metrics endpoint
type MetricsServer struct {
	logger    *zap.Logger
	startTime time.Time
}

// NewMetricsServer creates a new metrics server
func NewMetricsServer(logger *zap.Logger) *MetricsServer {
	return &MetricsServer{
		logger:    logger,
		startTime: time.Now(),
	}
}

// Handler returns an HTTP handler that serves basic metrics
func (ms *MetricsServer) Handler() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodGet {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		metrics := ms.collectMetrics()

		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		w.WriteHeader(http.StatusOK)

		for _, metric := range metrics {
			fmt.Fprintf(w, "%s\n", metric)
		}
	}
}

// collectMetrics collects basic application metrics
func (ms *MetricsServer) collectMetrics() []string {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)

	uptime := time.Since(ms.startTime).Seconds()

	metrics := []string{
		fmt.Sprintf("# HELP mapleopentech_uptime_seconds Total uptime of the service in seconds"),
		fmt.Sprintf("# TYPE mapleopentech_uptime_seconds counter"),
		fmt.Sprintf("mapleopentech_uptime_seconds %.2f", uptime),

		fmt.Sprintf("# HELP mapleopentech_memory_alloc_bytes Currently allocated memory in bytes"),
		fmt.Sprintf("# TYPE mapleopentech_memory_alloc_bytes gauge"),
		fmt.Sprintf("mapleopentech_memory_alloc_bytes %d", m.Alloc),

		fmt.Sprintf("# HELP mapleopentech_memory_total_alloc_bytes Total allocated memory in bytes"),
		fmt.Sprintf("# TYPE mapleopentech_memory_total_alloc_bytes counter"),
		fmt.Sprintf("mapleopentech_memory_total_alloc_bytes %d", m.TotalAlloc),

		fmt.Sprintf("# HELP mapleopentech_memory_sys_bytes Memory obtained from system in bytes"),
		fmt.Sprintf("# TYPE mapleopentech_memory_sys_bytes gauge"),
		fmt.Sprintf("mapleopentech_memory_sys_bytes %d", m.Sys),

		fmt.Sprintf("# HELP mapleopentech_gc_runs_total Total number of GC runs"),
		fmt.Sprintf("# TYPE mapleopentech_gc_runs_total counter"),
		fmt.Sprintf("mapleopentech_gc_runs_total %d", m.NumGC),

		fmt.Sprintf("# HELP mapleopentech_goroutines Current number of goroutines"),
		fmt.Sprintf("# TYPE mapleopentech_goroutines gauge"),
		fmt.Sprintf("mapleopentech_goroutines %d", runtime.NumGoroutine()),
	}

	return metrics
}

// RecordMetric records a custom metric (placeholder for future implementation)
func (ms *MetricsServer) RecordMetric(name string, value float64, labels map[string]string) {
	ms.logger.Debug("Recording metric",
		zap.String("name", name),
		zap.Float64("value", value),
		zap.Any("labels", labels),
	)
}
