package com.nisemoe.nise.service

import com.nisemoe.generated.tables.references.USERS
import org.jooq.DSLContext
import org.springframework.security.authentication.AnonymousAuthenticationToken
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.core.user.DefaultOAuth2User
import org.springframework.stereotype.Service
import java.time.OffsetDateTime

@Service
class AuthService(
    private val dslContext: DSLContext
) {

    data class UserInfo(
        val userId: Long,
        val username: String,

        val country: String?,
        val joinDate: OffsetDateTime?,

    )

    fun isAdmin(): Boolean {
        if(!this.isLoggedIn())
            return false

        val currentUser = this.getCurrentUser()
        return dslContext.fetchExists(USERS, USERS.USER_ID.eq(currentUser.userId).and(USERS.IS_ADMIN))
    }

    fun isLoggedIn(): Boolean {
        val authentication = SecurityContextHolder.getContext().authentication
        return !(authentication == null || authentication is AnonymousAuthenticationToken || authentication.principal == null)
    }

    fun parseJoinDate(joinDate: String?): OffsetDateTime? {
        return try {
            if(joinDate == null) null else OffsetDateTime.parse(joinDate)
        } catch (e: Exception) {
            null
        }
    }

    fun getCurrentUser(): UserInfo {
        if(!this.isLoggedIn())
            throw IllegalStateException("User is not logged in")

        val authentication = SecurityContextHolder.getContext().authentication
        val userDetails = authentication.principal as DefaultOAuth2User

        return UserInfo(
            userId = (userDetails.attributes["id"] as Int).toLong(),
            username = userDetails.attributes["username"] as String,
            country = userDetails.attributes["country_code"] as String?,
            joinDate = parseJoinDate(userDetails.attributes["join_date"] as String?)
        )
    }

}