package com.betriebsratkanzlei.legalconsenthub.user

import com.betriebsratkanzlei.legalconsenthub.error.UserAlreadyExistsException
import com.betriebsratkanzlei.legalconsenthub.error.UserNotFoundException
import com.betriebsratkanzlei.legalconsenthub.security.CustomJwtTokenPrincipal
import com.betriebsratkanzlei.legalconsenthub_api.model.UserDto
import jakarta.transaction.Transactional
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Service

@Service
class UserService(
    private val userRepository: UserRepository,
    private val userMapper: UserMapper,
) {
    fun getCurrentUser(): User {
        val principal = SecurityContextHolder.getContext().authentication.principal as CustomJwtTokenPrincipal
        val userId = principal.id ?: throw IllegalStateException("User ID not found")

        return userRepository
            .findById(userId)
            .orElseThrow { UserNotFoundException(userId) }
    }

    @Transactional
    fun createUpdateUserFromJwt(userDto: UserDto): User {
        val existingUser = userRepository.findById(userDto.keycloakId)

        if (existingUser.isEmpty) {
            return createUser(userDto)
        } else {
            val user = existingUser.get()
            if (user.organizationId == null && userDto.organizationId != null) {
                user.organizationId = userDto.organizationId
            }
            return updateUser(userMapper.toUserDto(user))
        }
    }

    fun createUser(userDto: UserDto): User {
        if (userRepository.existsById(userDto.keycloakId)) {
            throw UserAlreadyExistsException(userDto.keycloakId)
        }

        val user =
            User(
                keycloakId = userDto.keycloakId,
                name = userDto.name,
                organizationId = userDto.organizationId,
            )

        return userRepository.save(user)
    }

    fun getUserById(userId: String): User =
        userRepository
            .findById(userId)
            .orElseThrow { UserNotFoundException(userId) }

    @Transactional
    fun updateUser(userDto: UserDto): User {
        val user =
            userRepository
                .findById(userDto.keycloakId)
                .orElseThrow { UserNotFoundException(userDto.keycloakId) }

        user.name = userDto.name
        // Only update organization if it's not already set
        if (user.organizationId == null && userDto.organizationId != null) {
            user.organizationId = userDto.organizationId
        }

        return userRepository.save(user)
    }

    fun deleteUser(userId: String) {
        userRepository.deleteById(userId)
    }
}
