package provider import ( "context" "github.com/gochat/gochat/internal/model/channel" ) // ChannelProvider defines the interface that every channel type must implement. // This mirrors Chatwoot's channel provider pattern where each channel (web_widget, // facebook, twitter, etc.) handles its own message processing, webhook handling, // and contact identification. type ChannelProvider interface { // Name returns the channel type identifier (e.g., "web_widget", "facebook"). Name() string // CreateChannel persists a new channel of this type with the given params. CreateChannel(ctx context.Context, accountID uint, params map[string]interface{}) (channel.Channelable, error) // UpdateChannel modifies an existing channel's configuration. UpdateChannel(ctx context.Context, channelID uint, params map[string]interface{}) (channel.Channelable, error) // DeleteChannel removes a channel. DeleteChannel(ctx context.Context, channelID uint) error // HandleWebhook processes incoming webhook events from the channel source. HandleWebhook(ctx context.Context, payload map[string]interface{}) error // ProcessIncomingMessage transforms a raw channel payload into a gochat Message. ProcessIncomingMessage(ctx context.Context, inboxID uint, contactID uint, payload map[string]interface{}) (*IncomingMessageResult, error) // ProcessOutgoingMessage sends a message back through the channel. ProcessOutgoingMessage(ctx context.Context, conversationID uint, messageID uint, content string) error // ValidateConfig checks that the channel-specific config params are valid. ValidateConfig(params map[string]interface{}) error } // IncomingMessageResult holds the processed result of an incoming channel message. type IncomingMessageResult struct { Content string `json:"content"` ContentType string `json:"content_type"` SourceID string `json:"source_id"` Extras map[string]interface{} `json:"extras,omitempty"` } // ChannelRegistry holds all registered channel providers. type ChannelRegistry struct { providers map[string]ChannelProvider } // NewChannelRegistry creates an empty registry. func NewChannelRegistry() *ChannelRegistry { return &ChannelRegistry{ providers: make(map[string]ChannelProvider), } } // Register adds a channel provider to the registry. func (r *ChannelRegistry) Register(provider ChannelProvider) { r.providers[provider.Name()] = provider } // Get returns a channel provider by name, or nil if not found. func (r *ChannelRegistry) Get(name string) ChannelProvider { return r.providers[name] } // List returns all registered provider names. func (r *ChannelRegistry) List() []string { names := make([]string, 0, len(r.providers)) for name := range r.providers { names = append(names, name) } return names }