package dev.inmo.postssystem.features.auth.client

import dev.inmo.postssystem.features.auth.common.*
import dev.inmo.postssystem.features.users.common.User
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import io.ktor.client.HttpClient
import io.ktor.client.request.HttpRequestBuilder
import kotlinx.serialization.builtins.nullable

class ClientAuthFeature(
    private val requester: UnifiedRequester,
    baseUrl: String
) : AuthFeature {
    private val rootUrl = buildStandardUrl(baseUrl.dropLastWhile { it == '/' }, authRootPathPart)
    private val fullAuthPath = buildStandardUrl(
        rootUrl,
        authAuthPathPart
    )
    private val fullRefreshPath = buildStandardUrl(
        rootUrl,
        authRefreshPathPart
    )
    private val fullGetMePath = buildStandardUrl(
        rootUrl,
        authGetMePathPart
    )

    constructor(client: HttpClient, rootUrl: String): this(
        UnifiedRequester(client),
        rootUrl
    )

    override suspend fun auth(creds: AuthCreds): AuthTokenInfo? = requester.unipost(
        fullAuthPath,
        AuthCreds.serializer() to creds,
        AuthTokenInfo.serializer().nullable
    )

    override suspend fun refresh(refresh: RefreshToken): AuthTokenInfo? = requester.unipost(
        fullRefreshPath,
        RefreshToken.serializer() to refresh,
        AuthTokenInfo.serializer().nullable
    )

    override suspend fun getMe(authToken: AuthToken): User? = requester.unipost(
        fullGetMePath,
        AuthToken.serializer() to authToken,
        User.serializer().nullable
    )

    fun isAuthRequest(builder: HttpRequestBuilder): Boolean = builder.url.buildString().let {
        it == fullAuthPath || it == fullRefreshPath
    }
}
