package v1 import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/service" "github.com/gochat/gochat/pkg/response" ) // AgentBotInboxHandler handles bot-inbox binding endpoints. // Reference: Chatwoot app/controllers/api/v1/accounts/agent_bot_inboxes_controller.rb type AgentBotInboxHandler struct { svc *service.AgentBotInboxService } // NewAgentBotInboxHandler creates a new AgentBotInbox handler with service injection. func NewAgentBotInboxHandler(svc *service.AgentBotInboxService) *AgentBotInboxHandler { return &AgentBotInboxHandler{svc: svc} } // Bind creates a new bot-inbox binding (status=active). // POST /api/v1/accounts/:account_id/agent_bot_inboxes func (h *AgentBotInboxHandler) Bind(c *gin.Context) { accountID, err := parseUintParam(c, "account_id") if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid account_id") return } var req service.BindBotToInboxRequest if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error()) return } binding, svcErr := h.svc.Bind(c.Request.Context(), accountID, req) if svcErr != nil { handleServiceError(c, svcErr) return } response.Created(c, binding) } // Unbind removes a bot-inbox binding by ID. // DELETE /api/v1/accounts/:account_id/agent_bot_inboxes/:id func (h *AgentBotInboxHandler) Unbind(c *gin.Context) { id, err := parseUintParam(c, "id") if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid binding ID") return } if svcErr := h.svc.Unbind(c.Request.Context(), id); svcErr != nil { handleServiceError(c, svcErr) return } response.NoContent(c) } // UpdateStatus toggles a binding's active/inactive status. // PATCH /api/v1/accounts/:account_id/agent_bot_inboxes/:id/status func (h *AgentBotInboxHandler) UpdateStatus(c *gin.Context) { id, err := parseUintParam(c, "id") if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid binding ID") return } var req service.UpdateBindingStatusRequest if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrValidation, err.Error()) return } if _, svcErr := h.svc.UpdateStatus(c.Request.Context(), id, req); svcErr != nil { handleServiceError(c, svcErr) return } response.OK(c, gin.H{ "id": id, "status": req.Status, }) } // ListByInbox retrieves all bot-inbox bindings for a given inbox. // GET /api/v1/accounts/:account_id/agent_bot_inboxes?inbox_id=X func (h *AgentBotInboxHandler) ListByInbox(c *gin.Context) { inboxIDStr := c.Query("inbox_id") if inboxIDStr == "" { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "inbox_id query parameter required") return } inboxID, err := parseUintQuery(inboxIDStr) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid inbox_id") return } bindings, svcErr := h.svc.ListByInbox(c.Request.Context(), inboxID) if svcErr != nil { handleServiceError(c, svcErr) return } response.OK(c, bindings) } // ListByBot retrieves all bot-inbox bindings for a given agent bot. // GET /api/v1/accounts/:account_id/agent_bot_inboxes?agent_bot_id=X func (h *AgentBotInboxHandler) ListByBot(c *gin.Context) { botIDStr := c.Query("agent_bot_id") if botIDStr == "" { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "agent_bot_id query parameter required") return } botID, err := parseUintQuery(botIDStr) if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "invalid agent_bot_id") return } bindings, svcErr := h.svc.ListByBot(c.Request.Context(), botID) if svcErr != nil { handleServiceError(c, svcErr) return } response.OK(c, bindings) } // parseUintQuery parses a uint from a query string value. func parseUintQuery(s string) (uint, error) { n, err := strconv.ParseUint(s, 10, 32) if err != nil { return 0, err } return uint(n), nil }