package dev.zxq5.chatapp.android.data.repository

import dev.zxq5.chatapp.android.api.model.QrResponse
import dev.zxq5.chatapp.android.api.SettingsClient
import dev.zxq5.chatapp.android.api.model.InviteRequest
import dev.zxq5.chatapp.android.api.model.TotpStatus
import dev.zxq5.chatapp.android.core.data.TokenStore
import dev.zxq5.chatapp.android.core.error.ApiResult

class SettingsRepository(private val tokenStore: TokenStore) {

    private var _settingsClient: SettingsClient? = null
    private var _lastToken: String? = null

    private fun getSettingsClient(): SettingsClient? {
        val token = tokenStore.get() ?: return null
        if (_settingsClient == null || token != _lastToken) {
            _settingsClient = SettingsClient(token)
            _lastToken = token
        }
        return _settingsClient
    }

    fun resetClient() {
        _settingsClient = null
        _lastToken = null
    }

    suspend fun createInvite(request: InviteRequest): ApiResult<String> {
        return getSettingsClient()?.createInvite(request) ?: ApiResult.NetworkError("Not authenticated")
    }

    suspend fun getTotpQr(password: String): ApiResult<QrResponse?> {
        val settingsClient = getSettingsClient() ?: return ApiResult.NetworkError("Not authenticated")
        return settingsClient.getTotpQr(password)
    }

    suspend fun confirmTotp(code: String): ApiResult<Unit> {
        val client = getSettingsClient() ?: return ApiResult.NetworkError("Not authenticated")
        return client.confirmTotp(code)
    }

    suspend fun getTotpStatus(): ApiResult<TotpStatus> {
        return getSettingsClient()?.getTotpStatus() ?: ApiResult.NetworkError("Not authenticated")
    }

    suspend fun disableTotp(password: String, totpCode: String): ApiResult<Unit> {
        val client = getSettingsClient() ?: return ApiResult.NetworkError("Not authenticated")
        return client.disableTotp(password, totpCode)
    }

    suspend fun changePassword(old: String, new: String): ApiResult<Unit> {
        return getSettingsClient()?.changePassword(old, new) ?: ApiResult.NetworkError("Not authenticated")
    }

    suspend fun updateDisplayName(name: String?): Boolean {
        return getSettingsClient()?.updateDisplayName(name) ?: false
    }

    suspend fun updateUsername(username: String): ApiResult<Unit> {
        return getSettingsClient()?.updateUsername(username) ?: ApiResult.NetworkError("Not authenticated")
    }

    suspend fun deleteAccount(password: String, totpCode: String?): ApiResult<Unit> {
        return getSettingsClient()?.deleteAccount(password, totpCode) ?: ApiResult.NetworkError("Not authenticated")
    }

    fun logout() {
        tokenStore.clear()
        resetClient()
    }
}
