package com.nisemoe.nise.controller

import com.nisemoe.generated.tables.references.SCORES
import com.nisemoe.nise.SimilarReplayEntry
import com.nisemoe.nise.SuspiciousScoreEntry
import com.nisemoe.nise.UserDetails
import com.nisemoe.nise.UserQueueDetails
import com.nisemoe.nise.database.ScoreService
import com.nisemoe.nise.database.UserService
import com.nisemoe.nise.service.AuthService
import com.nisemoe.nise.service.UpdateUserQueueService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
class UserDetailsController(
    private val scoreService: ScoreService,
    private val authService: AuthService,
    private val userService: UserService,
    private val userQueueService: UpdateUserQueueService
) {

    data class UserDetailsResponse(
        val user_details: UserDetails,
        val queue_details: UserQueueDetails,
        val suspicious_scores: List<SuspiciousScoreEntry>,
        val similar_replays: List<SimilarReplayEntry>,
        val total_scores: Int = 0,
        val is_banned: Boolean,
        val approximate_ban_date: String?,
    )

    data class UserQueueRequest(
        val userId: Long
    )

    @PostMapping("user-queue")
    fun addUserToQueue(@RequestBody request: UserQueueRequest): ResponseEntity<Unit> {
        // Check if the user_id currently exists
        this.userService.getUserDetails(request.userId)
            ?: return ResponseEntity.notFound().build()

        val userQueueDetails = this.userQueueService.getUserQueueDetails(request.userId)
        if(!userQueueDetails.canUpdate)
            return ResponseEntity.badRequest().build()

        val inserted = this.userQueueService.insertUser(request.userId, addedByUserId = this.authService.getCurrentUser().userId)

        return if(inserted)
            ResponseEntity.ok().build()
        else
            ResponseEntity.badRequest().build()
    }

    data class UserDetailsRequest(
        val userId: Long?,
        val username: String?
    )

    @PostMapping("user-details")
    fun getUserDetails(@RequestBody request: UserDetailsRequest): ResponseEntity<UserDetailsResponse> {
        // Check if BOTH are null or BOTH are not null
        if((request.userId == null) == (request.username == null))
            return ResponseEntity.badRequest().build()

        val identifier: Any = request.userId ?: request.username ?: return ResponseEntity.badRequest().build()
        val userDetailsExtended = this.userService.getUserDetails(identifier = identifier)
            ?: return ResponseEntity.notFound().build()

        val userId = userDetailsExtended.userDetails.user_id

        var suspiciousScoresCondition = this.scoreService.getDefaultCondition()
        suspiciousScoresCondition = suspiciousScoresCondition.and(SCORES.USER_ID.eq(userId))

        val response = UserDetailsResponse(
            user_details = userDetailsExtended.userDetails,
            queue_details = this.userQueueService.getUserQueueDetails(userId),
            suspicious_scores = this.scoreService.getSuspiciousScores(suspiciousScoresCondition),
            similar_replays = this.scoreService.getSimilarReplaysForUserId(userId),
            total_scores = this.userService.getTotalUserScores(userId),
            is_banned = userDetailsExtended.is_banned,
            approximate_ban_date = userDetailsExtended.approximate_ban_date?.toString()
        )
        return ResponseEntity.ok(response)
    }

}