package feedback import ( "context" "tm/pkg/logger" "tm/pkg/response" ) // FeedbackService interface defines feedback business logic methods type FeedbackService interface { ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error) GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error) DeleteFeedback(ctx context.Context, id string) error GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error) } // feedbackService implements FeedbackService interface type feedbackService struct { feedbackRepo Repository logger logger.Logger } // NewFeedbackService creates a new feedback service func NewFeedbackService(feedbackRepo Repository, logger logger.Logger) FeedbackService { return &feedbackService{ feedbackRepo: feedbackRepo, logger: logger, } } func (s *feedbackService) ToggleFeedback(ctx context.Context, req ToggleFeedbackForm, customerID *string, companyID *string) (*FeedbackResponse, error) { existing, err := s.feedbackRepo.GetByCompanyID(ctx, *companyID, req.TenderID) if err != nil { feedback := &Feedback{ TenderID: req.TenderID, FeedbackType: req.FeedbackType, CompanyID: companyID, CustomerID: customerID, } err = s.feedbackRepo.Create(ctx, feedback) if err != nil { s.logger.Error("Failed to create new feedback", map[string]interface{}{ "tender_id": req.TenderID, "company_id": *companyID, "error": err.Error(), }) return nil, err } return feedback.ToResponse(), nil } if existing.FeedbackType == req.FeedbackType { err = s.feedbackRepo.Delete(ctx, existing.GetID()) if err != nil { s.logger.Error("Failed to update existing feedback", map[string]interface{}{ "feedback_id": existing.GetID(), "tender_id": req.TenderID, "company_id": *companyID, "error": err.Error(), }) return nil, err } if req.FeedbackType == FeedbackTypeLike { existing.FeedbackType = "unlike" } else { existing.FeedbackType = "undislike" } return existing.ToResponse(), nil } if existing.FeedbackType == FeedbackTypeLike { existing.FeedbackType = FeedbackTypeDislike } else { existing.FeedbackType = FeedbackTypeLike } err = s.feedbackRepo.Update(ctx, existing) if err != nil { s.logger.Error("Failed to update existing feedback", map[string]interface{}{ "feedback_id": existing.GetID(), "tender_id": req.TenderID, "company_id": *companyID, "error": err.Error(), }) return nil, err } return existing.ToResponse(), nil } func (s *feedbackService) GetFeedback(ctx context.Context, id string) (*FeedbackResponse, error) { feedback, err := s.feedbackRepo.GetByID(ctx, id) if err != nil { s.logger.Error("Failed to get feedback", map[string]interface{}{ "id": id, "error": err.Error(), }) return nil, err } return feedback.ToResponse(), nil } func (s *feedbackService) ListFeedback(ctx context.Context, criteria FeedbackSearchCriteria, limit, offset int) (*FeedbackListResponse, error) { feedbacks, total, err := s.feedbackRepo.List(ctx, criteria, limit, offset) if err != nil { s.logger.Error("Failed to list feedback", map[string]interface{}{ "criteria": criteria, "limit": limit, "offset": offset, "error": err.Error(), }) return nil, err } meta := &response.Meta{ Total: int(total), Limit: limit, Offset: offset, Page: (offset / limit) + 1, Pages: int((total + int64(limit) - 1) / int64(limit)), } result := make([]*FeedbackResponse, len(feedbacks)) for i, feedback := range feedbacks { result[i] = feedback.ToResponse() } return &FeedbackListResponse{ Feedback: result, Meta: meta, }, nil } func (s *feedbackService) DeleteFeedback(ctx context.Context, id string) error { return s.feedbackRepo.Delete(ctx, id) } func (s *feedbackService) GetFeedbackByTenderID(ctx context.Context, tenderID, companyID string) (*FeedbackResponse, error) { feedback, err := s.feedbackRepo.GetByTenderID(ctx, tenderID, companyID) if err != nil { s.logger.Error("Failed to get feedback by tender ID", map[string]interface{}{ "tender_id": tenderID, "error": err.Error(), }) return nil, err } return feedback.ToResponse(), nil }