package com.rosetta.messenger.data

import android.content.Context
import android.content.SharedPreferences
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import io.mockk.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.Assert.*

/**
 * Unit tests for AccountManager
 * Tests account storage and retrieval logic
 */
@OptIn(ExperimentalCoroutinesApi::class)
class AccountManagerTest {
    
    private lateinit var mockContext: Context
    private lateinit var mockSharedPrefs: SharedPreferences
    private lateinit var mockEditor: SharedPreferences.Editor
    
    @Before
    fun setup() {
        mockContext = mockk(relaxed = true)
        mockSharedPrefs = mockk(relaxed = true)
        mockEditor = mockk(relaxed = true)
        
        every { mockContext.getSharedPreferences(any(), any()) } returns mockSharedPrefs
        every { mockSharedPrefs.edit() } returns mockEditor
        every { mockEditor.putString(any(), any()) } returns mockEditor
        every { mockEditor.commit() } returns true
        every { mockEditor.apply() } just Runs
    }
    
    @Test
    fun `getLastLoggedPublicKey should return null when not set`() {
        every { mockSharedPrefs.getString(any(), null) } returns null
        
        val accountManager = AccountManager(mockContext)
        val result = accountManager.getLastLoggedPublicKey()
        
        assertNull("Should return null when no last logged account", result)
    }
    
    @Test
    fun `setLastLoggedPublicKey should save publicKey synchronously`() {
        val testPublicKey = "04abcdef1234567890"
        
        val accountManager = AccountManager(mockContext)
        accountManager.setLastLoggedPublicKey(testPublicKey)
        
        verify { mockEditor.putString("last_logged_public_key", testPublicKey) }
        verify { mockEditor.commit() } // Should use commit() not apply()
    }
    
    @Test
    fun `getLastLoggedPublicKey should return saved publicKey`() {
        val testPublicKey = "04abcdef1234567890"
        every { mockSharedPrefs.getString("last_logged_public_key", null) } returns testPublicKey
        
        val accountManager = AccountManager(mockContext)
        val result = accountManager.getLastLoggedPublicKey()
        
        assertEquals("Should return saved public key", testPublicKey, result)
    }
    
    @Test
    fun `setLastLoggedPublicKey should overwrite previous value`() {
        val publicKey1 = "04abcdef1111111111"
        val publicKey2 = "04abcdef2222222222"
        
        val accountManager = AccountManager(mockContext)
        accountManager.setLastLoggedPublicKey(publicKey1)
        accountManager.setLastLoggedPublicKey(publicKey2)
        
        verify(exactly = 2) { mockEditor.putString("last_logged_public_key", any()) }
        verify(exactly = 2) { mockEditor.commit() }
    }
}
