import type { 
  KeycloakAdminConfig, 
  KeycloakUserRepresentation, 
  KeycloakRoleRepresentation,
  KeycloakGroupRepresentation,
  UserSessionRepresentation,
  EmailWorkflowData,
  MembershipProfileData
} from '~/utils/types';

export class KeycloakAdminClient {
  private config: KeycloakAdminConfig;

  constructor(config: KeycloakAdminConfig) {
    this.config = config;
  }

  /**
   * Get an admin access token using client credentials grant
   */
  async getAdminToken(): Promise<string> {
    const response = await fetch(`${this.config.issuer}/protocol/openid-connect/token`, {
      method: 'POST',
      headers: { 
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: new URLSearchParams({
        grant_type: 'client_credentials',
        client_id: this.config.clientId,
        client_secret: this.config.clientSecret
      })
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get admin token: ${response.status} - ${errorText}`);
    }

    const tokenData = await response.json();
    return tokenData.access_token;
  }

  /**
   * Find a user by email address
   */
  async findUserByEmail(email: string, adminToken?: string): Promise<any[]> {
    const token = adminToken || await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users?email=${encodeURIComponent(email)}&exact=true`, {
      headers: { 
        'Authorization': `Bearer ${token}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to search users: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  /**
   * Create a new user with temporary password and email verification
   */
  async createUserWithRegistration(userData: {
    email: string;
    firstName: string;
    lastName: string;
    username?: string;
  }): Promise<string> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    // Check if user already exists
    const existingUsers = await this.findUserByEmail(userData.email, adminToken);
    if (existingUsers.length > 0) {
      throw new Error('User with this email already exists');
    }

    const response = await fetch(`${adminBaseUrl}/users`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify({
        email: userData.email,
        username: userData.username || userData.email,
        firstName: userData.firstName,
        lastName: userData.lastName,
        enabled: true,
        emailVerified: false,
        groups: ['/users'], // Default to 'user' tier group
        attributes: {
          tier: ['user']
        },
        requiredActions: ['VERIFY_EMAIL', 'UPDATE_PASSWORD']
      })
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to create user: ${response.status} - ${errorText}`);
    }

    // Extract user ID from Location header
    const locationHeader = response.headers.get('location');
    if (!locationHeader) {
      throw new Error('User created but failed to get user ID');
    }

    const userId = locationHeader.split('/').pop();
    if (!userId) {
      throw new Error('Failed to extract user ID from response');
    }

    console.log(`[keycloak-admin] Created user ${userData.email} with ID: ${userId}`);
    return userId;
  }

  /**
   * Delete a user by ID
   */
  async deleteUser(userId: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}`, {
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to delete user: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Deleted user with ID: ${userId}`);
  }

  // ============================================================================
  // ROLE MANAGEMENT METHODS
  // ============================================================================

  /**
   * Create a new realm role
   */
  async createRealmRole(roleName: string, description: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/roles`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify({
        name: roleName,
        description: description,
        composite: false,
        clientRole: false
      })
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to create realm role: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Created realm role: ${roleName}`);
  }

