package model

import (
	"time"

	"gorm.io/gorm"

	"github.com/pingcap-inc/clinic/pkg/db"
)

func InsertRole(roleName string, orgID uint, description string, callback func(roleID uint) error) error {
	role := &db.Role{
		Model: gorm.Model{
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		},
		RoleName:       roleName,
		OrganizationID: orgID,
		Description:    description,
	}

	return db.Transaction(func(txn *gorm.DB) error {
		if err := txn.Create(role).Error; err != nil {
			return err
		}

		return callback(role.ID)
	})
}

func GetRoleByName(name string, orgID uint) (*db.Role, error) {
	var role db.Role
	err := db.Transaction(func(txn *gorm.DB) error {
		err := txn.Where("role_name=? and organization_id=?", name, orgID).First(&role).Error
		if err != nil && err != gorm.ErrRecordNotFound {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, err
	}

	return &role, nil
}

func GetRolesByIDs(ids []uint, orgID uint) ([]db.Role, error) {
	roles := []db.Role{}
	err := db.Transaction(func(tx *gorm.DB) error {
		err := tx.Where("id IN (?) and organization_id = ?", ids, orgID).Find(&roles).Error
		if err != nil && err != gorm.ErrRecordNotFound {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return roles, nil
}

func DeleteRoleByOrg(orgID uint) error {
	err := db.Transaction(func(tx *gorm.DB) error {
		return tx.Where("organization_id = ?", orgID).Unscoped().Delete(&db.Role{}).Error
	})
	return err
}

func ListRoles(orgID uint) ([]db.Role, error) {
	var (
		err   error
		roles []db.Role
	)

	err = db.Transaction(func(tx *gorm.DB) error {
		return db.NewRoleQuerySet(tx).OrganizationIDEq(orgID).All(&roles)
	})

	return roles, err
}
