package repository import ( "context" "time" "eslogad-be/internal/entities" "github.com/google/uuid" "gorm.io/gorm" ) type VoteEventRepositoryImpl struct { db *gorm.DB } func NewVoteEventRepository(db *gorm.DB) *VoteEventRepositoryImpl { return &VoteEventRepositoryImpl{ db: db, } } func (r *VoteEventRepositoryImpl) Create(ctx context.Context, voteEvent *entities.VoteEvent) error { return r.db.WithContext(ctx).Create(voteEvent).Error } func (r *VoteEventRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.VoteEvent, error) { var voteEvent entities.VoteEvent err := r.db.WithContext(ctx). Preload("Candidates"). First(&voteEvent, "id = ?", id).Error if err != nil { return nil, err } return &voteEvent, nil } func (r *VoteEventRepositoryImpl) GetActiveEvents(ctx context.Context) ([]*entities.VoteEvent, error) { var events []*entities.VoteEvent now := time.Now() err := r.db.WithContext(ctx). Preload("Candidates"). Where("is_active = ? AND start_date <= ? AND end_date >= ?", true, now, now). Find(&events).Error return events, err } func (r *VoteEventRepositoryImpl) List(ctx context.Context, limit, offset int) ([]*entities.VoteEvent, int64, error) { var events []*entities.VoteEvent var total int64 if err := r.db.WithContext(ctx).Model(&entities.VoteEvent{}).Count(&total).Error; err != nil { return nil, 0, err } err := r.db.WithContext(ctx). Preload("Candidates"). Limit(limit). Offset(offset). Order("created_at DESC"). Find(&events).Error return events, total, err } func (r *VoteEventRepositoryImpl) Update(ctx context.Context, voteEvent *entities.VoteEvent) error { return r.db.WithContext(ctx).Save(voteEvent).Error } func (r *VoteEventRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error { return r.db.WithContext(ctx).Delete(&entities.VoteEvent{}, "id = ?", id).Error } func (r *VoteEventRepositoryImpl) CreateCandidate(ctx context.Context, candidate *entities.Candidate) error { return r.db.WithContext(ctx).Create(candidate).Error } func (r *VoteEventRepositoryImpl) GetCandidatesByEventID(ctx context.Context, eventID uuid.UUID) ([]*entities.Candidate, error) { var candidates []*entities.Candidate err := r.db.WithContext(ctx). Where("vote_event_id = ?", eventID). Find(&candidates).Error return candidates, err } func (r *VoteEventRepositoryImpl) SubmitVote(ctx context.Context, vote *entities.Vote) error { return r.db.WithContext(ctx).Create(vote).Error } func (r *VoteEventRepositoryImpl) HasUserVoted(ctx context.Context, userID, eventID uuid.UUID) (bool, error) { var count int64 err := r.db.WithContext(ctx). Model(&entities.Vote{}). Where("user_id = ? AND vote_event_id = ?", userID, eventID). Count(&count).Error return count > 0, err } func (r *VoteEventRepositoryImpl) GetVoteResults(ctx context.Context, eventID uuid.UUID) (map[uuid.UUID]int64, error) { type result struct { CandidateID uuid.UUID VoteCount int64 } var results []result err := r.db.WithContext(ctx). Model(&entities.Vote{}). Select("candidate_id, COUNT(*) as vote_count"). Where("vote_event_id = ?", eventID). Group("candidate_id"). Scan(&results).Error if err != nil { return nil, err } resultMap := make(map[uuid.UUID]int64) for _, r := range results { resultMap[r.CandidateID] = r.VoteCount } return resultMap, nil } func (r *VoteEventRepositoryImpl) GetVotedCount(ctx context.Context, eventID uuid.UUID) (int64, error) { var count int64 err := r.db.WithContext(ctx). Model(&entities.Vote{}). Where("vote_event_id = ?", eventID). Count(&count).Error return count, err } func (r *VoteEventRepositoryImpl) GetTotalActiveUsersCount(ctx context.Context) (int64, error) { var count int64 err := r.db.WithContext(ctx). Model(&entities.User{}). Where("is_active = ?", true). Count(&count).Error return count, err }