# Configuration Keycloak pour UnionFlow
# Crée les rôles et les comptes de test pour MUKEFI et MESKA

$ErrorActionPreference = "Stop"

# Configuration
$KEYCLOAK_URL = "http://localhost:8180"
$REALM_NAME = "unionflow"
$ADMIN_USERNAME = "admin"
$ADMIN_PASSWORD = "admin"
$TEST_PASSWORD = "Test@123"

function Write-Header {
    param([string]$Text)
    Write-Host ""
    Write-Host "=" -NoNewline -ForegroundColor Cyan
    Write-Host (" " * 68) -NoNewline
    Write-Host "=" -ForegroundColor Cyan
    Write-Host $Text -ForegroundColor White
    Write-Host "=" -NoNewline -ForegroundColor Cyan
    Write-Host (" " * 68) -NoNewline
    Write-Host "=" -ForegroundColor Cyan
}

function Get-KeycloakAdminToken {
    Write-Host "`n📡 Connexion à Keycloak..." -ForegroundColor Yellow

    $tokenUrl = "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token"
    $body = @{
        client_id = "admin-cli"
        username = $ADMIN_USERNAME
        password = $ADMIN_PASSWORD
        grant_type = "password"
    }

    try {
        $response = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $body -ContentType "application/x-www-form-urlencoded"
        Write-Host "✅ Connecté à Keycloak Admin API" -ForegroundColor Green
        return $response.access_token
    }
    catch {
        Write-Host "❌ Erreur connexion Keycloak: $_" -ForegroundColor Red
        Write-Host "   Vérifiez que Keycloak est démarré sur $KEYCLOAK_URL" -ForegroundColor Yellow
        return $null
    }
}

function Get-Headers {
    param([string]$Token)
    return @{
        "Authorization" = "Bearer $Token"
        "Content-Type" = "application/json"
    }
}

function Get-RealmUsers {
    param([string]$Token)
    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users"
    try {
        return Invoke-RestMethod -Uri $url -Method Get -Headers $headers
    }
    catch {
        Write-Host "  ⚠️  Erreur récupération utilisateurs: $_" -ForegroundColor Yellow
        return @()
    }
}

function Remove-RealmUser {
    param([string]$Token, [string]$UserId, [string]$Username)
    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$UserId"
    try {
        Invoke-RestMethod -Uri $url -Method Delete -Headers $headers | Out-Null
        Write-Host "  ✅ Supprimé: $Username" -ForegroundColor Green
        return $true
    }
    catch {
        Write-Host "  ❌ Erreur suppression $Username : $_" -ForegroundColor Red
        return $false
    }
}

function Get-RealmRoles {
    param([string]$Token)
    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles"
    try {
        return Invoke-RestMethod -Uri $url -Method Get -Headers $headers
    }
    catch {
        Write-Host "  ⚠️  Erreur récupération rôles: $_" -ForegroundColor Yellow
        return @()
    }
}

function New-RealmRole {
    param([string]$Token, [string]$Name, [string]$Description)
    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles"
    $body = @{
        name = $Name
        description = $Description
        composite = $false
        clientRole = $false
    } | ConvertTo-Json

    try {
        Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body | Out-Null
        Write-Host "  ✅ Rôle créé: $Name" -ForegroundColor Green
        return $true
    }
    catch {
        if ($_.Exception.Response.StatusCode.value__ -eq 409) {
            Write-Host "  ⚠️  Rôle existe déjà: $Name" -ForegroundColor Yellow
            return $true
        }
        Write-Host "  ❌ Erreur création rôle $Name : $_" -ForegroundColor Red
        return $false
    }
}

function New-RealmUser {
    param(
        [string]$Token,
        [string]$Username,
        [string]$Email,
        [string]$FirstName,
        [string]$LastName,
        [string]$Password,
        [string[]]$Roles
    )

    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users"

    $body = @{
        username = $Username
        email = $Email
        firstName = $FirstName
        lastName = $LastName
        enabled = $true
        emailVerified = $true
        credentials = @(
            @{
                type = "password"
                value = $Password
                temporary = $false
            }
        )
    } | ConvertTo-Json -Depth 10

    try {
        $response = Invoke-WebRequest -Uri $url -Method Post -Headers $headers -Body $body

        if ($response.StatusCode -eq 201) {
            # Récupérer l'ID de l'utilisateur
            $location = $response.Headers.Location
            if ($location) {
                $userId = $location.Split('/')[-1]
            }
            else {
                # Chercher l'utilisateur par username
                $users = Get-RealmUsers -Token $Token
                $user = $users | Where-Object { $_.username -eq $Username }
                if ($user) {
                    $userId = $user.id
                }
            }

            if ($userId) {
                # Assigner les rôles
                Add-RolesToUser -Token $Token -UserId $userId -RoleNames $Roles
                Write-Host "  ✅ Utilisateur créé: $Username ($Email)" -ForegroundColor Green
                return $userId
            }
        }
    }
    catch {
        if ($_.Exception.Response.StatusCode.value__ -eq 409) {
            Write-Host "  ⚠️  Utilisateur existe déjà: $Username" -ForegroundColor Yellow
        }
        else {
            Write-Host "  ❌ Erreur création utilisateur $Username : $_" -ForegroundColor Red
        }
        return $null
    }
}

