package com.betriebsratkanzlei.legalconsenthub.security

import org.springframework.core.convert.converter.Converter
import org.springframework.security.authentication.AbstractAuthenticationToken
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.stereotype.Component

@Component
class CustomJwtAuthenticationConverter : Converter<Jwt, AbstractAuthenticationToken> {
    override fun convert(jwt: Jwt): AbstractAuthenticationToken {
        val userId = jwt.subject
        val username = jwt.getClaimAsString("name")

        val resourceAccess = jwt.getClaimAsMap("resource_access") as? Map<*, *>
        val legalconsenthubResource = resourceAccess?.get("legalconsenthub") as? Map<*, *>
        val roles = (legalconsenthubResource?.get("roles") as? List<*>)?.mapNotNull { it as? String } ?: emptyList()

        val organizationIds = extractOrganizationIds(jwt)

        val authorities: Collection<GrantedAuthority> =
            roles.map { role ->
                SimpleGrantedAuthority("ROLE_$role")
            }

        val principal = CustomJwtTokenPrincipal(userId, username, roles, organizationIds)

        return CustomJwtAuthentication(jwt, principal, authorities)
    }

    private fun extractOrganizationIds(jwt: Jwt): List<String> {
        val organizationClaim = jwt.getClaimAsMap("organization") ?: return emptyList()

        return organizationClaim.values.mapNotNull { meta ->
            (meta as? Map<*, *>)?.get("id") as? String
        }
    }
}
