package repositories

import (
	"GoMembership/internal/database"

	"gorm.io/gorm"

	"GoMembership/internal/models"
)

type SubscriptionModelsRepositoryInterface interface {
	CreateSubscriptionModel(subscriptionModel *models.SubscriptionModel) (uint, error)
	UpdateSubscription(subscription *models.SubscriptionModel) (*models.SubscriptionModel, error)
	GetSubscriptionModelNames() ([]string, error)
	GetSubscriptions(where map[string]interface{}) (*[]models.SubscriptionModel, error)
	// GetUsersBySubscription(id uint) (*[]models.SubscriptionModel, error)
	DeleteSubscription(id *uint) error
}

type SubscriptionModelsRepository struct{}

func (sr *SubscriptionModelsRepository) CreateSubscriptionModel(subscriptionModel *models.SubscriptionModel) (uint, error) {

	result := database.DB.Create(subscriptionModel)
	if result.Error != nil {
		return 0, result.Error
	}
	return subscriptionModel.ID, nil
}

func (sr *SubscriptionModelsRepository) UpdateSubscription(subscription *models.SubscriptionModel) (*models.SubscriptionModel, error) {

	result := database.DB.Model(&models.SubscriptionModel{ID: subscription.ID}).Updates(subscription)
	if result.Error != nil {
		return nil, result.Error
	}
	return subscription, nil
}

func (sr *SubscriptionModelsRepository) DeleteSubscription(id *uint) error {

	result := database.DB.Delete(&models.SubscriptionModel{}, id)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func GetSubscriptionByName(modelname *string) (*models.SubscriptionModel, error) {
	var model models.SubscriptionModel
	result := database.DB.Where("name = ?", modelname).First(&model)
	if result.Error != nil {
		return nil, result.Error
	}
	return &model, nil
}

func (sr *SubscriptionModelsRepository) GetSubscriptionModelNames() ([]string, error) {
	var names []string
	if err := database.DB.Model(&models.SubscriptionModel{}).Pluck("name", &names).Error; err != nil {
		return []string{}, err
	}
	return names, nil
}

func (sr *SubscriptionModelsRepository) GetSubscriptions(where map[string]interface{}) (*[]models.SubscriptionModel, error) {
	var subscriptions []models.SubscriptionModel
	result := database.DB.Where(where).Find(&subscriptions)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			return nil, gorm.ErrRecordNotFound
		}
		return nil, result.Error
	}
	return &subscriptions, nil
}

func GetUsersBySubscription(subscriptionID uint) (*[]models.User, error) {
	var users []models.User

	err := database.DB.Preload("Membership").
		Preload("Membership.SubscriptionModel").
		Preload("BankAccount").
		Preload("Licence").
		Preload("Licence.Categories").
		Joins("JOIN memberships ON users.membership_id = memberships.id").
		Joins("JOIN subscription_models ON memberships.subscription_model_id = subscription_models.id").
		Where("subscription_models.id = ?", subscriptionID).
		Find(&users).Error

	if err != nil {
		return nil, err
	}

	return &users, nil

}
