package com.crm.chat.data.repository

import com.crm.chat.data.api.ApiClient
import com.crm.chat.data.api.AuthApiService
import com.crm.chat.data.model.AuthResponse
import com.crm.chat.data.model.LoginRequest
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import retrofit2.Response

class AuthRepositoryTest {

    private lateinit var authApiService: AuthApiService
    private lateinit var apiClient: ApiClient
    private lateinit var authRepository: AuthRepository

    @Before
    fun setup() {
        authApiService = mockk()
        apiClient = mockk()
        coEvery { apiClient.authApiService } returns authApiService
        authRepository = AuthRepository(apiClient)
    }

    @Test
    fun `login returns success when server returns valid token`() = runBlocking {
        // Given
        val validToken = "valid-jwt-token"
        val authResponse = AuthResponse(token = validToken)
        val response = Response.success(authResponse)
        
        coEvery { 
            authApiService.loginSite(any()) 
        } returns response

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isSuccess)
        assertEquals(validToken, result.getOrNull()?.token)
    }

    @Test
    fun `login returns error when server returns null response`() = runBlocking {
        // Given
        val response = Response.success<AuthResponse>(null)
        
        coEvery { 
            authApiService.loginSite(any()) 
        } returns response

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isFailure)
        assertEquals("Сервер вернул пустой ответ. Проверьте подключение к серверу и правильность URL.", 
            result.exceptionOrNull()?.message)
    }

    @Test
    fun `login returns error when server returns empty token`() = runBlocking {
        // Given
        val authResponse = AuthResponse(token = null)
        val response = Response.success(authResponse)
        
        coEvery { 
            authApiService.loginSite(any()) 
        } returns response

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isFailure)
        assertEquals("Сервер вернул пустой токен. Проверьте правильность email и пароля.", 
            result.exceptionOrNull()?.message)
    }

    @Test
    fun `login returns error when server returns 401`() = runBlocking {
        // Given
        val response = Response.error<AuthResponse>(401, mockk())
        
        coEvery { 
            authApiService.loginSite(any()) 
        } returns response

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isFailure)
        assertEquals("Неверный email или пароль (401). Проверьте правильность введенных данных.", 
            result.exceptionOrNull()?.message)
    }

    @Test
    fun `login returns error when server returns 404`() = runBlocking {
        // Given
        val response = Response.error<AuthResponse>(404, mockk())
        
        coEvery { 
            authApiService.loginSite(any()) 
        } returns response

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isFailure)
        assertEquals("Сервер не найден (404). Проверьте URL сервера и подключение к сети.", 
            result.exceptionOrNull()?.message)
    }

    @Test
    fun `login returns error when network exception occurs`() = runBlocking {
        // Given
        coEvery { 
            authApiService.loginSite(any()) 
        } throws java.net.UnknownHostException("Host not found")

        // When
        val result = authRepository.login("test@example.com", "password")

        // Then
        assertTrue(result.isFailure)
        assertEquals("Нет подключения к серверу. Проверьте интернет-соединение и правильность URL.", 
            result.exceptionOrNull()?.message)
    }
}
