// repository/event_repository.go
package repository

import (
	"api_bb/internal/models"
	"fmt"
	"time"

	"gorm.io/gorm"
)

type EventRepository interface {
	Create(event *models.Event) error
	FindByID(id uint) (*models.Event, error)
	FindAll() ([]models.Event, error)
	Update(event *models.Event) error
	Delete(id uint) error
	FindByType(eventType models.EventType) ([]models.Event, error)
	FindUpcoming() ([]models.Event, error)
	FindByDateRange(startDate, endDate time.Time) ([]models.Event, error)
	UpdateParticipantsCount(eventID uint, count int) error
	UpdateRegistrationStatus(eventID uint, registrationOpen bool) error
}

type eventRepository struct {
	db *gorm.DB
}

func NewEventRepository(db *gorm.DB) EventRepository {
	return &eventRepository{db: db}
}

func (r *eventRepository) Create(event *models.Event) error {
	return r.db.Create(event).Error
}

func (r *eventRepository) FindByID(id uint) (*models.Event, error) {
	var event models.Event
	err := r.db.Preload("Registrations").First(&event, id).Error
	return &event, err
}

func (r *eventRepository) FindAll() ([]models.Event, error) {
	var events []models.Event
	err := r.db.Order("date DESC").Find(&events).Error
	return events, err
}

func (r *eventRepository) Update(event *models.Event) error {
	return r.db.Save(event).Error
}

func (r *eventRepository) Delete(id uint) error {
	return r.db.Delete(&models.Event{}, id).Error
}

func (r *eventRepository) FindByType(eventType models.EventType) ([]models.Event, error) {
	var events []models.Event
	err := r.db.Where("type = ?", eventType).Order("date DESC").Find(&events).Error
	return events, err
}

func (r *eventRepository) FindUpcoming() ([]models.Event, error) {
	var events []models.Event
	err := r.db.Where("date >= ?", time.Now()).Order("date ASC").Find(&events).Error
	return events, err
}

func (r *eventRepository) FindByDateRange(startDate, endDate time.Time) ([]models.Event, error) {
	var events []models.Event
	err := r.db.Where("date BETWEEN ? AND ?", startDate, endDate).Order("date ASC").Find(&events).Error
	return events, err
}

func (r *eventRepository) UpdateParticipantsCount(eventID uint, count int) error {
	result := r.db.Model(&models.Event{}).Where("id = ?", eventID).Update("participants_count", count)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("event not found")
	}
	return nil
}

func (r *eventRepository) UpdateRegistrationStatus(eventID uint, registrationOpen bool) error {
	result := r.db.Model(&models.Event{}).Where("id = ?", eventID).Update("registration_open", registrationOpen)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("event not found")
	}
	return nil
}