package llc.arma.fleet.monitor.domain.service

import llc.arma.fleet.monitor.data.entity.UserEntity
import llc.arma.fleet.monitor.data.repository.UserRepository
import llc.arma.fleet.monitor.presentation.model.AuthPayload
import llc.arma.fleet.monitor.presentation.model.LoginPayload
import llc.arma.fleet.monitor.presentation.model.RefreshSessionPayload
import llc.arma.fleet.monitor.security.AuthTokenStore
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service

@Service
class AuthService(
    private val userRepository: UserRepository,
    private val passwordEncoder: PasswordEncoder,
    private val tokenStore: AuthTokenStore,
) {
    fun login(payload: LoginPayload): AuthPayload {
        val user = userRepository.findByLoginOrEmail(payload.loginOrEmail, payload.loginOrEmail)
            ?: throw IllegalArgumentException("Пользователь не найден")

        if (!user.active) {
            throw IllegalArgumentException("Пользователь заблокирован")
        }

        if (!passwordEncoder.matches(payload.password, user.passwordHash)) {
            throw IllegalArgumentException("Неверный пароль")
        }

        return createAuthPayload(user)
    }

    fun refreshSession(payload: RefreshSessionPayload): AuthPayload {
        val session = tokenStore.refreshSession(payload.refreshToken)
            ?: throw IllegalArgumentException("Refresh token is invalid")

        val user = userRepository.findById(session.userId).orElse(null)
            ?: throw IllegalArgumentException("User not found")

        if (!user.active) {
            throw IllegalArgumentException("User is blocked")
        }

        return AuthPayload(
            user = user,
            accessToken = session.accessToken,
            refreshToken = session.refreshToken,
        )
    }

    fun getCurrentUser(userId: Long?): UserEntity? {
        if (userId == null) return null
        return userRepository.findById(userId).orElse(null)
    }

    private fun createAuthPayload(user: UserEntity): AuthPayload {
        val session = tokenStore.createSession(user.id!!)

        return AuthPayload(
            user = user,
            accessToken = session.accessToken,
            refreshToken = session.refreshToken,
        )
    }
}
