package api

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

// ConfigHandler handles GET/PUT for server configuration settings
type ConfigHandler struct {
	config ConfigProvider
}

// ConfigProvider is an interface for the server config so we don't import main package
type ConfigProvider interface {
	GetConfigJSON() json.RawMessage
	UpdateConfigFromJSON(data json.RawMessage) error
}

func NewConfigHandler(cp ConfigProvider) *ConfigHandler {
	return &ConfigHandler{config: cp}
}

func (h *ConfigHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodGet:
		h.getConfig(w, r)
	case http.MethodPut:
		h.updateConfig(w, r)
	default:
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
	}
}

func writeConfigJSONError(w http.ResponseWriter, status int, msg string) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	_ = json.NewEncoder(w).Encode(map[string]string{"error": msg})
}

// GET /api/v1/config
func (h *ConfigHandler) getConfig(w http.ResponseWriter, r *http.Request) {
	configJSON := h.config.GetConfigJSON()
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	_, _ = w.Write(configJSON)
}

// PUT /api/v1/config
func (h *ConfigHandler) updateConfig(w http.ResponseWriter, r *http.Request) {
	var body json.RawMessage
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		writeConfigJSONError(w, http.StatusBadRequest, "Invalid JSON")
		return
	}

	if err := h.config.UpdateConfigFromJSON(body); err != nil {
		status := http.StatusInternalServerError
		if strings.HasPrefix(err.Error(), "invalid config:") {
			status = http.StatusBadRequest
		}
		writeConfigJSONError(w, status, err.Error())
		return
	}

	// Return updated config
	h.getConfig(w, r)
}
