import { jwtDecode } from 'jwt-decode'
import type { KeycloakTokenPayload, Organization } from '~~/types/keycloak'

export default defineOAuthKeycloakEventHandler({
  async onSuccess(event, { user, tokens }) {
    const rawAccessToken = tokens?.access_token
    let decodedJwt: KeycloakTokenPayload | null = null

    try {
      decodedJwt = jwtDecode<KeycloakTokenPayload>(rawAccessToken!)
    } catch (err) {
      console.warn('[auth] Failed to decode access token:', err)
    }

    const organizations = decodedJwt ? extractOrganizations(decodedJwt) : []
    const roles = decodedJwt ? extractRoles(decodedJwt) : []

    await setUserSession(event, {
      user: {
        keycloakId: user.sub,
        name: user.preferred_username,
        organizations,
        roles
      },
      jwt: {
        accessToken: tokens.access_token,
        refreshToken: tokens.refresh_token,
        expiresIn: tokens.expires_in
      },
      loggedInAt: Date.now()
    })

    return sendRedirect(event, '/')
  },

  onError(event) {
    console.log('error during keycloak authentication', event)
    return sendRedirect(event, '/login')
  }
})

function extractOrganizations(decoded: KeycloakTokenPayload): Organization[] {
  const organizations: Organization[] = []
  const orgClaim = decoded?.organization ?? null

  if (orgClaim && typeof orgClaim === 'object') {
    Object.entries(orgClaim).forEach(([name, meta]) => {
      if (!name || !meta?.id) return

      organizations.push({
        name: name,
        id: meta.id
      })
    })
  }

  return organizations
}

function extractRoles(decoded: KeycloakTokenPayload): string[] {
  return decoded?.resource_access?.legalconsenthub?.roles ?? []
}
