package com.rosetta.messenger.session

import com.rosetta.messenger.data.DecryptedAccount
import com.rosetta.messenger.network.SearchUser
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

data class IdentityProfile(
    val publicKey: String,
    val displayName: String = "",
    val username: String = "",
    val verified: Int = 0,
    val resolved: Boolean = false,
    val updatedAtMs: Long = System.currentTimeMillis()
)

data class IdentityStateSnapshot(
    val account: DecryptedAccount? = null,
    val profile: IdentityProfile? = null,
    val authInProgress: Boolean = false,
    val pendingPublicKey: String? = null,
    val reason: String = ""
) {
    val ownProfileResolved: Boolean
        get() {
            val activeAccount = account ?: return false
            val ownProfile = profile ?: return false
            return ownProfile.resolved && ownProfile.publicKey.equals(activeAccount.publicKey, ignoreCase = true)
        }
}

/**
 * Runtime identity source of truth for account/profile resolution.
 */
object IdentityStore {
    private val _state = MutableStateFlow(IdentityStateSnapshot())
    val state: StateFlow<IdentityStateSnapshot> = _state.asStateFlow()

    fun markLoggedOut(reason: String = "") {
        _state.value =
            IdentityStateSnapshot(
                account = null,
                profile = null,
                authInProgress = false,
                pendingPublicKey = null,
                reason = reason
            )
    }

    fun markAuthInProgress(publicKey: String? = null, reason: String = "") {
        _state.value =
            _state.value.copy(
                authInProgress = true,
                pendingPublicKey = publicKey?.trim().orEmpty().ifBlank { null },
                reason = reason
            )
    }

    fun setAccount(account: DecryptedAccount, reason: String = "") {
        val current = _state.value
        val existingProfile = current.profile
        val nextProfile =
            if (
                existingProfile != null &&
                    existingProfile.publicKey.equals(account.publicKey, ignoreCase = true)
            ) {
                existingProfile
            } else {
                null
            }

        _state.value =
            current.copy(
                account = account,
                profile = nextProfile,
                authInProgress = false,
                pendingPublicKey = null,
                reason = reason
            )
    }

    fun updateOwnProfile(
        publicKey: String,
        displayName: String? = null,
        username: String? = null,
        verified: Int? = null,
        resolved: Boolean = true,
        reason: String = ""
    ) {
        val normalizedPublicKey = publicKey.trim()
        if (normalizedPublicKey.isBlank()) return

        val current = _state.value
        val base =
            current.profile?.takeIf { it.publicKey.equals(normalizedPublicKey, ignoreCase = true) }
                ?: IdentityProfile(publicKey = normalizedPublicKey)

        val nextProfile =
            base.copy(
                displayName = displayName?.takeIf { it.isNotBlank() } ?: base.displayName,
                username = username?.takeIf { it.isNotBlank() } ?: base.username,
                verified = verified ?: base.verified,
                resolved = base.resolved || resolved,
                updatedAtMs = System.currentTimeMillis()
            )

        _state.value =
            current.copy(
                profile = nextProfile,
                reason = reason
            )
    }

    fun updateOwnProfile(user: SearchUser, reason: String = "") {
        updateOwnProfile(
            publicKey = user.publicKey,
            displayName = user.title,
            username = user.username,
            verified = user.verified,
            resolved = true,
            reason = reason
        )
    }
}
