package serverless

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

	"github.com/DeBrosOfficial/network/pkg/serverless"
	"go.uber.org/zap"
)

// setSecretRequest is the request body for setting a secret.
type setSecretRequest struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

// HandleSetSecret handles PUT /v1/functions/secrets
// Stores an encrypted secret scoped to the caller's namespace.
func (h *ServerlessHandlers) HandleSetSecret(w http.ResponseWriter, r *http.Request) {
	if h.secretsManager == nil {
		writeError(w, http.StatusNotImplemented, "Secrets management not available")
		return
	}

	namespace := h.getNamespaceFromRequest(r)
	if namespace == "" {
		writeError(w, http.StatusBadRequest, "namespace required")
		return
	}

	var req setSecretRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		writeError(w, http.StatusBadRequest, "Invalid JSON: "+err.Error())
		return
	}

	if req.Name == "" {
		writeError(w, http.StatusBadRequest, "secret name required")
		return
	}
	if req.Value == "" {
		writeError(w, http.StatusBadRequest, "secret value required")
		return
	}

	ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
	defer cancel()

	if err := h.secretsManager.Set(ctx, namespace, req.Name, req.Value); err != nil {
		h.logger.Error("Failed to set secret",
			zap.String("namespace", namespace),
			zap.String("name", req.Name),
			zap.Error(err),
		)
		writeError(w, http.StatusInternalServerError, "Failed to set secret: "+err.Error())
		return
	}

	h.logger.Info("Secret set via API",
		zap.String("namespace", namespace),
		zap.String("name", req.Name),
	)

	writeJSON(w, http.StatusOK, map[string]any{
		"message":   "Secret set",
		"name":      req.Name,
		"namespace": namespace,
	})
}

// HandleListSecrets handles GET /v1/functions/secrets
// Lists all secret names in the caller's namespace (values are never returned).
func (h *ServerlessHandlers) HandleListSecrets(w http.ResponseWriter, r *http.Request) {
	if h.secretsManager == nil {
		writeError(w, http.StatusNotImplemented, "Secrets management not available")
		return
	}

	namespace := h.getNamespaceFromRequest(r)
	if namespace == "" {
		writeError(w, http.StatusBadRequest, "namespace required")
		return
	}

	ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
	defer cancel()

	names, err := h.secretsManager.List(ctx, namespace)
	if err != nil {
		h.logger.Error("Failed to list secrets",
			zap.String("namespace", namespace),
			zap.Error(err),
		)
		writeError(w, http.StatusInternalServerError, "Failed to list secrets")
		return
	}

	writeJSON(w, http.StatusOK, map[string]any{
		"secrets": names,
		"count":   len(names),
	})
}

// HandleDeleteSecret handles DELETE /v1/functions/secrets/{name}
// Deletes a secret from the caller's namespace.
func (h *ServerlessHandlers) HandleDeleteSecret(w http.ResponseWriter, r *http.Request, secretName string) {
	if h.secretsManager == nil {
		writeError(w, http.StatusNotImplemented, "Secrets management not available")
		return
	}

	namespace := h.getNamespaceFromRequest(r)
	if namespace == "" {
		writeError(w, http.StatusBadRequest, "namespace required")
		return
	}

	ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
	defer cancel()

	if err := h.secretsManager.Delete(ctx, namespace, secretName); err != nil {
		if errors.Is(err, serverless.ErrSecretNotFound) {
			writeError(w, http.StatusNotFound, "Secret not found")
			return
		}
		h.logger.Error("Failed to delete secret",
			zap.String("namespace", namespace),
			zap.String("name", secretName),
			zap.Error(err),
		)
		writeError(w, http.StatusInternalServerError, "Failed to delete secret: "+err.Error())
		return
	}

	h.logger.Info("Secret deleted via API",
		zap.String("namespace", namespace),
		zap.String("name", secretName),
	)

	writeJSON(w, http.StatusOK, map[string]any{
		"message": "Secret deleted",
	})
}