  /**
   * Get a realm role by name
   */
  async getRealmRole(roleName: string, adminToken?: string): Promise<KeycloakRoleRepresentation> {
    const token = adminToken || await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/roles/${roleName}`, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get realm role: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  /**
   * Get all realm roles
   */
  async getAllRealmRoles(adminToken?: string): Promise<KeycloakRoleRepresentation[]> {
    const token = adminToken || await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/roles`, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get realm roles: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  /**
   * Assign a realm role to a user (requires proper Keycloak admin permissions)
   */
  async assignRealmRoleToUser(userId: string, roleName: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Assigning realm role ${roleName} to user ${userId}`);
    
    try {
      // First try to get the role to ensure it exists
      const role = await this.getRealmRole(roleName, adminToken);
      
      // Then assign it to user
      const response = await fetch(`${adminBaseUrl}/users/${userId}/role-mappings/realm`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${adminToken}`,
          'Content-Type': 'application/json',
          'User-Agent': 'MonacoUSA-Portal/1.0'
        },
        body: JSON.stringify([role])
      });

      if (!response.ok) {
        const errorText = await response.text().catch(() => 'Unknown error');
        throw new Error(`Failed to assign role to user: ${response.status} - ${errorText}`);
      }

      console.log(`[keycloak-admin] ✅ Successfully assigned role ${roleName} to user ${userId}`);
    } catch (error: any) {
      // Provide detailed error information for troubleshooting
      if (error.message?.includes('403')) {
        console.error(`[keycloak-admin] ❌ Permission denied when assigning role ${roleName} to user ${userId}:`);
        console.error(`[keycloak-admin] The Keycloak service account needs the following permissions:`);
        console.error(`[keycloak-admin] 1. 'view-realm' permission to read realm roles`);
        console.error(`[keycloak-admin] 2. 'manage-users' permission to assign roles to users`);
        console.error(`[keycloak-admin] 3. Access to the '${roleName}' realm role`);
        console.warn(`[keycloak-admin] User ${userId} created successfully but role ${roleName} could not be assigned due to insufficient permissions.`);
        console.warn(`[keycloak-admin] Please assign the role manually in Keycloak admin console.`);
        // Don't throw - allow user creation to complete
        return;
      } else if (error.message?.includes('404')) {
        console.error(`[keycloak-admin] ❌ Role ${roleName} does not exist in Keycloak realm.`);
        console.error(`[keycloak-admin] Please create the '${roleName}' role in Keycloak admin console.`);
        console.warn(`[keycloak-admin] User ${userId} created successfully but role ${roleName} does not exist.`);
        // Don't throw - allow user creation to complete
        return;
      } else {
        console.error(`[keycloak-admin] ❌ Unexpected error assigning role ${roleName} to user ${userId}:`, error);
        console.warn(`[keycloak-admin] User ${userId} created successfully but role assignment failed.`);
        // Don't throw - allow user creation to complete
        return;
      }
    }
  }

  /**
   * Remove a realm role from a user
   */
  async removeRealmRoleFromUser(userId: string, roleName: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    // First get the role
    const role = await this.getRealmRole(roleName, adminToken);
    
    // Then remove it from user
    const response = await fetch(`${adminBaseUrl}/users/${userId}/role-mappings/realm`, {
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify([role])
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to remove role from user: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Removed role ${roleName} from user ${userId}`);
  }

  /**
   * Get user's realm role mappings
   */
  async getUserRealmRoles(userId: string, adminToken?: string): Promise<KeycloakRoleRepresentation[]> {
    const token = adminToken || await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/role-mappings/realm`, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get user roles: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  // ============================================================================
  // USER PROFILE MANAGEMENT METHODS
  // ============================================================================

  /**
   * Get user by ID with full profile information
   */
  async getUserById(userId: string, adminToken?: string): Promise<KeycloakUserRepresentation> {
    const token = adminToken || await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}`, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get user: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  /**
   * Update user profile with membership data synchronization
   */
  async updateUserProfile(userId: string, profileData: {
    firstName?: string;
    lastName?: string;
    email?: string;
    enabled?: boolean;
    emailVerified?: boolean;
    attributes?: {
      membershipStatus?: string;
      duesStatus?: string;
      memberSince?: string;
      nationality?: string;
      phone?: string;
      address?: string;
      registrationDate?: string;
      paymentDueDate?: string;
      lastLoginDate?: string;
      membershipTier?: string;
      nocodbMemberId?: string;
    };
  }): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    // Build user representation
    const userUpdate: any = {};
    if (profileData.firstName !== undefined) userUpdate.firstName = profileData.firstName;
    if (profileData.lastName !== undefined) userUpdate.lastName = profileData.lastName;
    if (profileData.email !== undefined) userUpdate.email = profileData.email;
    if (profileData.enabled !== undefined) userUpdate.enabled = profileData.enabled;
    if (profileData.emailVerified !== undefined) userUpdate.emailVerified = profileData.emailVerified;
    
    // Handle custom attributes
    if (profileData.attributes) {
      userUpdate.attributes = {};
      Object.entries(profileData.attributes).forEach(([key, value]) => {
        if (value !== undefined && value !== null) {
          userUpdate.attributes[key] = [value]; // Keycloak expects arrays for attributes
        }
      });
    }

    const response = await fetch(`${adminBaseUrl}/users/${userId}`, {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify(userUpdate)
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to update user profile: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Updated profile for user ${userId}`);
  }

  /**
   * Create user with group-based registration (replaces role-based method)
   */
  async createUserWithGroupAssignment(userData: {
    email: string;
    firstName: string;
    lastName: string;
    username?: string;
    membershipTier?: 'user' | 'board' | 'admin';
    membershipData?: MembershipProfileData;
  }): Promise<string> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Creating user with group assignment: ${userData.email}, tier: ${userData.membershipTier || 'user'}`);
    
    // Check if user already exists
    const existingUsers = await this.findUserByEmail(userData.email, adminToken);
    if (existingUsers.length > 0) {
      throw new Error('User with this email already exists');
    }

    // Build user attributes
    const attributes: Record<string, string[]> = {
      membershipTier: [userData.membershipTier || 'user'],
      registrationDate: [new Date().toISOString()]
    };

    if (userData.membershipData) {
      Object.entries(userData.membershipData).forEach(([key, value]) => {
        if (value !== undefined && value !== null) {
          attributes[key] = [String(value)];
        }
      });
    }

    const response = await fetch(`${adminBaseUrl}/users`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify({
        email: userData.email,
        username: userData.username || userData.email,
        firstName: userData.firstName,
        lastName: userData.lastName,
        enabled: true,
        emailVerified: false,
        attributes,
        requiredActions: ['VERIFY_EMAIL', 'UPDATE_PASSWORD']
      })
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to create user: ${response.status} - ${errorText}`);
    }

    // Extract user ID from Location header
    const locationHeader = response.headers.get('location');
    if (!locationHeader) {
      throw new Error('User created but failed to get user ID');
    }

    const userId = locationHeader.split('/').pop();
    if (!userId) {
      throw new Error('Failed to extract user ID from response');
    }

    console.log(`[keycloak-admin] Created user ${userData.email} with ID: ${userId}`);

    // Assign appropriate group instead of role
    const groupName = userData.membershipTier || 'user';
    console.log(`[keycloak-admin] Assigning user to group: ${groupName}`);
    
    try {
      const groupId = await this.getGroupByName(groupName);
      await this.assignUserToGroup(userId, groupId);
      console.log(`[keycloak-admin] ✅ Successfully assigned user ${userId} to group: ${groupName}`);
    } catch (error: any) {
      console.warn(`[keycloak-admin] ⚠️ Failed to assign user ${userId} to group ${groupName}:`, error);
      console.warn(`[keycloak-admin] User will receive default group assignment from Keycloak realm settings`);
      // Don't fail the entire operation - user gets default group automatically
    }

    console.log(`[keycloak-admin] ✅ User creation with group assignment completed: ${userData.email}`);
    return userId;
  }

  /**
   * @deprecated Use createUserWithGroupAssignment() instead
   * This method has permission issues with role assignment
   */
  async createUserWithRoleRegistration(userData: {
    email: string;
    firstName: string;
    lastName: string;
    username?: string;
    membershipTier?: 'user' | 'board' | 'admin';
    membershipData?: MembershipProfileData;
  }): Promise<string> {
    console.warn('[keycloak-admin] createUserWithRoleRegistration is deprecated. Use createUserWithGroupAssignment instead.');
    throw new Error('Method deprecated. Use createUserWithGroupAssignment() instead - it resolves permission issues.');
  }

  // ============================================================================
  // SESSION MANAGEMENT METHODS
  // ============================================================================

  /**
   * Get all active sessions for a user
   */
  async getUserSessions(userId: string): Promise<UserSessionRepresentation[]> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/sessions`, {
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get user sessions: ${response.status} - ${errorText}`);
    }

    return response.json();
  }

  /**
   * Logout a specific user session
   */
  async logoutUserSession(sessionId: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/sessions/${sessionId}`, {
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to logout session: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Logged out session: ${sessionId}`);
  }

  /**
   * Logout all sessions for a user
   */
  async logoutAllUserSessions(userId: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/logout`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to logout all user sessions: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Logged out all sessions for user: ${userId}`);
  }

  // ============================================================================
  // GROUP MANAGEMENT METHODS
  // ============================================================================

  /**
   * Create a new group
   */
  async createGroup(name: string, path: string, parentPath?: string): Promise<string> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const groupData = {
      name: name,
      path: path
    };

    let url = `${adminBaseUrl}/groups`;
    if (parentPath) {
      // Find parent group ID first
      const parentId = await this.getGroupByPath(parentPath);
      url = `${adminBaseUrl}/groups/${parentId}/children`;
    }

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify(groupData)
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to create group: ${response.status} - ${errorText}`);
    }

    const locationHeader = response.headers.get('location');
    const groupId = locationHeader?.split('/').pop() || '';
    
    console.log(`[keycloak-admin] Created group: ${name} with ID: ${groupId}`);
    return groupId;
  }

  /**
   * Get group by path
   */
  async getGroupByPath(path: string): Promise<string> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/groups?search=${encodeURIComponent(path)}`, {
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to find group: ${response.status} - ${errorText}`);
    }

    const groups: KeycloakGroupRepresentation[] = await response.json();
    const group = groups.find(g => g.path === path);
    
    if (!group?.id) {
      throw new Error(`Group not found: ${path}`);
    }

    return group.id;
  }

  /**
   * Get group by name (for groups without leading slash)
   */
  async getGroupByName(name: string): Promise<string> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Searching for group by name: ${name}`);
    
    const response = await fetch(`${adminBaseUrl}/groups?search=${encodeURIComponent(name)}`, {
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to find group: ${response.status} - ${errorText}`);
    }

    const groups: KeycloakGroupRepresentation[] = await response.json();
    console.log(`[keycloak-admin] Found ${groups.length} groups matching search "${name}":`, groups.map(g => ({ id: g.id, name: g.name, path: g.path })));
    
    // Try exact name match first
    let group = groups.find(g => g.name === name);
    
    // If no exact name match, try path match with leading slash
    if (!group) {
      group = groups.find(g => g.path === `/${name}`);
    }
    
    // If still no match, try path match without leading slash
    if (!group) {
      group = groups.find(g => g.path === name);
    }
    
    if (!group?.id) {
      console.error(`[keycloak-admin] No group found matching name "${name}". Available groups:`, groups);
      throw new Error(`Group not found: ${name}. Available groups: ${groups.map(g => g.name || g.path).join(', ')}`);
    }

    console.log(`[keycloak-admin] Found group: ${group.name} (path: ${group.path}) with ID: ${group.id}`);
    return group.id;
  }

  /**
   * Assign user to group
   */
  async assignUserToGroup(userId: string, groupId: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/groups/${groupId}`, {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to assign user to group: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Assigned user ${userId} to group ${groupId}`);
  }

  /**
   * Get all groups for a user
   */
  async getUserGroups(userId: string): Promise<KeycloakGroupRepresentation[]> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Getting groups for user: ${userId}`);
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/groups`, {
      headers: { 
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to get user groups: ${response.status} - ${errorText}`);
    }

    const groups = await response.json();
    console.log(`[keycloak-admin] ✅ Retrieved ${groups.length} groups for user ${userId}`);
    return groups;
  }

  /**
   * Get total count of users in the realm
   * This fetches actual user count from Keycloak instead of using mock data
   */
  async getUserCount(includeServiceAccounts: boolean = false): Promise<number> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Getting user count from Keycloak (includeServiceAccounts: ${includeServiceAccounts})`);
    
    try {
      // Fetch users with minimal data (just count)
      // Using max=0 to get count without user details for performance
      const countUrl = new URL(`${adminBaseUrl}/users/count`);
      if (!includeServiceAccounts) {
        countUrl.searchParams.set('excludeServiceAccounts', 'true');
      }
      
      // First try the count endpoint if it exists
      let response = await fetch(countUrl.toString(), {
        headers: { 
          'Authorization': `Bearer ${adminToken}`,
          'User-Agent': 'MonacoUSA-Portal/1.0'
        }
      });

      // If count endpoint doesn't exist, fall back to fetching users
      if (response.status === 404) {
        console.log(`[keycloak-admin] Count endpoint not available, fetching full user list`);
        
        const usersUrl = new URL(`${adminBaseUrl}/users`);
        usersUrl.searchParams.set('max', '10000'); // Set a high limit to get all users
        
        response = await fetch(usersUrl.toString(), {
          headers: { 
            'Authorization': `Bearer ${adminToken}`,
            'User-Agent': 'MonacoUSA-Portal/1.0'
          }
        });

        if (!response.ok) {
          const errorText = await response.text().catch(() => 'Unknown error');
          throw new Error(`Failed to get users: ${response.status} - ${errorText}`);
        }

        const users = await response.json();
        
        // Filter out service accounts if needed
        let userCount = users.length;
        if (!includeServiceAccounts) {
          const regularUsers = users.filter((user: any) => !user.username?.startsWith('service-account-'));
          userCount = regularUsers.length;
        }
        
        console.log(`[keycloak-admin] ✅ Retrieved user count: ${userCount}`);
        return userCount;
      }

      if (!response.ok) {
        const errorText = await response.text().catch(() => 'Unknown error');
        throw new Error(`Failed to get user count: ${response.status} - ${errorText}`);
      }

      const count = await response.json();
      console.log(`[keycloak-admin] ✅ Retrieved user count: ${count}`);
      return typeof count === 'object' ? count.count : count;
      
    } catch (error: any) {
      console.error(`[keycloak-admin] ❌ Error getting user count:`, error);
      throw error;
    }
  }

  /**
   * Remove user from a group
   */
  async removeUserFromGroup(userId: string, groupId: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    console.log(`[keycloak-admin] Removing user ${userId} from group ${groupId}`);
    
    const response = await fetch(`${adminBaseUrl}/users/${userId}/groups/${groupId}`, {
      method: 'DELETE',
      headers: { 
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to remove user from group: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] ✅ Removed user ${userId} from group ${groupId}`);
  }

  /**
   * Change user's primary group (remove from old primary groups, add to new)
   */
  async changeUserPrimaryGroup(userId: string, newGroupName: string): Promise<void> {
    console.log(`[keycloak-admin] Changing user ${userId} primary group to: ${newGroupName}`);
    
    if (!['user', 'board', 'admin'].includes(newGroupName)) {
      throw new Error(`Invalid group name: ${newGroupName}. Must be one of: user, board, admin`);
    }

    try {
      // Get current user groups
      const currentGroups = await this.getUserGroups(userId);
      const primaryGroups = currentGroups.filter(g => ['user', 'board', 'admin'].includes(g.name || ''));
      
      console.log(`[keycloak-admin] User currently in ${primaryGroups.length} primary groups: ${primaryGroups.map(g => g.name).join(', ')}`);
      
      // Remove from old primary groups
      for (const group of primaryGroups) {
        if (group.id && group.name !== newGroupName) {
          console.log(`[keycloak-admin] Removing user from old group: ${group.name}`);
          await this.removeUserFromGroup(userId, group.id);
        }
      }
      
      // Add to new group (if not already in it)
      const alreadyInNewGroup = primaryGroups.some(g => g.name === newGroupName);
      if (!alreadyInNewGroup) {
        console.log(`[keycloak-admin] Adding user to new group: ${newGroupName}`);
        // Try without leading slash first (groups named directly like "board")
        console.log(`[keycloak-admin] Looking up group with name: ${newGroupName}`);
        const newGroupId = await this.getGroupByName(newGroupName);
        await this.assignUserToGroup(userId, newGroupId);
      } else {
        console.log(`[keycloak-admin] User already in target group: ${newGroupName}`);
      }
      
      console.log(`[keycloak-admin] ✅ Successfully changed user ${userId} primary group to: ${newGroupName}`);
    } catch (error: any) {
      console.error(`[keycloak-admin] ❌ Error changing user primary group:`, error);
      throw error;
    }
  }

  // ============================================================================
  // ADVANCED EMAIL WORKFLOWS
  // ============================================================================

  /**
   * Send custom email workflows
   */
  async sendCustomEmail(userId: string, emailData: EmailWorkflowData): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const emailUrl = new URL(`${adminBaseUrl}/users/${userId}/execute-actions-email`);
    
    // Configure email based on type
    switch (emailData.emailType) {
      case 'DUES_REMINDER':
        emailUrl.searchParams.set('lifespan', emailData.lifespan?.toString() || '259200'); // 3 days
        if (emailData.customData?.dueAmount) {
          emailUrl.searchParams.set('dueAmount', emailData.customData.dueAmount);
        }
        break;
      case 'MEMBERSHIP_RENEWAL':
        emailUrl.searchParams.set('lifespan', emailData.lifespan?.toString() || '604800'); // 1 week
        if (emailData.customData?.renewalDate) {
          emailUrl.searchParams.set('renewalDate', emailData.customData.renewalDate);
        }
        break;
      case 'WELCOME':
        emailUrl.searchParams.set('lifespan', emailData.lifespan?.toString() || '43200'); // 12 hours
        break;
      case 'VERIFICATION':
        emailUrl.searchParams.set('lifespan', emailData.lifespan?.toString() || '86400'); // 24 hours
        break;
    }

    if (emailData.redirectUri) {
      emailUrl.searchParams.set('redirect_uri', emailData.redirectUri);
    }

    emailUrl.searchParams.set('client_id', this.config.clientId);

    const response = await fetch(emailUrl.toString(), {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'Content-Type': 'application/json',
        'User-Agent': 'MonacoUSA-Portal/1.0'
      },
      body: JSON.stringify([emailData.emailType])
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to send ${emailData.emailType} email: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Sent ${emailData.emailType} email to user ${userId}`);
  }

  /**
   * Send enhanced verification email
   */
  async sendVerificationEmail(userId: string, redirectUri?: string): Promise<void> {
    const adminToken = await this.getAdminToken();
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    
    const emailUrl = new URL(`${adminBaseUrl}/users/${userId}/send-verify-email`);
    if (redirectUri) {
      emailUrl.searchParams.set('redirect_uri', redirectUri);
    }
    emailUrl.searchParams.set('client_id', this.config.clientId);
    
    const response = await fetch(emailUrl.toString(), {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${adminToken}`,
        'User-Agent': 'MonacoUSA-Portal/1.0'
      }
    });

    if (!response.ok) {
      const errorText = await response.text().catch(() => 'Unknown error');
      throw new Error(`Failed to send verification email: ${response.status} - ${errorText}`);
    }

    console.log(`[keycloak-admin] Sent verification email to user ${userId}`);
  }

  /**
   * Send password reset email to a user
   */
  async sendPasswordResetEmail(userId: string, adminToken: string, portalClientId: string, callbackUrl: string): Promise<void> {
    const adminBaseUrl = this.config.issuer.replace('/realms/', '/admin/realms/');
    const resetUrl = new URL(`${adminBaseUrl}/users/${userId}/execute-actions-email`);
    
    // Add query parameters for better email template rendering
    resetUrl.searchParams.set('clientId', portalClientId);
    resetUrl.searchParams.set('redirectUri', callbackUrl.replace('/auth/callback', '/login'));
    resetUrl.searchParams.set('lifespan', '43200'); // 12 hours

    // Create AbortController for timeout handling
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout

    try {
      const response = await fetch(resetUrl.toString(), {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${adminToken}`,
          'Content-Type': 'application/json',
          'User-Agent': 'MonacoUSA-Portal/1.0'
        },
        body: JSON.stringify(['UPDATE_PASSWORD']),
        signal: controller.signal
      });

      clearTimeout(timeoutId);

      if (!response.ok) {
        const errorText = await response.text().catch(() => 'Unknown error');
        throw new Error(`Failed to send reset email: ${response.status} - ${errorText}`);
      }
    } catch (error) {
      clearTimeout(timeoutId);
      throw error;
    }
  }
}

export function createKeycloakAdminClient(): KeycloakAdminClient {
  const config = useRuntimeConfig() as any;
  
  if (!config.keycloakAdmin?.clientId || !config.keycloakAdmin?.clientSecret || !config.keycloak?.issuer) {
    throw new Error('Missing Keycloak admin configuration');
  }

  return new KeycloakAdminClient({
    issuer: config.keycloak.issuer,
    clientId: config.keycloakAdmin.clientId,
    clientSecret: config.keycloakAdmin.clientSecret
  });
}

/**
 * Helper function to delete a Keycloak user by ID
 */
export async function deleteKeycloakUser(userId: string): Promise<void> {
  try {
    console.log(`[Keycloak] Attempting to delete user: ${userId}`);
    
    const adminClient = createKeycloakAdminClient();
    await adminClient.deleteUser(userId);
    
    console.log(`[Keycloak] User ${userId} deleted successfully`);
  } catch (error) {
    console.error(`[Keycloak] Failed to delete user ${userId}:`, error);
    throw error;
  }
}
