package service import ( "context" "sync" "time" "github.com/dnoulet/go-first/internal/model" "github.com/google/uuid" "github.com/rs/zerolog/log" ) type ContactService struct { mu sync.RWMutex submissions map[uuid.UUID]*model.ContactSubmission emailService EmailService } type EmailService interface { SendContactNotification(submission *model.ContactSubmission) error SendAutoReply(submission *model.ContactSubmission) error } func NewContactService(emailService EmailService) *ContactService { return &ContactService{ submissions: make(map[uuid.UUID]*model.ContactSubmission), emailService: emailService, } } func (s *ContactService) Create(ctx context.Context, req *model.ContactForm) (*model.ContactSubmission, error) { submission := &model.ContactSubmission{ ID: uuid.New(), Name: req.Name, Email: req.Email, Subject: req.Subject, Message: req.Message, Status: "new", CreatedAt: time.Now(), UpdatedAt: time.Now(), } s.mu.Lock() s.submissions[submission.ID] = submission s.mu.Unlock() if s.emailService != nil { go func() { if err := s.emailService.SendContactNotification(submission); err != nil { log.Error().Err(err).Msg("Failed to send contact notification email") } if err := s.emailService.SendAutoReply(submission); err != nil { log.Error().Err(err).Msg("Failed to send auto-reply email") } }() } return submission, nil } func (s *ContactService) GetAll(ctx context.Context) ([]*model.ContactSubmission, error) { s.mu.RLock() defer s.mu.RUnlock() var result []*model.ContactSubmission for _, sub := range s.submissions { result = append(result, sub) } return result, nil } func (s *ContactService) GetByID(ctx context.Context, id uuid.UUID) (*model.ContactSubmission, error) { s.mu.RLock() defer s.mu.RUnlock() sub, ok := s.submissions[id] if !ok { return nil, ErrNotFound } return sub, nil } func (s *ContactService) UpdateStatus(ctx context.Context, id uuid.UUID, status string) (*model.ContactSubmission, error) { s.mu.Lock() defer s.mu.Unlock() sub, ok := s.submissions[id] if !ok { return nil, ErrNotFound } sub.Status = status sub.UpdatedAt = time.Now() return sub, nil } func (s *ContactService) Delete(ctx context.Context, id uuid.UUID) error { s.mu.Lock() defer s.mu.Unlock() if _, ok := s.submissions[id]; !ok { return ErrNotFound } delete(s.submissions, id) return nil }