package com.rosetta.messenger.data

import android.content.Context
import android.content.SharedPreferences
import com.rosetta.messenger.network.SearchUser
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.json.JSONArray
import org.json.JSONObject

/**
 * Менеджер для хранения недавно открытых пользователей (до 15 записей)
 * Привязан к аккаунту пользователя
 */
object RecentSearchesManager {
    private const val PREFS_NAME = "recent_searches"
    private const val KEY_USERS_PREFIX = "recent_users_" // + accountPublicKey
    private const val MAX_USERS = 15
    
    private lateinit var prefs: SharedPreferences
    private var currentAccount: String = ""
    private val _recentUsers = MutableStateFlow<List<SearchUser>>(emptyList())
    val recentUsers: StateFlow<List<SearchUser>> = _recentUsers.asStateFlow()
    
    fun init(context: Context) {
        prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    }
    
    /**
     * Установить текущий аккаунт и загрузить его историю
     */
    fun setAccount(accountPublicKey: String) {
        currentAccount = accountPublicKey
        loadUsers()
    }
    
    private fun getUsersKey(): String = KEY_USERS_PREFIX + currentAccount
    
    private fun loadUsers() {
        if (currentAccount.isEmpty()) {
            _recentUsers.value = emptyList()
            return
        }
        val usersJson = prefs.getString(getUsersKey(), "[]") ?: "[]"
        try {
            val jsonArray = JSONArray(usersJson)
            val users = mutableListOf<SearchUser>()
            for (i in 0 until jsonArray.length()) {
                val obj = jsonArray.getJSONObject(i)
                users.add(
                    SearchUser(
                        publicKey = obj.getString("publicKey"),
                        username = obj.optString("username", ""),
                        title = obj.optString("title", ""),
                        verified = obj.optInt("verified", 0),
                        online = obj.optInt("online", 0)
                    )
                )
            }
            _recentUsers.value = users
        } catch (e: Exception) {
            _recentUsers.value = emptyList()
        }
    }
    
    /**
     * Добавить пользователя в историю
     */
    fun addUser(user: SearchUser) {
        if (currentAccount.isEmpty()) return
        
        val currentUsers = _recentUsers.value.toMutableList()
        
        // Удаляем если уже есть (чтобы переместить наверх)
        currentUsers.removeAll { it.publicKey == user.publicKey }
        
        // Добавляем в начало
        currentUsers.add(0, user)
        
        // Ограничиваем до MAX_USERS
        val limitedUsers = currentUsers.take(MAX_USERS)
        
        // Сохраняем
        _recentUsers.value = limitedUsers
        saveUsers(limitedUsers)
    }
    
    /**
     * Удалить пользователя из истории
     */
    fun removeUser(publicKey: String) {
        if (currentAccount.isEmpty()) return
        
        val currentUsers = _recentUsers.value.toMutableList()
        currentUsers.removeAll { it.publicKey == publicKey }
        _recentUsers.value = currentUsers
        saveUsers(currentUsers)
    }
    
    /**
     * Очистить всю историю текущего аккаунта
     */
    fun clearAll() {
        _recentUsers.value = emptyList()
        if (currentAccount.isNotEmpty()) {
            prefs.edit().remove(getUsersKey()).apply()
        }
    }
    
    private fun saveUsers(users: List<SearchUser>) {
        if (currentAccount.isEmpty()) return
        
        val jsonArray = JSONArray()
        users.forEach { user ->
            val obj = JSONObject().apply {
                put("publicKey", user.publicKey)
                put("username", user.username)
                put("title", user.title)
                put("verified", user.verified)
                put("online", user.online)
            }
            jsonArray.put(obj)
        }
        prefs.edit().putString(getUsersKey(), jsonArray.toString()).apply()
    }
}
