package com.betriebsratkanzlei.legalconsenthub.security

import com.betriebsratkanzlei.legalconsenthub.user.UserService
import com.betriebsratkanzlei.legalconsenthub_api.model.UserDto
import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.slf4j.LoggerFactory
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
import org.springframework.stereotype.Component
import org.springframework.web.filter.OncePerRequestFilter

@Component
class JwtUserSyncFilter(
    val userService: UserService,
) : OncePerRequestFilter() {
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain,
    ) {
        val logger = LoggerFactory.getLogger(JwtUserSyncFilter::class.java)
        val auth: Authentication? = SecurityContextHolder.getContext().authentication

        println("JwtUserSyncFilter invoked for request: ${request.requestURI}")
        try {
            if (auth is JwtAuthenticationToken && auth.isAuthenticated) {
                val jwt: Jwt = auth.token
                val keycloakId = jwt.subject
                val name = jwt.getClaimAsString("name")

                // Extract organization information from JWT
                val organizationClaim = jwt.getClaimAsMap("organization")
                val organizationId =
                    organizationClaim?.values?.firstOrNull()?.let { orgData ->
                        if (orgData is Map<*, *>) {
                            orgData["id"] as? String
                        } else {
                            null
                        }
                    }

                val user = UserDto(keycloakId, name, organizationId)

                if (keycloakId != null) {
                    userService.createUpdateUserFromJwt(user)
                }
            }
        } catch (ex: Exception) {
            logger.warn("Failed to sync user from JWT: {}", ex.message, ex)
        }

        filterChain.doFilter(request, response)
    }
}