function Add-RolesToUser {
    param([string]$Token, [string]$UserId, [string[]]$RoleNames)

    # Récupérer les objets de rôle
    $allRoles = Get-RealmRoles -Token $Token
    $rolesToAssign = $allRoles | Where-Object { $RoleNames -contains $_.name }

    if ($rolesToAssign.Count -eq 0) {
        return
    }

    $headers = Get-Headers -Token $Token
    $url = "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$UserId/role-mappings/realm"
    $body = $rolesToAssign | ConvertTo-Json -Depth 10 -AsArray

    try {
        Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body | Out-Null
        Write-Host "    → Rôles assignés: $($RoleNames -join ', ')" -ForegroundColor Cyan
    }
    catch {
        Write-Host "    ⚠️  Erreur assignation rôles: $_" -ForegroundColor Yellow
    }
}

# ============================================================================
# MAIN
# ============================================================================

Write-Header "🔧 Configuration Keycloak pour UnionFlow"

# 1. Connexion
$token = Get-KeycloakAdminToken
if (-not $token) {
    Write-Host "`n❌ Impossible de se connecter à Keycloak. Script arrêté." -ForegroundColor Red
    exit 1
}

# 2. Audit de l'existant
Write-Host "`n📋 Audit de l'état actuel..." -ForegroundColor Yellow
$existingUsers = Get-RealmUsers -Token $token
$existingRoles = Get-RealmRoles -Token $token

Write-Host "  • Utilisateurs existants: $($existingUsers.Count)" -ForegroundColor White
foreach ($user in $existingUsers) {
    Write-Host "    - $($user.username) ($($user.email))" -ForegroundColor Gray
}

Write-Host "  • Rôles existants: $($existingRoles.Count)" -ForegroundColor White
foreach ($role in $existingRoles) {
    Write-Host "    - $($role.name)" -ForegroundColor Gray
}

# 3. Suppression des utilisateurs existants
Write-Host "`n🗑️  Suppression des utilisateurs existants..." -ForegroundColor Yellow
foreach ($user in $existingUsers) {
    Remove-RealmUser -Token $token -UserId $user.id -Username $user.username
}

# 4. Création de la structure de rôles
Write-Host "`n👥 Création de la structure de rôles..." -ForegroundColor Yellow

$rolesToCreate = @(
    @{name="SUPER_ADMIN"; description="Super administrateur - Accès total plateforme multi-organisations"},
    @{name="ADMIN_ORGANISATION"; description="Administrateur d'une organisation - Accès total à son organisation"},
    @{name="TRESORIER"; description="Trésorier - Gestion financière, comptabilité, épargne/crédit"},
    @{name="SECRETAIRE"; description="Secrétaire - Gestion administrative, membres, adhésions, documents"},
    @{name="RESPONSABLE_SOCIAL"; description="Responsable social - Gestion aide sociale et solidarité"},
    @{name="RESPONSABLE_EVENEMENTS"; description="Responsable événements - Gestion événements et logistique"},
    @{name="RESPONSABLE_CREDIT"; description="Responsable crédit - Gestion épargne/crédit (mutuelles)"},
    @{name="MEMBRE_BUREAU"; description="Membre du bureau - Accès étendu consultation et actions"},
    @{name="MEMBRE_ACTIF"; description="Membre actif - Consultation et actions de base"},
    @{name="MEMBRE_SIMPLE"; description="Membre simple - Consultation uniquement"},
    @{name="MEMBRE"; description="Rôle technique - Membre base"},
    @{name="ADMIN"; description="Rôle technique - Admin base"},
    @{name="USER"; description="Rôle technique - Utilisateur base"}
)

foreach ($role in $rolesToCreate) {
    New-RealmRole -Token $token -Name $role.name -Description $role.description
}

# 5. Création des comptes de test
Write-Host "`n👤 Création des comptes de test..." -ForegroundColor Yellow
Write-Host "   Mot de passe pour tous: $TEST_PASSWORD`n" -ForegroundColor Cyan

