package repository import ( "database/sql" "time" "aggios-app/backend/internal/domain" "github.com/google/uuid" ) // SubscriptionRepository handles database operations for subscriptions type SubscriptionRepository struct { db *sql.DB } // NewSubscriptionRepository creates a new subscription repository func NewSubscriptionRepository(db *sql.DB) *SubscriptionRepository { return &SubscriptionRepository{db: db} } // Create creates a new subscription func (r *SubscriptionRepository) Create(subscription *domain.Subscription) error { query := ` INSERT INTO agency_subscriptions (id, agency_id, plan_id, billing_type, current_users, status, start_date, renewal_date, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at ` now := time.Now() subscription.ID = uuid.New() subscription.CreatedAt = now subscription.UpdatedAt = now subscription.StartDate = now // Set renewal date based on billing type if subscription.BillingType == "annual" { subscription.RenewalDate = now.AddDate(1, 0, 0) } else { subscription.RenewalDate = now.AddDate(0, 1, 0) } return r.db.QueryRow( query, subscription.ID, subscription.AgencyID, subscription.PlanID, subscription.BillingType, subscription.CurrentUsers, subscription.Status, subscription.StartDate, subscription.RenewalDate, subscription.CreatedAt, subscription.UpdatedAt, ).Scan(&subscription.ID, &subscription.CreatedAt, &subscription.UpdatedAt) } // GetByID retrieves a subscription by ID func (r *SubscriptionRepository) GetByID(id uuid.UUID) (*domain.Subscription, error) { query := ` SELECT id, agency_id, plan_id, billing_type, current_users, status, start_date, renewal_date, created_at, updated_at FROM agency_subscriptions WHERE id = $1 ` subscription := &domain.Subscription{} err := r.db.QueryRow(query, id).Scan( &subscription.ID, &subscription.AgencyID, &subscription.PlanID, &subscription.BillingType, &subscription.CurrentUsers, &subscription.Status, &subscription.StartDate, &subscription.RenewalDate, &subscription.CreatedAt, &subscription.UpdatedAt, ) return subscription, err } // GetByAgencyID retrieves a subscription by agency ID func (r *SubscriptionRepository) GetByAgencyID(agencyID uuid.UUID) (*domain.Subscription, error) { query := ` SELECT id, agency_id, plan_id, billing_type, current_users, status, start_date, renewal_date, created_at, updated_at FROM agency_subscriptions WHERE agency_id = $1 AND status = 'active' LIMIT 1 ` subscription := &domain.Subscription{} err := r.db.QueryRow(query, agencyID).Scan( &subscription.ID, &subscription.AgencyID, &subscription.PlanID, &subscription.BillingType, &subscription.CurrentUsers, &subscription.Status, &subscription.StartDate, &subscription.RenewalDate, &subscription.CreatedAt, &subscription.UpdatedAt, ) return subscription, err } // ListAll retrieves all subscriptions func (r *SubscriptionRepository) ListAll() ([]*domain.Subscription, error) { query := ` SELECT id, agency_id, plan_id, billing_type, current_users, status, start_date, renewal_date, created_at, updated_at FROM agency_subscriptions ORDER BY created_at DESC ` rows, err := r.db.Query(query) if err != nil { return nil, err } defer rows.Close() var subscriptions []*domain.Subscription for rows.Next() { subscription := &domain.Subscription{} err := rows.Scan( &subscription.ID, &subscription.AgencyID, &subscription.PlanID, &subscription.BillingType, &subscription.CurrentUsers, &subscription.Status, &subscription.StartDate, &subscription.RenewalDate, &subscription.CreatedAt, &subscription.UpdatedAt, ) if err != nil { return nil, err } subscriptions = append(subscriptions, subscription) } return subscriptions, rows.Err() } // Update updates a subscription func (r *SubscriptionRepository) Update(subscription *domain.Subscription) error { query := ` UPDATE agency_subscriptions SET plan_id = $2, billing_type = $3, current_users = $4, status = $5, renewal_date = $6, updated_at = $7 WHERE id = $1 RETURNING updated_at ` subscription.UpdatedAt = time.Now() return r.db.QueryRow( query, subscription.ID, subscription.PlanID, subscription.BillingType, subscription.CurrentUsers, subscription.Status, subscription.RenewalDate, subscription.UpdatedAt, ).Scan(&subscription.UpdatedAt) } // Delete deletes a subscription func (r *SubscriptionRepository) Delete(id uuid.UUID) error { query := `DELETE FROM agency_subscriptions WHERE id = $1` result, err := r.db.Exec(query, id) if err != nil { return err } rowsAffected, err := result.RowsAffected() if err != nil { return err } if rowsAffected == 0 { return sql.ErrNoRows } return nil } // UpdateUserCount updates the current user count for a subscription func (r *SubscriptionRepository) UpdateUserCount(agencyID uuid.UUID, userCount int) error { query := ` UPDATE agency_subscriptions SET current_users = $2, updated_at = $3 WHERE agency_id = $1 AND status = 'active' ` _, err := r.db.Exec(query, agencyID, userCount, time.Now()) return err }