package users

import (
	"context"
	"errors"
	"fmt"

	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"

	"github.com/ultisuite/ulti-backend/internal/auth"
	"github.com/ultisuite/ulti-backend/internal/permission"
)

// IsPlatformAdmin reports whether the user row is marked platform_admin.
func IsPlatformAdmin(ctx context.Context, db *pgxpool.Pool, externalID string) (bool, error) {
	if db == nil || externalID == "" {
		return false, nil
	}
	var admin bool
	err := db.QueryRow(ctx, `
		SELECT platform_admin FROM users WHERE external_id = $1
	`, externalID).Scan(&admin)
	if errors.Is(err, pgx.ErrNoRows) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return admin, nil
}

// GrantPlatformAdmin sets platform_admin for the given external_id.
func GrantPlatformAdmin(ctx context.Context, db *pgxpool.Pool, externalID string) error {
	if db == nil {
		return fmt.Errorf("database not configured")
	}
	if externalID == "" {
		return fmt.Errorf("missing external id")
	}
	tag, err := db.Exec(ctx, `
		UPDATE users SET platform_admin = true, updated_at = NOW()
		WHERE external_id = $1
	`, externalID)
	if err != nil {
		return err
	}
	if tag.RowsAffected() == 0 {
		return pgx.ErrNoRows
	}
	return nil
}

// ApplyPlatformAdminGroups adds admin RBAC groups when the user is platform_admin.
func ApplyPlatformAdminGroups(ctx context.Context, db *pgxpool.Pool, claims *auth.Claims) error {
	if claims == nil || db == nil {
		return nil
	}
	admin, err := IsPlatformAdmin(ctx, db, claims.Sub)
	if err != nil {
		return err
	}
	if admin {
		claims.Groups = permission.WithPlatformAdmin(claims.Groups)
	}
	return nil
}

func bootstrapFirstUserAdmin(ctx context.Context, db *pgxpool.Pool, userID string) error {
	var hasAdmin bool
	if err := db.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM users WHERE platform_admin = true)`).Scan(&hasAdmin); err != nil {
		return err
	}
	if hasAdmin {
		return nil
	}
	_, err := db.Exec(ctx, `
		UPDATE users SET platform_admin = true, updated_at = NOW()
		WHERE id = $1
	`, userID)
	return err
}
