package service import ( "context" "errors" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" applogger "github.com/gochat/gochat/pkg/logger" ) // BannerService implements business logic for Banner operations. // Reference: Chatwoot Platform::Api::V1::BannersController — super-admin CRUD, // and api/v1/accounts/:account_id/banners — read-only list of active banners. type BannerService struct { repo *repository.BannerRepo } // NewBannerService creates a new BannerService. func NewBannerService(repo *repository.BannerRepo) *BannerService { return &BannerService{repo: repo} } // List retrieves all banners with pagination (platform admin). func (s *BannerService) List(ctx context.Context, offset, limit int) ([]model.Banner, int64, error) { banners, total, err := s.repo.List(ctx, offset, limit) if err != nil { applogger.L().Errorf("BannerService.List error: %v", err) return nil, 0, err } return banners, total, nil } // Get retrieves a single banner by ID. func (s *BannerService) Get(ctx context.Context, id uint) (*model.Banner, error) { banner, err := s.repo.FindByID(ctx, id) if err != nil { applogger.L().Errorf("BannerService.Get error: %v", err) return nil, err } return banner, nil } // Create creates a new banner. func (s *BannerService) Create(ctx context.Context, banner *model.Banner) error { if banner.Title == "" { return errors.New("title is required") } if banner.Content == "" { return errors.New("content is required") } if banner.BannerType == "" { return errors.New("banner_type is required") } if err := s.repo.Create(ctx, banner); err != nil { applogger.L().Errorf("BannerService.Create error: %v", err) return err } return nil } // Update patches an existing banner. func (s *BannerService) Update(ctx context.Context, id uint, updates map[string]interface{}) error { if id == 0 { return errors.New("invalid banner ID") } if err := s.repo.Update(ctx, id, updates); err != nil { applogger.L().Errorf("BannerService.Update error: %v", err) return err } return nil } // Delete soft-deletes a banner by ID. func (s *BannerService) Delete(ctx context.Context, id uint) error { if id == 0 { return errors.New("invalid banner ID") } if err := s.repo.Delete(ctx, id); err != nil { applogger.L().Errorf("BannerService.Delete error: %v", err) return err } return nil } // ListActive returns all active banners (for account-scoped read-only endpoint). func (s *BannerService) ListActive(ctx context.Context) ([]model.Banner, error) { banners, err := s.repo.FindActive(ctx) if err != nil { applogger.L().Errorf("BannerService.ListActive error: %v", err) return nil, err } return banners, nil }