package com.crm.chat.data.repository

import com.crm.chat.data.api.ApiClient
import com.crm.chat.data.api.User
import com.crm.chat.data.model.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import android.util.Log
import okhttp3.MediaType.Companion.toMediaType

class ChatRepository(private val apiClient: ApiClient) {

    // Expose base URL for download URL construction
    fun getBaseUrl(): String = apiClient.getBaseUrl()

    suspend fun getChatProviders(): Result<List<ChatProvider>> {
        return withContext(Dispatchers.IO) {
            try {
                // TODO: Implement chat providers API when available
                Result.success(emptyList())
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting chat providers", e)
                Result.failure(e)
            }
        }
    }

    suspend fun getChats(limit: Int = 50, offset: Int = 0): Result<List<Chat>> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.getChats(limit, offset)

                if (response.isSuccessful) {
                    val chats = response.body()
                    if (chats != null) {
                        Result.success(chats)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting chats", e)
                Result.failure(e)
            }
        }
    }

    suspend fun getChat(chatId: Long): Result<Chat> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.getChat(chatId)

                if (response.isSuccessful) {
                    val chat = response.body()
                    if (chat != null) {
                        Result.success(chat)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting chat", e)
                Result.failure(e)
            }
        }
    }

    suspend fun deleteChat(chatId: Long): Result<Unit> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.deleteChat(chatId)

                if (response.isSuccessful) {
                    Result.success(Unit)
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error deleting chat", e)
                Result.failure(e)
            }
        }
    }

    // Chat creation methods
    suspend fun createPersonalChat(request: CreatePersonalChatRequest): Result<Chat> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.createPersonalChat(request)

                if (response.isSuccessful) {
                    val chat = response.body()
                    if (chat != null) {
                        Result.success(chat)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error creating personal chat", e)
                Result.failure(e)
            }
        }
    }

    suspend fun createGroupChat(request: CreateGroupChatRequest): Result<Chat> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.createGroupChat(request)

                if (response.isSuccessful) {
                    val chat = response.body()
                    if (chat != null) {
                        Result.success(chat)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error creating group chat", e)
                Result.failure(e)
            }
        }
    }

    suspend fun createExternalChat(request: CreateExternalChatRequest): Result<Chat> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.createExternalChat(request)

                if (response.isSuccessful) {
                    val chat = response.body()
                    if (chat != null) {
                        Result.success(chat)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error creating external chat", e)
                Result.failure(e)
            }
        }
    }

    // Chat search methods
    suspend fun findChats(filters: Map<String, String>): Result<List<Chat>> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.findChats(filters)

                if (response.isSuccessful) {
                    val chats = response.body()
                    if (chats != null) {
                        Result.success(chats)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error finding chats", e)
                Result.failure(e)
            }
        }
    }

    suspend fun findChatsFull(filters: Map<String, String>): Result<List<Chat>> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.findChatsFull(filters)

                if (response.isSuccessful) {
                    val chats = response.body()
                    if (chats != null) {
                        Result.success(chats)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error finding chats full", e)
                Result.failure(e)
            }
        }
    }

    // Message management methods
    suspend fun sendMessage(chatId: Long, request: SendMessageRequest): Result<ChatMessage> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.sendMessage(chatId, request)

                if (response.isSuccessful) {
                    val message = response.body()
                    if (message != null) {
                        Result.success(message)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error sending message", e)
                Result.failure(e)
            }
        }
    }

    suspend fun updateMessage(chatId: Long, messageId: Long, request: UpdateMessageRequest): Result<ChatMessage> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.updateMessage(chatId, messageId, request)

                if (response.isSuccessful) {
                    val message = response.body()
                    if (message != null) {
                        Result.success(message)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error updating message", e)
                Result.failure(e)
            }
        }
    }

    suspend fun deleteMessage(chatId: Long, messageId: Long): Result<Unit> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.deleteMessage(chatId, messageId)

                if (response.isSuccessful) {
                    Result.success(Unit)
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error deleting message", e)
                Result.failure(e)
            }
        }
    }

    suspend fun reactToMessage(chatId: Long, messageId: Long, reaction: String): Result<ChatMessage> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.reactToMessage(chatId, messageId, reaction)

                if (response.isSuccessful) {
                    val message = response.body()
                    if (message != null) {
                        Result.success(message)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error reacting to message", e)
                Result.failure(e)
            }
        }
    }

    suspend fun unreactToMessage(chatId: Long, messageId: Long, reactionId: Long): Result<ChatMessage> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.unreactToMessage(chatId, messageId, reactionId)

                if (response.isSuccessful) {
                    val message = response.body()
                    if (message != null) {
                        Result.success(message)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error unreacting to message", e)
                Result.failure(e)
            }
        }
    }

    // Message methods
    suspend fun getChatMessages(chatId: Long, limit: Int = 50, offset: Int = 0): Result<ChatMessagesResponse> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.getChatMessages(chatId, limit, offset)

                if (response.isSuccessful) {
                    val messagesResponse = response.body()
                    if (messagesResponse != null) {
                        Result.success(messagesResponse)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting chat messages", e)
                Result.failure(e)
            }
        }
    }

    suspend fun markMessagesAsRead(chatId: Long, messageIds: List<Long>): Result<List<ChatMessage>> {
        return withContext(Dispatchers.IO) {
            try {
                val request = com.crm.chat.data.model.MarkMessagesReadRequest(messageIds)
                val response = apiClient.chatApiService.markMessagesAsRead(chatId, request)

                if (response.isSuccessful) {
                    val messages = response.body()
                    if (messages != null) {
                        Result.success(messages)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error marking messages as read", e)
                Result.failure(e)
            }
        }
    }

    suspend fun markAllMessagesAsRead(chatId: Long): Result<Unit> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.markAllMessagesAsRead(chatId)

                if (response.isSuccessful) {
                    Result.success(Unit)
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error marking messages as read", e)
                Result.failure(e)
            }
        }
    }

    // Utility methods
    suspend fun getUnseenCount(): Result<Int> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.getUnseenCount()

                if (response.isSuccessful) {
                    val count = response.body()
                    if (count != null) {
                        Result.success(count)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting unseen count", e)
                Result.failure(e)
            }
        }
    }

    suspend fun getUsers(search: String? = null, limit: Int = 50, offset: Int = 0): Result<List<User>> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiClient.chatApiService.getUsers(limit, offset, search)

                if (response.isSuccessful) {
                    val users = response.body()
                    if (users != null) {
                        Result.success(users)
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code()}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error getting users", e)
                Result.failure(e)
            }
        }
    }

    @Suppress("DEPRECATION")
    suspend fun uploadFile(fileUri: android.net.Uri, contentResolver: android.content.ContentResolver): Result<List<FileUploadResponse>> {
        return withContext(Dispatchers.IO) {
            try {
                // Read file data
                val fileName = getFileName(fileUri, contentResolver)
                val mimeType = contentResolver.getType(fileUri) ?: "application/octet-stream"
                val inputStream = contentResolver.openInputStream(fileUri)
                    ?: return@withContext Result.failure(Exception("Cannot open file"))

                val fileData = inputStream.use { it.readBytes() }

                // Create multipart request
                val requestBody = okhttp3.MultipartBody.Builder()
                    .setType(okhttp3.MultipartBody.FORM)
                    .addFormDataPart(fileName, fileName,
                        okhttp3.RequestBody.create(mimeType.toMediaType(), fileData))
                    .build()

                val response = apiClient.getOkHttpClientInstance().newCall(
                    okhttp3.Request.Builder()
                        .url("${apiClient.getBaseUrl()}/api/storage/upload")
                        .post(requestBody)
                        .addHeader("X-Api-Key", apiClient.getApiKey() ?: "")
                        .build()
                ).execute()

                if (response.isSuccessful) {
                    val responseBody = response.body?.string()
                    if (responseBody != null) {
                        val gson = com.google.gson.Gson()
                        val fileResponse = gson.fromJson(
                            responseBody,
                            Array<FileUploadResponse>::class.java
                        )
                        Result.success(fileResponse.toList())
                    } else {
                        Result.failure(Exception("Empty response"))
                    }
                } else {
                    Result.failure(Exception("Error: ${response.code}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error uploading file", e)
                Result.failure(e)
            }
        }
    }

    private fun getFileName(uri: android.net.Uri, contentResolver: android.content.ContentResolver): String {
        var fileName = "file"
        contentResolver.query(uri, null, null, null, null)?.use { cursor ->
            val nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
            if (cursor.moveToFirst() && nameIndex >= 0) {
                fileName = cursor.getString(nameIndex)
            }
        }
        return fileName
    }

    @Suppress("DEPRECATION")
    suspend fun downloadFile(downloadUrl: String, fileName: String, context: android.content.Context): Result<java.io.File> {
        return withContext(Dispatchers.IO) {
            try {
                // Log the request details
                Log.d("ChatRepository", "Download request URL: $downloadUrl")
                Log.d("ChatRepository", "Download file name: $fileName")

                // Create a request WITHOUT Authorization header (like web version)
                // Only add X-Api-Key if it's needed for the specific endpoint
                val request = okhttp3.Request.Builder()
                    .url(downloadUrl)
                    .addHeader("X-Api-Key", apiClient.getApiKey() ?: "")
                    // Remove Authorization header that was causing 400 errors
                    .build()

                Log.d("ChatRepository", "Request headers: X-Api-Key=${apiClient.getApiKey()}")

                val response = apiClient.getOkHttpClientInstance().newCall(request).execute()

                Log.d("ChatRepository", "Response code: ${response.code}")
                Log.d("ChatRepository", "Response message: ${response.message}")

                if (response.isSuccessful) {
                    val inputStream = response.body?.byteStream()
                    if (inputStream != null) {
                        // Save to cache directory first
                        val cacheDir = context.cacheDir
                        val cacheFile = java.io.File(cacheDir, "temp_$fileName")

                        cacheFile.outputStream().use { output ->
                            inputStream.copyTo(output)
                        }

                        Log.d("ChatRepository", "File saved to cache: ${cacheFile.absolutePath}, size: ${cacheFile.length()} bytes")

                        Result.success(cacheFile)
                    } else {
                        Log.e("ChatRepository", "Empty response body")
                        Result.failure(Exception("Empty response body"))
                    }
                } else {
                    Log.e("ChatRepository", "Download failed with code: ${response.code}, message: ${response.message}")
                    val errorBody = response.body?.string()
                    Log.e("ChatRepository", "Error response body: $errorBody")
                    Result.failure(Exception("Download failed: ${response.code} - ${response.message}"))
                }
            } catch (e: Exception) {
                Log.e("ChatRepository", "Error downloading file", e)
                Result.failure(e)
            }
        }
    }

}
