package com.aiosman.ravenow.ui.chat

import android.content.Context
import android.net.Uri
import android.provider.MediaStore
import android.util.Log
import android.webkit.MimeTypeMap
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.aiosman.ravenow.data.AccountService
import com.aiosman.ravenow.data.AccountServiceImpl
import com.aiosman.ravenow.data.UserService
import com.aiosman.ravenow.data.UserServiceImpl
import com.aiosman.ravenow.entity.AccountProfileEntity
import com.aiosman.ravenow.entity.ChatItem
import io.openim.android.sdk.OpenIMClient
import io.openim.android.sdk.enums.ConversationType
import io.openim.android.sdk.enums.ViewType
import io.openim.android.sdk.listener.OnAdvanceMsgListener
import io.openim.android.sdk.listener.OnBase
import io.openim.android.sdk.listener.OnMsgSendCallback
import io.openim.android.sdk.models.*
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

/**
 * 聊天ViewModel基类，包含所有聊天功能的通用实现
 * 子类需要实现抽象方法来处理特定的聊天类型（单聊/群聊）
 */
abstract class BaseChatViewModel : ViewModel() {
    
    // 通用状态属性
    var chatData by mutableStateOf<List<ChatItem>>(emptyList())
    var myProfile by mutableStateOf<AccountProfileEntity?>(null)
    var hasMore by mutableStateOf(true)
    var isLoading by mutableStateOf(false)
    var lastMessage: Message? = null
    val showTimestampMap = mutableMapOf<String, Boolean>()
    var goToNew by mutableStateOf(false)
    var conversationID: String = "" // 会话ID，通过getOneConversation初始化
    
    // 通用服务
    val userService: UserService = UserServiceImpl()
    val accountService: AccountService = AccountServiceImpl()
    var textMessageListener: OnAdvanceMsgListener? = null

    val fetchHistorySize = 20
    
    /**
     * 初始化方法，子类需要实现具体的初始化逻辑
     */
    abstract fun init(context: Context)
    
    /**
     * 获取日志标签，子类需要实现
     */
    abstract fun getLogTag(): String
    
    /**
     * 获取会话参数，子类需要实现
     * @return Triple(targetId, conversationType, isSingleChat)
     */
    abstract fun getConversationParams(): Triple<String, Int, Boolean>
    
    /**
     * 处理接收到的新消息，子类可以重写以添加特定逻辑
     */
    open fun handleNewMessage(message: Message, context: Context): Boolean {
        return false // 默认不处理，子类重写
    }
    
    /**
     * 获取发送消息时的接收者ID，子类需要实现
     */
    abstract fun getReceiverInfo(): Pair<String?, String?> // (recvID, groupID)
    
    /**
     * 发送消息成功后的额外处理，子类可以重写
     */
    open fun onMessageSentSuccess(message: String, sentMessage: Message?) {
        // 默认无额外处理，子类可以重写
    }
    
    /**
     * 获取会话信息并初始化conversationID
     */
    fun getOneConversation(onSuccess: (() -> Unit)? = null) {
        val (targetId, conversationType, isSingleChat) = getConversationParams()
        
        OpenIMClient.getInstance().conversationManager.getOneConversation(
            object : OnBase<ConversationInfo> {
                override fun onError(code: Int, error: String) {
                    Log.e(getLogTag(), "getOneConversation error: $error")
                }

                override fun onSuccess(data: ConversationInfo) {
                    conversationID = data.conversationID
                    Log.d(getLogTag(), "获取会话信息成功，conversationID: $conversationID")
                    onSuccess?.invoke()
                }
            },
            targetId,
            conversationType
        )
    }
    
    /**
     * 注册消息监听器
     */
    fun RegistListener(context: Context) {
        // 检查 OpenIM 是否已登录
        if (!com.aiosman.ravenow.AppState.enableChat) {
            Log.w(getLogTag(), "OpenIM 未登录，跳过注册消息监听器")
            return
        }
        
        textMessageListener = object : OnAdvanceMsgListener {
            override fun onRecvNewMessage(msg: Message?) {
                msg?.let { message ->
                    if (handleNewMessage(message, context)) {
                        val chatItem = ChatItem.convertToChatItem(message, context, avatar = getMessageAvatar(message))
                        chatItem?.let {
                            chatData = listOf(it) + chatData
                            goToNew = true
                            Log.i(getLogTag(), "收到来自 ${message.sendID} 的消息，更新聊天列表")
                        }
                    }
                }
            }
        }
        OpenIMClient.getInstance().messageManager.setAdvancedMsgListener(textMessageListener)
    }
    
    /**
     * 获取消息头像，子类可以重写
     */
    open fun getMessageAvatar(message: Message): String? {
        return null
    }
    
    /**
     * 取消注册消息监听器
     */
    fun UnRegistListener() {
        textMessageListener = null
    }
    
    /**
     * 清除未读消息
     */
    fun clearUnRead() {
        if (conversationID.isEmpty()) {
            Log.w(getLogTag(), "conversationID为空，无法清除未读消息")
            return
        }

        OpenIMClient.getInstance().messageManager.markConversationMessageAsRead(
            conversationID,
            object : OnBase<String> {
                override fun onSuccess(data: String?) {
                    Log.i("openim", "清除未读消息成功")
                }

                override fun onError(code: Int, error: String?) {
                    Log.i("openim", "清除未读消息失败, code:$code, error:$error")
                }
            }
        )
    }
    
    /**
     * 加载更多历史消息
     */
    fun onLoadMore(context: Context) {
        if (!hasMore || isLoading) {
            return
        }
        loadHistoryMessages(context, isLoadMore = true)
    }
    
