package repository

import (
	"context"

	"gorm.io/gorm"

	"security-center-backend/internal/model"
)

type PermissionRepository interface {
	List(ctx context.Context) ([]model.Permission, error)
	FindByIDs(ctx context.Context, ids []uint64) ([]model.Permission, error)
	Upsert(ctx context.Context, permissions []model.Permission) error
}

type GormPermissionRepository struct {
	db *gorm.DB
}

func NewPermissionRepository(db *gorm.DB) PermissionRepository {
	return &GormPermissionRepository{db: db}
}

func (r *GormPermissionRepository) List(ctx context.Context) ([]model.Permission, error) {
	var permissions []model.Permission
	if err := r.db.WithContext(ctx).Find(&permissions).Error; err != nil {
		return nil, err
	}
	return permissions, nil
}

func (r *GormPermissionRepository) FindByIDs(ctx context.Context, ids []uint64) ([]model.Permission, error) {
	var permissions []model.Permission
	if len(ids) == 0 {
		return permissions, nil
	}
	if err := r.db.WithContext(ctx).Find(&permissions, ids).Error; err != nil {
		return nil, err
	}
	return permissions, nil
}

func (r *GormPermissionRepository) Upsert(ctx context.Context, permissions []model.Permission) error {
	for _, perm := range permissions {
		var existing model.Permission
		err := r.db.WithContext(ctx).Unscoped().Where("name = ?", perm.Name).First(&existing).Error
		switch {
		case err == nil:
			if err := r.db.WithContext(ctx).Unscoped().Model(&existing).Updates(map[string]interface{}{
				"description": perm.Description,
				"metadata":    perm.Metadata,
				"deleted_at":  nil,
			}).Error; err != nil {
				return err
			}
		case err != nil && err == gorm.ErrRecordNotFound:
			if err := r.db.WithContext(ctx).Create(&perm).Error; err != nil {
				return err
			}
		case err != nil:
			return err
		}
	}
	return nil
}
