/**
 * SSO (Single Sign-On) integration for Phoenix Nexus
 * 
 * This module handles SSO flow between the public site and portals
 * using Keycloak as the identity provider.
 */

export interface SSOConfig {
  keycloakUrl: string
  realm: string
  clientId: string
  redirectUri: string
}

export interface UserRole {
  role: 'admin' | 'developer' | 'partner' | 'tenant-admin' | 'user'
  portal: string
}

/**
 * Determine which portal to redirect to based on user role
 */
export function getPortalForRole(role: string): string {
  const roleMap: Record<string, string> = {
    admin: '/portal',
    'tenant-admin': '/portal/admin',
    developer: '/portal/developers',
    partner: '/portal/partners',
    user: '/portal',
  }

  return roleMap[role] || '/portal'
}

/**
 * Initiate SSO flow
 */
export async function initiateSSO(config: SSOConfig): Promise<string> {
  const authUrl = new URL(
    `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect/auth`
  )

  authUrl.searchParams.set('client_id', config.clientId)
  authUrl.searchParams.set('redirect_uri', config.redirectUri)
  authUrl.searchParams.set('response_type', 'code')
  authUrl.searchParams.set('scope', 'openid profile email')
  authUrl.searchParams.set('state', generateState())

  return authUrl.toString()
}

/**
 * Handle SSO callback
 */
export async function handleSSOCallback(
  code: string,
  state: string,
  config: SSOConfig
): Promise<{ token: string; user: any; role: string }> {
  // Exchange code for token
  const tokenUrl = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect/token`
  
  const response = await fetch(tokenUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      redirect_uri: config.redirectUri,
      client_id: config.clientId,
      client_secret: process.env.KEYCLOAK_CLIENT_SECRET || '',
    }),
  })

  if (!response.ok) {
    throw new Error('Failed to exchange code for token')
  }

  const data = await response.json()
  
  // Get user info
  const userInfoUrl = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect/userinfo`
  const userResponse = await fetch(userInfoUrl, {
    headers: {
      Authorization: `Bearer ${data.access_token}`,
    },
  })

  const user = await userResponse.json()
  
  // Extract role from token or user info
  const role = extractRoleFromToken(data.access_token) || user.role || 'user'

  return {
    token: data.access_token,
    user,
    role,
  }
}

/**
 * Generate state parameter for OAuth flow
 */
function generateState(): string {
  return Math.random().toString(36).substring(2, 15) + 
         Math.random().toString(36).substring(2, 15)
}

/**
 * Extract role from JWT token
 */
function extractRoleFromToken(token: string): string | null {
  try {
    const payload = JSON.parse(atob(token.split('.')[1]))
    return payload.realm_access?.roles?.[0] || payload.role || null
  } catch {
    return null
  }
}

/**
 * Check if user is authenticated
 */
export function isAuthenticated(): boolean {
  // Check for token in localStorage or cookies
  if (typeof window === 'undefined') return false
  
  return !!localStorage.getItem('phoenix_token') || 
         !!document.cookie.includes('phoenix_session')
}

/**
 * Sign out user
 */
export function signOut(): void {
  if (typeof window === 'undefined') return
  
  localStorage.removeItem('phoenix_token')
  document.cookie = 'phoenix_session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
  
  window.location.href = '/'
}

