package learnernotifications import ( "context" "fmt" "time" "Yimaru-Backend/internal/domain" notificationservice "Yimaru-Backend/internal/services/notification" ) // Service sends learner-facing in-app and push notifications. type Service struct { notifications *notificationservice.Service } func New(notifications *notificationservice.Service) *Service { return &Service{notifications: notifications} } func (s *Service) NotifyWelcome(userID int64) { s.send(userID, domain.NOTIFICATION_TYPE_USER_WELCOME, domain.NotificationLevelSuccess, "Welcome to Yimaru Academy", "Your account is ready. Start learning and track your progress across programs and courses.") } func (s *Service) NotifyModuleCompleted(userID int64, moduleName string) { s.send(userID, domain.NOTIFICATION_TYPE_MODULE_COMPLETED, domain.NotificationLevelSuccess, "Module completed", fmt.Sprintf("Great work! You completed the module \"%s\".", moduleName)) } func (s *Service) NotifyCourseCompleted(userID int64, courseName string) { s.send(userID, domain.NOTIFICATION_TYPE_COURSE_COMPLETED, domain.NotificationLevelSuccess, "Course completed", fmt.Sprintf("Congratulations! You completed the course \"%s\".", courseName)) } func (s *Service) NotifyProgramCompleted(userID int64, programName string) { s.send(userID, domain.NOTIFICATION_TYPE_PROGRAM_COMPLETED, domain.NotificationLevelSuccess, "Program completed", fmt.Sprintf("Amazing achievement! You completed the program \"%s\".", programName)) } func (s *Service) NotifyLearnPackageSubscribed(userID int64, planName string) { s.send(userID, domain.NOTIFICATION_TYPE_SUBSCRIPTION_ACTIVATED, domain.NotificationLevelSuccess, "Subscription active", fmt.Sprintf("Your \"%s\" Learn English package is now active. Enjoy your learning journey!", planName)) } func (s *Service) NotifyLearnPackageExpiringSoon(userID int64, planName string, expiresAt time.Time) { s.send(userID, domain.NOTIFICATION_TYPE_SUBSCRIPTION_EXPIRING, domain.NotificationLevelWarning, "Subscription expiring soon", fmt.Sprintf("Your \"%s\" package expires on %s. Renew to keep uninterrupted access.", planName, expiresAt.Format("Jan 2, 2006"))) } func (s *Service) MaybeNotifyLearnPackageSubscribed(userID int64, planCategory, planName string) { if planCategory == string(domain.SubscriptionCategoryLearnEnglish) { s.NotifyLearnPackageSubscribed(userID, planName) } } func (s *Service) NotifyLMSPracticeMilestones(userID int64, result domain.LMSPracticeCompletionResult) { if result.ModuleCompleted != nil { s.NotifyModuleCompleted(userID, result.ModuleCompleted.Name) } if result.CourseCompleted != nil { s.NotifyCourseCompleted(userID, result.CourseCompleted.Name) } if result.ProgramCompleted != nil { s.NotifyProgramCompleted(userID, result.ProgramCompleted.Name) } } func (s *Service) SendLearnPackageExpiryReminders(reminders []domain.SubscriptionExpiryReminder) { for _, r := range reminders { s.NotifyLearnPackageExpiringSoon(r.UserID, r.PlanName, r.ExpiresAt) } } func (s *Service) send(userID int64, notifType domain.NotificationType, level domain.NotificationLevel, headline, message string) { if s == nil || s.notifications == nil || userID == 0 { return } go func() { ctx := context.Background() for _, channel := range []domain.DeliveryChannel{ domain.DeliveryChannelInApp, domain.DeliveryChannelPush, } { notification := &domain.Notification{ RecipientID: userID, ReceiverType: domain.ReceiverTypeUser, Type: notifType, Level: level, Reciever: domain.NotificationRecieverSideCustomer, DeliveryChannel: channel, DeliveryStatus: domain.DeliveryStatusPending, IsRead: false, Payload: domain.NotificationPayload{ Headline: headline, Message: message, }, } _ = s.notifications.SendNotification(ctx, notification) } }() }