package handlers

import (
	"errors"
	"net/http"
	"strconv"
	"strings"

	"github.com/acp/interceptor/internal/registry"
	"github.com/gin-gonic/gin"
)

// AgentHandler serves the lightweight agent registry API (#2).
type AgentHandler struct {
	store registry.Repository
}

// NewAgentHandler constructs an agent registry handler.
func NewAgentHandler(store registry.Repository) *AgentHandler {
	return &AgentHandler{store: store}
}

// ListAgents returns registered agents.
func (h *AgentHandler) ListAgents(c *gin.Context) {
	limit := 100
	if v := c.Query("limit"); v != "" {
		if n, err := strconv.Atoi(v); err == nil && n > 0 {
			limit = n
		}
	}
	agents, err := h.store.List(limit)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "list agents failed"})
		return
	}
	if agents == nil {
		agents = []registry.Agent{}
	}
	c.JSON(http.StatusOK, gin.H{"agents": agents})
}

// GetAgent returns one agent by id.
func (h *AgentHandler) GetAgent(c *gin.Context) {
	id := strings.TrimSpace(c.Param("agent_id"))
	a, err := h.store.Get(id)
	if err != nil {
		if errors.Is(err, registry.ErrNotFound) {
			c.JSON(http.StatusNotFound, gin.H{"error": "agent not found"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "get agent failed"})
		return
	}
	c.JSON(http.StatusOK, a)
}

// RegisterAgent creates or updates an agent (PUT semantics via POST).
func (h *AgentHandler) RegisterAgent(c *gin.Context) {
	var req registry.UpsertRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
		return
	}
	if strings.TrimSpace(req.AgentID) == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "agent_id required"})
		return
	}
	a, err := h.store.Upsert(req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "register agent failed"})
		return
	}
	c.JSON(http.StatusOK, a)
}

// PatchAgent updates selected fields.
func (h *AgentHandler) PatchAgent(c *gin.Context) {
	id := strings.TrimSpace(c.Param("agent_id"))
	var req registry.PatchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
		return
	}
	a, err := h.store.Patch(id, req)
	if err != nil {
		if errors.Is(err, registry.ErrNotFound) {
			c.JSON(http.StatusNotFound, gin.H{"error": "agent not found"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "patch agent failed"})
		return
	}
	c.JSON(http.StatusOK, a)
}
