package repositories

import (
	"context"
	"veza-backend-api/internal/models"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// RoomRepository gère les opérations de base de données pour les rooms
type RoomRepository struct {
	db *gorm.DB
}

// NewRoomRepository crée une nouvelle instance de RoomRepository
func NewRoomRepository(db *gorm.DB) *RoomRepository {
	return &RoomRepository{db: db}
}

// Create crée une nouvelle room
func (r *RoomRepository) Create(ctx context.Context, room *models.Room) error {
	return r.db.WithContext(ctx).Create(room).Error
}

// GetByID récupère une room par son ID
func (r *RoomRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Room, error) {
	var room models.Room
	err := r.db.WithContext(ctx).
		Preload("Members").
		Preload("Messages").
		First(&room, "id = ?", id).Error // Use explicit WHERE clause for UUID
	if err != nil {
		return nil, err
	}
	return &room, nil
}

// GetByUserID récupère toutes les rooms d'un utilisateur
// MIGRATION UUID: userID migré vers uuid.UUID
func (r *RoomRepository) GetByUserID(ctx context.Context, userID uuid.UUID) ([]*models.Room, error) {
	var rooms []*models.Room
	// Note: RoomMember model doesn't have DeletedAt field, so we don't check for deleted_at
	// Also, Preload("Members") would try to add deleted_at IS NULL which doesn't exist for RoomMember
	// So we load members separately or use Unscoped() to avoid the deleted_at check
	err := r.db.WithContext(ctx).
		Joins("JOIN room_members ON rooms.id = room_members.room_id").
		Where("room_members.user_id = ?", userID).
		Preload("Members", func(db *gorm.DB) *gorm.DB {
			// Don't add deleted_at condition since RoomMember doesn't have DeletedAt
			return db
		}).
		Find(&rooms).Error
	if err != nil {
		return nil, err
	}
	return rooms, nil
}

// Update met à jour une room
func (r *RoomRepository) Update(ctx context.Context, room *models.Room) error {
	return r.db.WithContext(ctx).Save(room).Error
}

// Delete supprime une room (soft delete)
func (r *RoomRepository) Delete(ctx context.Context, id uuid.UUID) error {
	return r.db.WithContext(ctx).Delete(&models.Room{}, "id = ?", id).Error // Use explicit WHERE clause for UUID
}

// AddMember ajoute un membre à une room
func (r *RoomRepository) AddMember(ctx context.Context, member *models.RoomMember) error {
	return r.db.WithContext(ctx).Create(member).Error
}

// RemoveMember retire un membre d'une room
// MIGRATION UUID: userID migré vers uuid.UUID
func (r *RoomRepository) RemoveMember(ctx context.Context, roomID uuid.UUID, userID uuid.UUID) error {
	return r.db.WithContext(ctx).
		Where("room_id = ? AND user_id = ?", roomID, userID).
		Delete(&models.RoomMember{}).Error
}

// GetMembersByRoomID récupère tous les membres d'une room
func (r *RoomRepository) GetMembersByRoomID(ctx context.Context, roomID uuid.UUID) ([]*models.RoomMember, error) {
	var members []*models.RoomMember
	err := r.db.WithContext(ctx).
		Where("room_id = ? AND deleted_at IS NULL", roomID).
		Preload("User").
		Find(&members).Error
	if err != nil {
		return nil, err
	}
	return members, nil
}
