package de.tsschulz.timeclock.data.auth

import de.tsschulz.timeclock.data.api.ApiException
import de.tsschulz.timeclock.data.api.LoginRequest
import de.tsschulz.timeclock.data.api.TimeClockApiClient
import de.tsschulz.timeclock.data.api.UserDto
import java.io.IOException

data class UserProfile(
    val id: Int,
    val fullName: String,
    val email: String?,
    val role: Int,
) {
    val isAdmin: Boolean get() = role == 1
}

class AuthRepository(
    private val api: TimeClockApiClient,
    private val tokenStore: TokenStore,
) {

    fun hasStoredToken(): Boolean = tokenStore.getToken() != null

    suspend fun restoreSession(): UserProfile? {
        if (tokenStore.getToken() == null) return null
        return try {
            val me = api.getMe()
            if (me.success && me.user != null) {
                me.user!!.toProfile()
            } else {
                tokenStore.clearToken()
                null
            }
        } catch (_: ApiException) {
            null
        } catch (_: IOException) {
            null
        } catch (_: Exception) {
            null
        }
    }

    suspend fun login(email: String, password: String, action: String = "0"): Result<UserProfile> {
        return try {
            val res = api.postLogin(
                LoginRequest(
                    email = email.trim(),
                    password = password,
                    action = action,
                ),
            )
            if (res.success && !res.token.isNullOrBlank() && res.user != null) {
                tokenStore.saveToken(res.token)
                Result.success(res.user!!.toProfile())
            } else {
                Result.failure(Exception(res.error ?: "Login fehlgeschlagen"))
            }
        } catch (e: ApiException) {
            Result.failure(Exception(e.message ?: "Login fehlgeschlagen"))
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    fun googleLoginUrl(): String = api.googleLoginUrl()

    suspend fun createGoogleLinkUrl(): Result<String> =
        try {
            val res = api.createGoogleLinkUrl()
            if (res.success && !res.url.isNullOrBlank()) {
                Result.success(res.url)
            } else {
                Result.failure(Exception(res.error ?: "Google-Verknüpfung konnte nicht gestartet werden"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }

    suspend fun completeOAuthLogin(token: String): Result<UserProfile> {
        tokenStore.saveToken(token)
        val user = restoreSession()
        return if (user != null) Result.success(user) else Result.failure(Exception("Google-Login konnte nicht abgeschlossen werden"))
    }

    suspend fun linkExistingOAuthAccount(pendingToken: String, email: String, password: String): Result<UserProfile> =
        try {
            val res = api.linkExistingOAuthAccount(pendingToken, email.trim(), password)
            if (res.success && !res.token.isNullOrBlank() && res.user != null) {
                tokenStore.saveToken(res.token)
                Result.success(res.user.toProfile())
            } else {
                Result.failure(Exception(res.error ?: "Google-Verknüpfung fehlgeschlagen"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }

    suspend fun logout() {
        try {
            api.postLogout()
        } catch (_: Exception) {
            // Session serverseitig ungültig oder offline — lokal trotzdem leeren
        } finally {
            tokenStore.clearToken()
        }
    }

    private fun UserDto.toProfile(): UserProfile =
        UserProfile(
            id = id,
            fullName = fullName,
            email = email,
            role = role,
        )
}
