package calendar import ( "context" "strings" "time" "github.com/ultisuite/ulti-backend/internal/api/paginate" "github.com/ultisuite/ulti-backend/internal/api/query" "github.com/ultisuite/ulti-backend/internal/nextcloud" ) type Service struct { nc *nextcloud.Client } func NewService(nc *nextcloud.Client) *Service { return &Service{nc: nc} } func calendarPath(userID, calID string) string { return "/remote.php/dav/calendars/" + userID + "/" + calID + "/" } func (s *Service) ListCalendars(ctx context.Context, userID string) ([]nextcloud.Calendar, error) { return s.nc.ListCalendars(ctx, userID) } type EventsList struct { Events []nextcloud.Event `json:"events"` Pagination query.PaginationMeta `json:"pagination,omitempty"` } func (s *Service) ListEvents(ctx context.Context, userID, calID string, params query.ListParams) (EventsList, error) { from := time.Now().AddDate(0, -1, 0) to := time.Now().AddDate(0, 1, 0) if params.From != nil { from = *params.From } if params.To != nil { to = *params.To } events, err := s.nc.ListEvents(ctx, userID, calendarPath(userID, calID), from, to) if err != nil { return EventsList{}, err } filtered := filterEvents(events, params.Q) page, total := paginate.Slice(filtered, params.Offset(), params.Limit()) return EventsList{ Events: page, Pagination: params.Meta(&total), }, nil } func (s *Service) CreateEvent(ctx context.Context, userID, calID string, event *nextcloud.Event) error { return s.nc.CreateEvent(ctx, userID, calendarPath(userID, calID), event) } func (s *Service) DeleteEvent(ctx context.Context, userID, eventPath string) error { return s.nc.DeleteEvent(ctx, userID, eventPath) } func filterEvents(events []nextcloud.Event, q string) []nextcloud.Event { q = strings.ToLower(strings.TrimSpace(q)) if q == "" { return events } out := make([]nextcloud.Event, 0, len(events)) for _, e := range events { if strings.Contains(strings.ToLower(e.Summary), q) || strings.Contains(strings.ToLower(e.Description), q) || strings.Contains(strings.ToLower(e.Location), q) { out = append(out, e) } } return out }