$usersToCreate = @(
    # Super-Admin
    @{username="superadmin"; email="superadmin@unionflow.test"; firstName="Super"; lastName="Admin"; roles=@("SUPER_ADMIN", "ADMIN", "USER")},

    # MUKEFI
    @{username="admin.mukefi"; email="admin.mukefi@unionflow.test"; firstName="Administrateur"; lastName="MUKEFI"; roles=@("ADMIN_ORGANISATION", "ADMIN", "USER")},
    @{username="tresorier.mukefi"; email="tresorier.mukefi@unionflow.test"; firstName="Trésorier"; lastName="MUKEFI"; roles=@("TRESORIER", "MEMBRE", "USER")},
    @{username="secretaire.mukefi"; email="secretaire.mukefi@unionflow.test"; firstName="Secrétaire"; lastName="MUKEFI"; roles=@("SECRETAIRE", "MEMBRE", "USER")},
    @{username="credit.mukefi"; email="credit.mukefi@unionflow.test"; firstName="Responsable Crédit"; lastName="MUKEFI"; roles=@("RESPONSABLE_CREDIT", "MEMBRE", "USER")},
    @{username="membre.mukefi"; email="membre.mukefi@unionflow.test"; firstName="Membre"; lastName="MUKEFI"; roles=@("MEMBRE_ACTIF", "MEMBRE", "USER")},

    # MESKA
    @{username="admin.meska"; email="admin.meska@unionflow.test"; firstName="Administrateur"; lastName="MESKA"; roles=@("ADMIN_ORGANISATION", "ADMIN", "USER")},
    @{username="secretaire.meska"; email="secretaire.meska@unionflow.test"; firstName="Secrétaire"; lastName="MESKA"; roles=@("SECRETAIRE", "MEMBRE", "USER")},
    @{username="social.meska"; email="social.meska@unionflow.test"; firstName="Responsable Social"; lastName="MESKA"; roles=@("RESPONSABLE_SOCIAL", "MEMBRE", "USER")},
    @{username="evenements.meska"; email="evenements.meska@unionflow.test"; firstName="Responsable Événements"; lastName="MESKA"; roles=@("RESPONSABLE_EVENEMENTS", "MEMBRE", "USER")},
    @{username="membre.meska"; email="membre.meska@unionflow.test"; firstName="Membre"; lastName="MESKA"; roles=@("MEMBRE_ACTIF", "MEMBRE", "USER")}
)

foreach ($user in $usersToCreate) {
    New-RealmUser -Token $token -Username $user.username -Email $user.email `
                  -FirstName $user.firstName -lastName $user.lastName `
                  -Password $TEST_PASSWORD -Roles $user.roles
}

# 6. Résumé final
Write-Header "✅ Configuration Keycloak terminée avec succès !"

Write-Host "`n📊 Résumé:" -ForegroundColor Yellow
Write-Host "  • $($rolesToCreate.Count) rôles créés" -ForegroundColor White
Write-Host "  • $($usersToCreate.Count) utilisateurs créés" -ForegroundColor White
Write-Host "  • Mot de passe: $TEST_PASSWORD" -ForegroundColor Cyan

Write-Host "`n👥 Comptes créés:" -ForegroundColor Yellow
Write-Host "`n  🔧 Super-Admin:" -ForegroundColor Magenta
Write-Host "    → superadmin@unionflow.test" -ForegroundColor White

Write-Host "`n  🏦 MUKEFI (Mutuelle):" -ForegroundColor Magenta
Write-Host "    → admin.mukefi@unionflow.test (Admin)" -ForegroundColor White
Write-Host "    → tresorier.mukefi@unionflow.test (Trésorier)" -ForegroundColor White
Write-Host "    → secretaire.mukefi@unionflow.test (Secrétaire)" -ForegroundColor White
Write-Host "    → credit.mukefi@unionflow.test (Responsable Crédit)" -ForegroundColor White
Write-Host "    → membre.mukefi@unionflow.test (Membre Actif)" -ForegroundColor White

Write-Host "`n  🤝 MESKA (Association):" -ForegroundColor Magenta
Write-Host "    → admin.meska@unionflow.test (Admin)" -ForegroundColor White
Write-Host "    → secretaire.meska@unionflow.test (Secrétaire)" -ForegroundColor White
Write-Host "    → social.meska@unionflow.test (Responsable Social)" -ForegroundColor White
Write-Host "    → evenements.meska@unionflow.test (Responsable Événements)" -ForegroundColor White
Write-Host "    → membre.meska@unionflow.test (Membre Actif)" -ForegroundColor White

Write-Host "`n🌐 Accès Keycloak:" -ForegroundColor Yellow
Write-Host "  • Console Admin: $KEYCLOAK_URL/admin" -ForegroundColor Cyan
Write-Host "  • Realm: $REALM_NAME" -ForegroundColor Cyan
Write-Host ""
