package usecase import ( "context" "math" "strings" "github.com/gofrs/uuid/v5" "github.com/saveinmed/backend-go/internal/domain" ) // RegisterProduct generates an ID and persists a new product. func (s *Service) RegisterProduct(ctx context.Context, product *domain.Product) error { product.ID = uuid.Must(uuid.NewV7()) return s.repo.CreateProduct(ctx, product) } // ListProducts returns a paginated list of products matching the filter. func (s *Service) ListProducts(ctx context.Context, filter domain.ProductFilter, page, pageSize int) (*domain.ProductPage, error) { if pageSize <= 0 { pageSize = 20 } if page <= 0 { page = 1 } filter.Limit = pageSize filter.Offset = (page - 1) * pageSize products, total, err := s.repo.ListProducts(ctx, filter) if err != nil { return nil, err } return &domain.ProductPage{Products: products, Total: total, Page: page, PageSize: pageSize}, nil } // SearchProducts returns products with distance, ordered by expiration date. // Seller info is anonymised until checkout. func (s *Service) SearchProducts(ctx context.Context, filter domain.ProductSearchFilter, page, pageSize int) (*domain.ProductSearchPage, error) { if pageSize <= 0 { pageSize = 20 } if page <= 0 { page = 1 } filter.Limit = pageSize filter.Offset = (page - 1) * pageSize products, total, err := s.repo.SearchProducts(ctx, filter) if err != nil { return nil, err } return &domain.ProductSearchPage{Products: products, Total: total, Page: page, PageSize: pageSize}, nil } // ListRecords provides advanced search for marketplace listings. func (s *Service) ListRecords(ctx context.Context, req domain.SearchRequest) (*domain.PaginationResponse[domain.Product], error) { page := req.Page pageSize := req.PageSize if pageSize <= 0 { pageSize = 20 } if page <= 0 { page = 1 } sortBy := strings.TrimSpace(req.SortBy) if sortBy == "" { sortBy = "updated_at" } sortOrder := strings.ToLower(strings.TrimSpace(req.SortOrder)) if sortOrder == "" { sortOrder = "desc" } filter := domain.RecordSearchFilter{ Query: strings.TrimSpace(req.Query), SortBy: sortBy, SortOrder: sortOrder, CreatedAfter: req.CreatedAfter, CreatedBefore: req.CreatedBefore, Limit: pageSize, Offset: (page - 1) * pageSize, } items, total, err := s.repo.ListRecords(ctx, filter) if err != nil { return nil, err } totalPages := int(math.Ceil(float64(total) / float64(pageSize))) return &domain.PaginationResponse[domain.Product]{ Items: items, TotalCount: total, CurrentPage: page, TotalPages: totalPages, }, nil } // GetProduct retrieves a product by ID. func (s *Service) GetProduct(ctx context.Context, id uuid.UUID) (*domain.Product, error) { return s.repo.GetProduct(ctx, id) } // UpdateProduct persists changes to a product. func (s *Service) UpdateProduct(ctx context.Context, product *domain.Product) error { return s.repo.UpdateProduct(ctx, product) } // DeleteProduct removes a product by ID. func (s *Service) DeleteProduct(ctx context.Context, id uuid.UUID) error { return s.repo.DeleteProduct(ctx, id) } // ListInventory returns a paginated list of inventory items for a seller. func (s *Service) ListInventory(ctx context.Context, filter domain.InventoryFilter, page, pageSize int) (*domain.InventoryPage, error) { if pageSize <= 0 { pageSize = 20 } if page <= 0 { page = 1 } filter.Limit = pageSize filter.Offset = (page - 1) * pageSize items, total, err := s.repo.ListInventory(ctx, filter) if err != nil { return nil, err } return &domain.InventoryPage{Items: items, Total: total, Page: page, PageSize: pageSize}, nil } // AdjustInventory increments or decrements the stock of a product. func (s *Service) AdjustInventory(ctx context.Context, productID uuid.UUID, delta int64, reason string) (*domain.InventoryItem, error) { return s.repo.AdjustInventory(ctx, productID, delta, reason) } // ListManufacturers returns all distinct manufacturer names in the catalogue. func (s *Service) ListManufacturers(ctx context.Context) ([]string, error) { return s.repo.ListManufacturers(ctx) }