package service import ( "errors" "git.urec56.ru/urec/chat_back_go/internal/domain" "git.urec56.ru/urec/chat_back_go/internal/logger" "git.urec56.ru/urec/chat_back_go/internal/repository" ) type messageService struct { repo repository.Message u User l *logger.Logger } func newMessageService(repo repository.Message, u User, l *logger.Logger) *messageService { return &messageService{repo: repo, u: u, l: l} } func (s *messageService) AddAvatarImageAndUsernameToMessage(msgRaw domain.RawMessage) (domain.Message, error) { u, err := s.u.Get(msgRaw.UserID, true) if err != nil { s.l.Infof("error adding image and username to message: %s", err) return domain.Message{}, domain.InternalServerError } return domain.Message{ ID: msgRaw.ID, Message: msgRaw.Message, ImageUrl: msgRaw.ImageUrl, ChatID: msgRaw.ChatID, UserID: msgRaw.UserID, Username: u.Username, AvatarImage: u.AvatarImage, CreatedAt: msgRaw.CreatedAt, AnswerID: msgRaw.AnswerID, AnswerMessage: msgRaw.AnswerMessage, AnswerImageUrl: msgRaw.AnswerImageUrl, }, nil } func (s *messageService) AddAvatarImageAndUsernameToMessages(msgsRaw []domain.RawMessage) []domain.Message { msgs := make([]domain.Message, 0, len(msgsRaw)) for _, v := range msgsRaw { msg, err := s.AddAvatarImageAndUsernameToMessage(v) if err != nil { continue } msgs = append(msgs, msg) } return msgs } func (s *messageService) GetRaw(ID domain.UUID) (domain.RawMessage, error) { rawMessage, err := s.repo.Get(ID) if err != nil { s.l.Infof("error getting message: %s", err) return domain.RawMessage{}, domain.InternalServerError } return rawMessage, nil } func (s *messageService) GetMessage(ID domain.UUID) (domain.Message, error) { rawMessage, err := s.GetRaw(ID) if err != nil { return domain.Message{}, domain.InternalServerError } newMessage, err := s.AddAvatarImageAndUsernameToMessage(rawMessage) if err != nil { return domain.Message{}, domain.InternalServerError } return newMessage, nil } func (s *messageService) GetPinned(chatID int) ([]domain.Message, error) { IDs, err := s.repo.GetPinnedIDs(chatID) if err != nil { s.l.Infof("error getting pinned ids: %s", err) return nil, domain.InternalServerError } rawMessages, err := s.repo.GetByIDs(IDs) if err != nil { s.l.Infof("error messages by ids: %s", err) return nil, domain.InternalServerError } messages := s.AddAvatarImageAndUsernameToMessages(rawMessages) return messages, nil } func (s *messageService) GetSome(chatID, offset, limit int) ([]domain.Message, error) { messagesRaw, err := s.repo.GetSome(repository.GetSome{ChatID: chatID, Offset: offset, Limit: limit}) if err != nil { s.l.Infof("error getting some messages: %s", err) return nil, domain.InternalServerError } messages := s.AddAvatarImageAndUsernameToMessages(messagesRaw) return messages, nil } func (s *messageService) SendMessage(userID, chatID int, message domain.SendMessage) (domain.Message, error) { var rawMessage domain.RawMessage var err error if message.Answer.IsZero() { rawMessage, err = s.repo.Send(repository.SendMessage{ Message: message.Message, ImageUrl: message.ImageUrl, ChatID: chatID, UserID: userID, }) if err != nil { s.l.Infof("error sending message: %s", err) return domain.Message{}, domain.InternalServerError } } else { answerMessage, err := s.GetRaw(message.Answer) if err != nil { s.l.Infof("error getting message: %s", err) return domain.Message{}, domain.InternalServerError } rawMessage, err = s.repo.Send(repository.SendMessage{ Message: message.Message, ImageUrl: message.ImageUrl, ChatID: chatID, UserID: userID, AnswerID: message.Answer, AnswerMessage: answerMessage.Message, AnswerImageUrl: answerMessage.ImageUrl, }) if err != nil { s.l.Infof("error sending message: %s", err) return domain.Message{}, domain.InternalServerError } } newMessage, err := s.AddAvatarImageAndUsernameToMessage(rawMessage) if err != nil { s.l.Infof("error getting message: %s", err) return domain.Message{}, domain.InternalServerError } return newMessage, nil } func (s *messageService) Delete(ID domain.UUID) error { if err := s.repo.Delete(ID); err != nil { s.l.Infof("error deleting message: %s", err) return domain.InternalServerError } return nil } func (s *messageService) Edit(ID domain.UUID, newMessage, newImageUrl string) error { if err := s.repo.Edit(repository.EditMessage{ID: ID, Message: newMessage, ImageUrl: newImageUrl}); err != nil { s.l.Infof("error editing message: %s", err) return domain.InternalServerError } return nil } func (s *messageService) Pin(chatID, userID int, messageID domain.UUID) (domain.Message, error) { err := s.repo.Pin(repository.PinMessage{ChatID: chatID, UserID: userID, MessageID: messageID}) if err != nil { if errors.Is(err, domain.MessageAlreadyPinnedError) { return domain.Message{}, err } s.l.Infof("error pinning message: %s", err) return domain.Message{}, domain.InternalServerError } message, err := s.GetMessage(messageID) if err != nil { s.l.Infof("error getting message: %s", err) return domain.Message{}, domain.InternalServerError } return message, nil } func (s *messageService) Unpin(chatID int, messageID domain.UUID) error { err := s.repo.Unpin(repository.UnpinMessage{ChatID: chatID, MessageID: messageID}) if err != nil { s.l.Infof("error unpinning message: %s", err) return domain.InternalServerError } return nil }