package admin

// Permission représente une permission granulaire.
type Permission string

// Permissions disponibles.
const (
	PermSchemaRead   Permission = "schema:read"
	PermSchemaWrite  Permission = "schema:write"
	PermSchemaUpload Permission = "schema:upload"

	PermQueriesRead  Permission = "queries:read"
	PermQueriesWrite Permission = "queries:write"

	PermEmailsRead  Permission = "emails:read"
	PermEmailsWrite Permission = "emails:write"

	PermCronRead    Permission = "cron:read"
	PermCronTrigger Permission = "cron:trigger"
	PermCronWrite   Permission = "cron:write"

	PermLogsRead Permission = "logs:read"

	PermDBIntrospect Permission = "db:introspect"

	PermAll Permission = "*"
)

// PermissionChecker vérifie les droits d'un utilisateur.
type PermissionChecker struct {
	config *AdminConfig
}

// NewPermissionChecker crée un nouveau vérificateur de permissions.
func NewPermissionChecker(config *AdminConfig) *PermissionChecker {
	return &PermissionChecker{config: config}
}

// HasPermission vérifie si l'utilisateur a une permission pour une app.
func (pc *PermissionChecker) HasPermission(user *AdminUser, appID string, perm Permission) bool {
	if user == nil {
		return false
	}

	// Super admin a toutes les permissions
	if user.IsSuperAdmin() {
		return true
	}

	// Vérifier l'accès à l'app
	if !pc.CanAccessApp(user, appID) {
		return false
	}

	// Vérifier la permission
	for _, p := range user.Permissions {
		if Permission(p) == PermAll || Permission(p) == perm {
			return true
		}
	}

	return false
}

// CanAccessApp vérifie si l'utilisateur peut accéder à une app.
func (pc *PermissionChecker) CanAccessApp(user *AdminUser, appID string) bool {
	if user == nil {
		return false
	}

	// Super admin a accès à tout
	if user.IsSuperAdmin() {
		return true
	}

	// App admin : vérifier la liste des apps autorisées
	for _, app := range user.Apps {
		if app == appID {
			return true
		}
	}

	return false
}

// GetAccessibleApps retourne les apps accessibles par l'utilisateur.
func (pc *PermissionChecker) GetAccessibleApps(user *AdminUser, allApps []string) []string {
	if user == nil {
		return nil
	}

	// Super admin voit tout
	if user.IsSuperAdmin() {
		return allApps
	}

	// App admin : filtrer sur ses apps autorisées
	var accessible []string
	for _, app := range allApps {
		if pc.CanAccessApp(user, app) {
			accessible = append(accessible, app)
		}
	}
	return accessible
}

// GetUserPermissions retourne les permissions effectives d'un utilisateur.
func (pc *PermissionChecker) GetUserPermissions(user *AdminUser) []Permission {
	if user == nil {
		return nil
	}

	// Super admin a toutes les permissions
	if user.IsSuperAdmin() {
		return []Permission{
			PermSchemaRead, PermSchemaWrite, PermSchemaUpload,
			PermQueriesRead, PermQueriesWrite,
			PermEmailsRead, PermEmailsWrite,
			PermCronRead, PermCronTrigger, PermCronWrite,
			PermLogsRead,
			PermDBIntrospect,
		}
	}

	// Convertir les permissions string en Permission
	perms := make([]Permission, 0, len(user.Permissions))
	for _, p := range user.Permissions {
		perms = append(perms, Permission(p))
	}
	return perms
}
