package service import ( "context" "errors" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" applogger "github.com/gochat/gochat/pkg/logger" ) // WhatsAppCallService implements business logic for WhatsAppCall operations. type WhatsAppCallService struct { repo *repository.WhatsAppCallRepo } // NewWhatsAppCallService creates a new WhatsAppCall service. func NewWhatsAppCallService(repo *repository.WhatsAppCallRepo) *WhatsAppCallService { return &WhatsAppCallService{repo: repo} } // WhatsAppCallCreateRequest is the DTO for creating a WhatsApp call. type WhatsAppCallCreateRequest struct { CallID string `json:"call_id" validate:"required"` InboxID uint `json:"inbox_id" validate:"required"` ConversationID uint `json:"conversation_id" validate:"required"` CallStatus string `json:"call_status" validate:"required"` Duration int `json:"duration"` CallerNumber string `json:"caller_number"` } // validCallStatuses defines allowed WhatsApp call status values. var validCallStatuses = map[string]bool{"ringing": true, "active": true, "ended": true, "failed": true} // GetByCallID retrieves a WhatsApp call by its call ID. func (s *WhatsAppCallService) GetByCallID(ctx context.Context, callID string) (*model.WhatsAppCall, error) { call, err := s.repo.FindByCallID(ctx, callID) if err != nil { applogger.L().Errorf("WhatsAppCallService.GetByCallID error: %v", err) return nil, err } return call, nil } // ListByConversation retrieves all WhatsApp calls for a conversation. func (s *WhatsAppCallService) ListByConversation(ctx context.Context, conversationID uint) ([]model.WhatsAppCall, error) { calls, err := s.repo.FindByConversationID(ctx, conversationID) if err != nil { applogger.L().Errorf("WhatsAppCallService.ListByConversation error: %v", err) return nil, err } return calls, nil } // CreateFromRequest creates a new WhatsApp call record from a DTO. func (s *WhatsAppCallService) CreateFromRequest(ctx context.Context, req *WhatsAppCallCreateRequest) (*model.WhatsAppCall, error) { if !validCallStatuses[req.CallStatus] { return nil, errors.New("invalid call_status: must be ringing/active/ended/failed") } call := &model.WhatsAppCall{ CallID: req.CallID, InboxID: req.InboxID, ConversationID: req.ConversationID, CallStatus: req.CallStatus, Duration: req.Duration, CallerNumber: req.CallerNumber, } if err := s.repo.Create(ctx, call); err != nil { applogger.L().Errorf("WhatsAppCallService.CreateFromRequest error: %v", err) return nil, err } return call, nil } // UpdateByCallID updates a WhatsApp call by its call_id (e.g. status transition). func (s *WhatsAppCallService) UpdateByCallID(ctx context.Context, callID string, callStatus string, duration int) (*model.WhatsAppCall, error) { if !validCallStatuses[callStatus] { return nil, errors.New("invalid call_status: must be ringing/active/ended/failed") } call, err := s.repo.FindByCallID(ctx, callID) if err != nil { return nil, err } call.CallStatus = callStatus call.Duration = duration if err := s.repo.Update(ctx, call); err != nil { applogger.L().Errorf("WhatsAppCallService.UpdateByCallID error: %v", err) return nil, err } return call, nil } // DeleteByCallID deletes a WhatsApp call record by call_id. func (s *WhatsAppCallService) DeleteByCallID(ctx context.Context, callID string) error { call, err := s.repo.FindByCallID(ctx, callID) if err != nil { return err } if err := s.repo.Delete(ctx, call.ID); err != nil { applogger.L().Errorf("WhatsAppCallService.DeleteByCallID error: %v", err) return err } return nil }