package de.krisenvorrat.server.routes

import de.krisenvorrat.server.model.ErrorResponse
import de.krisenvorrat.server.model.LoginRequest
import de.krisenvorrat.server.model.LoginResponse
import de.krisenvorrat.server.model.RefreshRequest
import de.krisenvorrat.server.repository.InventoryRepository
import de.krisenvorrat.server.repository.UserRepository
import de.krisenvorrat.server.security.JwtService
import io.ktor.http.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.mindrot.jbcrypt.BCrypt

internal fun Route.authRoutes(
    userRepository: UserRepository,
    jwtService: JwtService,
    inventoryRepository: InventoryRepository
) {
    route("/api/auth") {
        post("/login") {
            val request = call.receive<LoginRequest>()
            val user = userRepository.findByUsername(request.username)
            if (user == null || !BCrypt.checkpw(request.password, user.passwordHash)) {
                call.respond(
                    HttpStatusCode.Unauthorized,
                    ErrorResponse(status = 401, message = "Invalid username or password")
                )
                return@post
            }
            val accessToken = jwtService.generateAccessToken(user.id, user.username, user.isAdmin)
            val refreshToken = jwtService.generateRefreshToken(user.id)
            val inventoryId = user.inventoryId
            val inventoryName = if (inventoryId != null) inventoryRepository.getInventoryName(inventoryId) else null
            call.respond(
                HttpStatusCode.OK,
                LoginResponse(
                    accessToken = accessToken,
                    refreshToken = refreshToken,
                    userId = user.id,
                    username = user.username,
                    inventoryId = inventoryId,
                    inventoryName = inventoryName
                )
            )
        }

        post("/refresh") {
            val request = call.receive<RefreshRequest>()
            val userId = jwtService.extractRefreshUserId(request.refreshToken)
            if (userId == null) {
                call.respond(
                    HttpStatusCode.Unauthorized,
                    ErrorResponse(status = 401, message = "Invalid or expired refresh token")
                )
                return@post
            }
            val user = userRepository.findById(userId)
            if (user == null) {
                call.respond(
                    HttpStatusCode.Unauthorized,
                    ErrorResponse(status = 401, message = "User not found")
                )
                return@post
            }
            val accessToken = jwtService.generateAccessToken(user.id, user.username, user.isAdmin)
            val refreshToken = jwtService.generateRefreshToken(user.id)
            call.respond(
                HttpStatusCode.OK,
                LoginResponse(
                    accessToken = accessToken,
                    refreshToken = refreshToken,
                    userId = user.id,
                    username = user.username
                )
            )
        }
    }
}