    /**
     * 发送文本消息
     */
    fun sendMessage(message: String, context: Context) {
        // 检查 OpenIM 是否已登录
        if (!com.aiosman.ravenow.AppState.enableChat) {
            Log.w(getLogTag(), "OpenIM 未登录，无法发送消息")
            return
        }
        
        val textMessage = OpenIMClient.getInstance().messageManager.createTextMessage(message)
        val (recvID, groupID) = getReceiverInfo()
        
        OpenIMClient.getInstance().messageManager.sendMessage(
            object : OnMsgSendCallback {
                override fun onProgress(progress: Long) {
                    // 发送进度
                }

                override fun onError(code: Int, error: String?) {
                    Log.e(getLogTag(), "发送消息失败: $error")
                }

                override fun onSuccess(data: Message?) {
                    Log.d(getLogTag(), "发送消息成功")
                    onMessageSentSuccess(message, data)
                    data?.let { sentMessage ->
                        val chatItem = ChatItem.convertToChatItem(sentMessage, context, avatar = myProfile?.avatar)
                        chatItem?.let {
                            chatData = listOf(it) + chatData
                            goToNew = true
                        }
                    }
                }
            },
            textMessage,
            recvID,
            groupID,
            OfflinePushInfo()
        )
    }
    
    /**
     * 发送图片消息
     */
    fun sendImageMessage(imageUri: Uri, context: Context) {
        val tempFile = createTempFile(context, imageUri)
        val imagePath = tempFile?.path
        if (imagePath != null) {
            val imageMessage = OpenIMClient.getInstance().messageManager.createImageMessageFromFullPath(imagePath)
            val (recvID, groupID) = getReceiverInfo()
            
            OpenIMClient.getInstance().messageManager.sendMessage(
                object : OnMsgSendCallback {
                    override fun onProgress(progress: Long) {
                        Log.d(getLogTag(), "发送图片消息进度: $progress")
                    }

                    override fun onError(code: Int, error: String?) {
                        Log.e(getLogTag(), "发送图片消息失败: $error")
                    }

                    override fun onSuccess(data: Message?) {
                        Log.d(getLogTag(), "发送图片消息成功")
                        data?.let { sentMessage ->
                            val chatItem = ChatItem.convertToChatItem(sentMessage, context, avatar = myProfile?.avatar)
                            chatItem?.let {
                                chatData = listOf(it) + chatData
                                goToNew = true
                            }
                        }
                    }
                },
                imageMessage,
                recvID,
                groupID,
                OfflinePushInfo()
            )
        }
    }
    
    /**
     * 创建临时文件
     */
    fun createTempFile(context: Context, uri: Uri): File? {
        return try {
            val projection = arrayOf(MediaStore.Images.Media.DATA)
            val cursor = context.contentResolver.query(uri, projection, null, null, null)
            cursor?.use {
                if (it.moveToFirst()) {
                    val columnIndex = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
                    val filePath = it.getString(columnIndex)
                    val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
                    val mimeType = context.contentResolver.getType(uri)
                    val extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)
                    val tempFile =
                        File.createTempFile("temp_image", ".$extension", context.cacheDir)
                    val outputStream = FileOutputStream(tempFile)

                    inputStream?.use { input ->
                        outputStream.use { output ->
                            input.copyTo(output)
                        }
                    }
                    tempFile
                } else {
                    null
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
    
    /**
     * 获取历史消息
     */
    fun fetchHistoryMessage(context: Context) {
        loadHistoryMessages(context, isLoadMore = false)
    }
    
    /**
     * 加载历史消息的通用方法
     * @param context 上下文
     * @param isLoadMore 是否是加载更多（true：追加到现有数据，false：替换现有数据）
     */
    private fun loadHistoryMessages(context: Context, isLoadMore: Boolean) {
        if (conversationID.isEmpty()) {
            Log.w(getLogTag(), "conversationID为空，无法${if (isLoadMore) "加载更多" else "获取"}历史消息")
            return
        }
        
        if (isLoadMore) {
            isLoading = true
        }
        
        viewModelScope.launch {
            OpenIMClient.getInstance().messageManager.getAdvancedHistoryMessageList(
                object : OnBase<AdvancedMessage> {
                    override fun onSuccess(data: AdvancedMessage?) {
                        val messages = data?.messageList ?: emptyList()
                        val newChatItems = messages.mapNotNull {
                            ChatItem.convertToChatItem(it, context, avatar = getMessageAvatar(it))
                        }.reversed() // 反转顺序，使最新消息在前面
                        
                        // 根据是否是加载更多来决定数据处理方式
                        chatData = if (isLoadMore) {
                            chatData + newChatItems // 追加到现有数据
                        } else {
                            newChatItems // 替换现有数据
                        }
                        
                        if (messages.size < fetchHistorySize) {
                            hasMore = false
                        }
                        lastMessage = messages.firstOrNull()
                        
                        if (isLoadMore) {
                            isLoading = false
                        }
                        
                        Log.d(getLogTag(), "${if (isLoadMore) "加载更多" else "获取"}历史消息成功")
                    }

                    override fun onError(code: Int, error: String?) {
                        Log.e(getLogTag(), "${if (isLoadMore) "加载更多" else "获取"}历史消息失败: $error")
                        if (isLoadMore) {
                            isLoading = false
                        }
                    }
                },
                conversationID,
                if (isLoadMore) lastMessage else null, // 首次加载不传lastMessage
                fetchHistorySize,
                ViewType.History
            )
        }
    }
    
    /**
     * 获取显示的聊天列表
     */
    fun getDisplayChatList(): List<ChatItem> {
        val list = chatData
        // 更新每条消息的时间戳显示状态
        for (item in list) {
            item.showTimestamp = showTimestampMap.getOrDefault(item.msgId, false)
        }
        return list
    }
}
