#!/bin/bash

# Script d'automatisation de la configuration Keycloak pour UnionFlow
# Usage: ./setup-keycloak.sh

echo ""
echo "========================================================"
echo "🔧 Configuration automatique de Keycloak pour UnionFlow"
echo "========================================================"
echo ""

# Configuration
KEYCLOAK_URL="http://localhost:8180"
ADMIN_USER="admin"
ADMIN_PASS="admin"
REALM_NAME="unionflow"
CLIENT_ID="unionflow-client"

echo "📋 Paramètres:"
echo "   - Keycloak URL: $KEYCLOAK_URL"
echo "   - Admin User: $ADMIN_USER"
echo "   - Realm: $REALM_NAME"
echo "   - Client ID: $CLIENT_ID"
echo ""

# Vérifier que Keycloak est accessible
echo "🔍 Vérification de Keycloak..."
if ! curl -s "$KEYCLOAK_URL" > /dev/null; then
    echo "❌ ERREUR: Keycloak n'est pas accessible sur $KEYCLOAK_URL"
    echo "   Assurez-vous que Keycloak est démarré."
    exit 1
fi
echo "✅ Keycloak est accessible"
echo ""

# Étape 1: Obtenir le token admin
echo "📝 Étape 1/7: Obtention du token admin..."
TOKEN_RESPONSE=$(curl -s -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=$ADMIN_USER" \
  -d "password=$ADMIN_PASS" \
  -d "grant_type=password" \
  -d "client_id=admin-cli")

ADMIN_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)

if [ -z "$ADMIN_TOKEN" ]; then
    echo "❌ ERREUR: Impossible d'obtenir le token admin"
    echo "   Vérifiez les identifiants: $ADMIN_USER / $ADMIN_PASS"
    exit 1
fi
echo "✅ Token admin obtenu"
echo ""

# Étape 2: Créer le realm
echo "📝 Étape 2/7: Création du realm '$REALM_NAME'..."
curl -s -X POST "$KEYCLOAK_URL/admin/realms" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"realm\":\"$REALM_NAME\",\"enabled\":true,\"displayName\":\"UnionFlow\",\"registrationAllowed\":false,\"loginWithEmailAllowed\":true,\"duplicateEmailsAllowed\":false,\"resetPasswordAllowed\":true,\"editUsernameAllowed\":false,\"bruteForceProtected\":true}" > /dev/null 2>&1

if [ $? -ne 0 ]; then
    echo "⚠️  Le realm existe peut-être déjà, continuation..."
else
    echo "✅ Realm créé"
fi
echo ""

# Étape 3: Créer les rôles
echo "📝 Étape 3/7: Création des rôles..."

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"SUPER_ADMIN","description":"Super administrateur système"}' > /dev/null 2>&1
echo "   ✅ Rôle SUPER_ADMIN créé"

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"ADMIN_ORGANISATION","description":"Administrateur d'\''entité"}' > /dev/null 2>&1
echo "   ✅ Rôle ADMIN_ORGANISATION créé"

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"MEMBRE","description":"Membre standard"}' > /dev/null 2>&1
echo "   ✅ Rôle MEMBRE créé"

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"GESTIONNAIRE_MEMBRE","description":"Gestionnaire des membres"}' > /dev/null 2>&1
echo "   ✅ Rôle GESTIONNAIRE_MEMBRE créé"

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"GESTIONNAIRE_EVENEMENT","description":"Gestionnaire des événements"}' > /dev/null 2>&1
echo "   ✅ Rôle GESTIONNAIRE_EVENEMENT créé"

echo ""

# Étape 4: Créer le client
echo "📝 Étape 4/7: Création du client '$CLIENT_ID'..."
curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"clientId\":\"$CLIENT_ID\",\"enabled\":true,\"protocol\":\"openid-connect\",\"publicClient\":false,\"directAccessGrantsEnabled\":true,\"standardFlowEnabled\":true,\"implicitFlowEnabled\":false,\"serviceAccountsEnabled\":false,\"authorizationServicesEnabled\":false,\"rootUrl\":\"http://localhost:8086\",\"baseUrl\":\"http://localhost:8086\",\"redirectUris\":[\"http://localhost:8086/*\"],\"webOrigins\":[\"http://localhost:8086\"],\"attributes\":{\"post.logout.redirect.uris\":\"http://localhost:8086/*\"}}" > /dev/null 2>&1

