package services import ( "errors" "fmt" "regexp" "strings" "gauth-central/internal/database" "gauth-central/internal/models" "github.com/google/uuid" "gorm.io/gorm" ) type PostCommentService struct{} func NewPostCommentService() *PostCommentService { return &PostCommentService{} } func (s *PostCommentService) CreatePostComment( userID uuid.UUID, postID uuid.UUID, title string, body string, parentID *uuid.UUID, isActive bool, ) (*models.PostComment, error) { slug := s.generateUniqueSlug(slugifyPostComment(title), "") if slug == "" { return nil, errors.New("slug cannot be empty") } comment := models.PostComment{ UserID: userID, PostID: postID, Title: title, Body: body, ParentID: parentID, Slug: slug, IsActive: isActive, } if err := database.DB.Create(&comment).Error; err != nil { return nil, err } return s.GetPostCommentByID(comment.ID.String()) } func (s *PostCommentService) GetPostCommentsByPostID(postID string, onlyActive bool) ([]models.PostComment, error) { var comments []models.PostComment query := database.DB.Preload("User").Where("post_id = ?", postID).Order("created_at desc") if onlyActive { query = query.Where("is_active = ?", true) } if err := query.Find(&comments).Error; err != nil { return nil, err } return comments, nil } func (s *PostCommentService) GetAllPostComments(postID *string, onlyActive bool) ([]models.PostComment, error) { var comments []models.PostComment query := database.DB.Preload("User").Order("created_at desc") if postID != nil { query = query.Where("post_id = ?", *postID) } if onlyActive { query = query.Where("is_active = ?", true) } if err := query.Find(&comments).Error; err != nil { return nil, err } return comments, nil } func (s *PostCommentService) GetPostCommentByID(id string) (*models.PostComment, error) { var comment models.PostComment if err := database.DB.Preload("User").Where("id = ?", id).First(&comment).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("post comment not found") } return nil, err } return &comment, nil } func (s *PostCommentService) UpdatePostComment( id string, title *string, body *string, parentID *uuid.UUID, parentIDSet bool, slug *string, isActive *bool, ) (*models.PostComment, error) { comment, err := s.GetPostCommentByID(id) if err != nil { return nil, err } updates := map[string]interface{}{} if title != nil { updates["title"] = *title } if body != nil { updates["body"] = *body } if parentIDSet { updates["parent_id"] = parentID } if slug != nil { clean := slugifyPostComment(*slug) if clean == "" { return nil, errors.New("slug cannot be empty") } if s.slugExists(clean, id) { return nil, errors.New("slug already exists") } updates["slug"] = clean } if isActive != nil { updates["is_active"] = *isActive } if len(updates) > 0 { if err := database.DB.Model(comment).Updates(updates).Error; err != nil { return nil, err } } return s.GetPostCommentByID(id) } func (s *PostCommentService) DeletePostComment(id string) error { result := database.DB.Delete(&models.PostComment{}, "id = ?", id) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { return errors.New("post comment not found") } return nil } func (s *PostCommentService) generateUniqueSlug(baseSlug string, excludeID string) string { slug := baseSlug counter := 1 for s.slugExists(slug, excludeID) { slug = fmt.Sprintf("%s-%d", baseSlug, counter) counter++ } return slug } func (s *PostCommentService) slugExists(slug string, excludeID string) bool { var count int64 query := database.DB.Model(&models.PostComment{}).Where("slug = ?", slug) if excludeID != "" { query = query.Where("id <> ?", excludeID) } query.Count(&count) return count > 0 } func slugifyPostComment(input string) string { clean := strings.TrimSpace(input) if clean == "" { return "" } replacer := strings.NewReplacer( "ı", "i", "İ", "i", "ş", "s", "Ş", "s", "ğ", "g", "Ğ", "g", "ç", "c", "Ç", "c", "ö", "o", "Ö", "o", "ü", "u", "Ü", "u", ) clean = strings.ToLower(replacer.Replace(clean)) re := regexp.MustCompile(`[^a-z0-9]+`) clean = re.ReplaceAllString(clean, "-") clean = strings.Trim(clean, "-") if clean == "" { return "comment" } return clean }