if [ $? -ne 0 ]; then
    echo "⚠️  Le client existe peut-être déjà, continuation..."
else
    echo "✅ Client créé"
fi
echo ""

# Étape 5: Récupérer le client ID (UUID) et le secret
echo "📝 Étape 5/7: Récupération du client secret..."

CLIENTS=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \
  -H "Authorization: Bearer $ADMIN_TOKEN")

CLIENT_UUID=$(echo "$CLIENTS" | grep -o "\"id\":\"[^\"]*\"" | grep -B5 "\"clientId\":\"$CLIENT_ID\"" | head -1 | cut -d'"' -f4)

if [ -z "$CLIENT_UUID" ]; then
    # Méthode alternative avec jq si disponible
    if command -v jq &> /dev/null; then
        CLIENT_UUID=$(echo "$CLIENTS" | jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
    fi
fi

if [ -z "$CLIENT_UUID" ]; then
    echo "❌ ERREUR: Impossible de trouver le client UUID"
    echo "   Installez 'jq' pour un meilleur parsing JSON ou configurez manuellement"
    exit 1
fi

# Récupérer le secret du client
SECRET_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/client-secret" \
  -H "Authorization: Bearer $ADMIN_TOKEN")

CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | grep -o '"value":"[^"]*' | cut -d'"' -f4)

if [ -z "$CLIENT_SECRET" ] && command -v jq &> /dev/null; then
    CLIENT_SECRET=$(echo "$SECRET_RESPONSE" | jq -r '.value')
fi

if [ -z "$CLIENT_SECRET" ]; then
    echo "❌ ERREUR: Impossible de récupérer le client secret"
    exit 1
fi

echo "✅ Client Secret récupéré: $CLIENT_SECRET"
echo ""

# Étape 6: Ajouter l'audience mapper pour unionflow-server
echo "📝 Étape 6/8: Ajout de l'audience mapper 'unionflow-server'..."
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
  "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/protocol-mappers/models" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "unionflow-server-audience",
    "protocol": "openid-connect",
    "protocolMapper": "oidc-audience-mapper",
    "consentRequired": false,
    "config": {
      "included.client.audience": "unionflow-server",
      "id.token.claim": "false",
      "access.token.claim": "true"
    }
  }')
if [ "$HTTP_STATUS" = "201" ]; then
    echo "✅ Audience mapper 'unionflow-server' ajouté"
elif [ "$HTTP_STATUS" = "409" ]; then
    echo "⚠️  Audience mapper 'unionflow-server-audience' existe déjà"
else
    echo "⚠️  Échec ajout audience mapper (HTTP ${HTTP_STATUS}) — à configurer manuellement"
fi
echo ""

# Étape 7: Configurer le client scope mapper pour les rôles
echo "📝 Étape 7/8: Configuration du mapper de rôles..."

SCOPES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients/$CLIENT_UUID/default-client-scopes" \
  -H "Authorization: Bearer $ADMIN_TOKEN")

SCOPE_ID=$(echo "$SCOPES" | grep -o '"id":"[^"]*"' | grep -A5 "dedicated" | head -1 | cut -d'"' -f4)

if [ -z "$SCOPE_ID" ] && command -v jq &> /dev/null; then
    SCOPE_ID=$(echo "$SCOPES" | jq -r '.[] | select(.name | contains("dedicated")) | .id')
fi

if [ -n "$SCOPE_ID" ]; then
    curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/client-scopes/$SCOPE_ID/protocol-mappers/models" \
      -H "Authorization: Bearer $ADMIN_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name":"realm-roles","protocol":"openid-connect","protocolMapper":"oidc-usermodel-realm-role-mapper","config":{"multivalued":"true","userinfo.token.claim":"true","id.token.claim":"true","access.token.claim":"true","claim.name":"roles","jsonType.label":"String"}}' > /dev/null 2>&1
    echo "✅ Mapper de rôles configuré"
else
    echo "⚠️  Impossible de trouver le client scope dédié, le mapper devra être configuré manuellement"
fi
echo ""

# Étape 8: Créer un utilisateur test
echo "📝 Étape 8/8: Création de l'utilisateur test..."

curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username":"test@unionflow.dev","email":"test@unionflow.dev","firstName":"Test","lastName":"User","enabled":true,"emailVerified":true}' > /dev/null 2>&1

if [ $? -ne 0 ]; then
    echo "⚠️  L'utilisateur existe peut-être déjà, continuation..."
else
    echo "✅ Utilisateur créé"
fi

# Récupérer l'ID de l'utilisateur
USER_RESPONSE=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users?username=test@unionflow.dev" \
  -H "Authorization: Bearer $ADMIN_TOKEN")

USER_ID=$(echo "$USER_RESPONSE" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)

if [ -z "$USER_ID" ] && command -v jq &> /dev/null; then
    USER_ID=$(echo "$USER_RESPONSE" | jq -r '.[0].id')
fi

if [ -n "$USER_ID" ]; then
    # Définir le mot de passe
    curl -s -X PUT "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/reset-password" \
      -H "Authorization: Bearer $ADMIN_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"type":"password","value":"test123","temporary":false}' > /dev/null 2>&1
    echo "   ✅ Mot de passe défini (test123)"

    # Récupérer les rôles
    ROLES=$(curl -s -X GET "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
      -H "Authorization: Bearer $ADMIN_TOKEN")

    ROLE_MEMBRE_ID=$(echo "$ROLES" | grep -B2 '"name":"MEMBRE"' | grep '"id"' | cut -d'"' -f4)
    ROLE_ADMIN_ID=$(echo "$ROLES" | grep -B2 '"name":"ADMIN_ORGANISATION"' | grep '"id"' | cut -d'"' -f4)

    if command -v jq &> /dev/null; then
        ROLE_MEMBRE_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="MEMBRE") | .id')
        ROLE_ADMIN_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="ADMIN_ORGANISATION") | .id')
    fi

    if [ -n "$ROLE_MEMBRE_ID" ]; then
        curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
          -H "Authorization: Bearer $ADMIN_TOKEN" \
          -H "Content-Type: application/json" \
          -d "[{\"id\":\"$ROLE_MEMBRE_ID\",\"name\":\"MEMBRE\"}]" > /dev/null 2>&1
        echo "   ✅ Rôle MEMBRE assigné"
    fi

    if [ -n "$ROLE_ADMIN_ID" ]; then
        curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
          -H "Authorization: Bearer $ADMIN_TOKEN" \
          -H "Content-Type: application/json" \
          -d "[{\"id\":\"$ROLE_ADMIN_ID\",\"name\":\"ADMIN_ORGANISATION\"}]" > /dev/null 2>&1
        echo "   ✅ Rôle ADMIN_ORGANISATION assigné"
    fi
else
    echo "⚠️  Impossible de configurer l'utilisateur"
fi

echo ""

# Sauvegarder le client secret dans .env
echo ""
echo "💾 Sauvegarde de la configuration..."
cat > .env << EOF
# Configuration Keycloak générée automatiquement
# Date: $(date)

KEYCLOAK_CLIENT_SECRET=$CLIENT_SECRET
UNIONFLOW_BACKEND_URL=http://localhost:8085

# Informations de connexion pour tests
# Username: test@unionflow.dev
# Password: test123
EOF

echo "✅ Fichier .env créé avec le client secret"
echo ""

# Résumé
echo "========================================================"
echo "✅ Configuration Keycloak terminée avec succès!"
echo "========================================================"
echo ""
echo "📋 Résumé:"
echo "   - Realm: $REALM_NAME"
echo "   - Client ID: $CLIENT_ID"
echo "   - Client Secret: $CLIENT_SECRET"
echo "   - Utilisateur test: test@unionflow.dev"
echo "   - Mot de passe: test123"
echo "   - Rôles assignés: MEMBRE, ADMIN_ORGANISATION"
echo ""
echo "📄 Le client secret a été sauvegardé dans le fichier .env"
echo ""
echo "🚀 Prochaines étapes:"
echo "   1. Vérifiez le fichier .env"
echo "   2. Lancez l'application avec: ./start-local.sh"
echo "   3. Accédez à http://localhost:8086"
echo "   4. Connectez-vous avec test@unionflow.dev / test123"
echo ""
echo "========================================================"
echo ""
