package com.stand.standapp.ui.chat

import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.stand.standapp.AppConfig
import com.stand.standapp.ui.chat.model.ChatMessage
import com.stand.standapp.ui.chat.model.ChatSession
import com.stand.standapp.ui.chat.repo.AiChatRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONObject
import java.util.UUID

class ChatViewModel(application: Application) : AndroidViewModel(application) {
    private val repository = AiChatRepository()

    private val _sessions = MutableStateFlow<List<ChatSession>>(emptyList())
    val sessions: StateFlow<List<ChatSession>> = _sessions.asStateFlow()

    private val _currentSessionId = MutableStateFlow<String?>(null)
    val currentSessionId: StateFlow<String?> = _currentSessionId.asStateFlow()

    private val _messages = MutableStateFlow<List<ChatMessage>>(emptyList())
    val messages: StateFlow<List<ChatMessage>> = _messages.asStateFlow()

    // 👈 声明一个正在加载的状态，保证上一个问题没结束前无法再次发送提问！
    private val _isLoading = MutableStateFlow(false)
    val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
    
    // 👈 额外声明一个当前协程控制作业，用于物理取消/中止 SSE 对话！
    private var activeChatJob: kotlinx.coroutines.Job? = null

    private val prefs = application.getSharedPreferences("ai_chat_cache", Context.MODE_PRIVATE)

    init {
        // 👈 将数据加载移到IO线程，避免阻塞主线程导致UI卡顿
        viewModelScope.launch(kotlinx.coroutines.Dispatchers.IO) {
            loadCacheFromLocal()
        }
    }

    private fun loadCacheFromLocal() {
        try {
            val sessionsJson = prefs.getString("cache_sessions", "")
            val messagesJson = prefs.getString("cache_messages", "")

            if (!sessionsJson.isNullOrBlank()) {
                val sessionsArray = JSONArray(sessionsJson)
                val restoredSessions = mutableListOf<ChatSession>()
                for (i in 0 until sessionsArray.length()) {
                    val obj = sessionsArray.getJSONObject(i)
                    restoredSessions.add(
                        ChatSession(
                            id = obj.getString("id"),
                            title = obj.getString("title"),
                            timestamp = obj.getLong("timestamp")
                        )
                    )
                }
                _sessions.value = restoredSessions
                if (restoredSessions.isNotEmpty()) {
                    _currentSessionId.value = restoredSessions.first().id
                }
            }

            if (!messagesJson.isNullOrBlank()) {
                val messagesArray = JSONArray(messagesJson)
                val restoredMessages = mutableListOf<ChatMessage>()
                val maxMessages = 200 // 👈 限制最多加载200条消息，避免大数据解析卡顿
                val startIndex = (messagesArray.length() - maxMessages).coerceAtLeast(0)
                for (i in startIndex until messagesArray.length()) {
                    val obj = messagesArray.getJSONObject(i)
                    restoredMessages.add(
                        ChatMessage(
                            id = obj.getString("id"),
                            sessionId = obj.getString("sessionId"),
                            role = ChatMessage.Role.valueOf(obj.getString("role")),
                            content = obj.getString("content"),
                            isStreaming = false
                        )
                    )
                }
                _messages.value = restoredMessages
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        if (_sessions.value.isEmpty()) {
            createNewSession()
        }
    }

    private fun saveCacheToLocal() {
        try {
            // 保存会话列表
            val sessionsArray = JSONArray()
            _sessions.value.forEach { session ->
                val obj = JSONObject()
                obj.put("id", session.id)
                obj.put("title", session.title)
                obj.put("timestamp", session.timestamp)
                sessionsArray.put(obj)
            }

            // 保存消息列表
            val messagesArray = JSONArray()
            _messages.value.forEach { msg ->
                val obj = JSONObject()
                obj.put("id", msg.id)
                obj.put("sessionId", msg.sessionId)
                obj.put("role", msg.role.name)
                obj.put("content", msg.content)
                messagesArray.put(obj)
            }

            prefs.edit()
                .putString("cache_sessions", sessionsArray.toString())
                .putString("cache_messages", messagesArray.toString())
                .apply()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // 👈 用户手动中断当前正在生成的 AI 回答的方法！
    fun cancelActiveStreaming() {
        activeChatJob?.cancel() // 物理取消协程作业，断开 SSE OkHttp 连接并关闭流！
        activeChatJob = null
        
        // 将当前正在流式输出的 AI 消息状态重置为完成，防止气泡卡死在 streaming 样式
        _messages.value = _messages.value.map { msg ->
            if (msg.isStreaming) {
                msg.copy(isStreaming = false)
            } else msg
        }
        
        _isLoading.value = false // 释放锁，允许用户立刻开始下一次提问！
        saveCacheToLocal() // 强制存盘归档
    }

    fun createNewSession() {
        val newSession = ChatSession()
        // 👈 限制最多保留10组对话历史，超出时删除最旧的会话
        val trimmedSessions = if (_sessions.value.size >= 10) {
            val sessionsToKeep = _sessions.value.take(9)
            // 同时删除最旧会话的消息
            val removedSessionIds = _sessions.value.drop(9).map { it.id }.toSet()
            _messages.value = _messages.value.filter { it.sessionId !in removedSessionIds }
            sessionsToKeep
        } else {
            _sessions.value
        }
        _sessions.value = listOf(newSession) + trimmedSessions
        _currentSessionId.value = newSession.id
        saveCacheToLocal()
    }

    fun switchSession(sessionId: String) {
        _currentSessionId.value = sessionId
    }

    fun clearAllSessions() {
        _sessions.value = emptyList()
        _messages.value = emptyList()
        _currentSessionId.value = null
        prefs.edit().clear().apply()
        createNewSession()
    }

    fun sendMessage(content: String) {
        if (_isLoading.value) return // 👈 拦截提问：上一个回答正在流式写时，绝对不允许重复提交！
        
        val sessionId = _currentSessionId.value ?: return
        _isLoading.value = true // 👈 锁定发送状态
        
        // 1. 如果是新会话，更新标题
        updateSessionTitleIfFirstMessage(sessionId, content)

        // 2. 添加用户消息
        val userMsg = ChatMessage(sessionId = sessionId, role = ChatMessage.Role.USER, content = content)
        
        // 3. 准备 AI 空消息，处于 streaming 状态
        val aiMsgId = UUID.randomUUID().toString()
        val aiMsg = ChatMessage(id = aiMsgId, sessionId = sessionId, role = ChatMessage.Role.AI, content = "", isStreaming = true)
        
        _messages.value = _messages.value + userMsg + aiMsg
        saveCacheToLocal() // 👈 用户发出消息，存入本地历史记录

        // 4. 发起网络请求，流式追加内容
        activeChatJob = viewModelScope.launch {
            val token = AppConfig.getAccessToken(getApplication())
            
            // 提取当前会话（除了刚发出的这条和尚未生成的AI回复之外的）历史对话上下文
            // 👈 限制最多取最近10轮对话（20条消息），避免token超限
            val currentSessionMsgs = _messages.value
                .filter { it.sessionId == sessionId && it.id != userMsg.id && it.id != aiMsgId && !it.isStreaming }
                .takeLast(6)
            
            // 👈 使用 JSONArray 构建历史记录，确保特殊字符被正确转义
            val historyArray = JSONArray()
            currentSessionMsgs.forEach { chatMessage ->
                val roleStr = if (chatMessage.role == ChatMessage.Role.USER) "user" else "assistant"
                val historyItem = JSONObject()
                historyItem.put("role", roleStr)
                historyItem.put("content", chatMessage.content)
                historyArray.put(historyItem)
            }
            val historyJson = if (currentSessionMsgs.isEmpty()) "" else historyArray.toString()

            repository.streamChat(getApplication(), content, token, historyJson)
                .catch { e ->
                    appendAiMessageChunk(aiMsgId, "\n[请求异常: ${e.message}]")
                    finalizeAiMessage(aiMsgId)
                    _isLoading.value = false // 发生异常释放锁
                }
                .onCompletion {
                    finalizeAiMessage(aiMsgId)
                    _isLoading.value = false // 传输完成释放锁
                }
                .collect { chunk ->
                    appendAiMessageChunk(aiMsgId, chunk)
                }
        }
    }

    private fun appendAiMessageChunk(messageId: String, chunk: String) {
        _messages.value = _messages.value.map { msg ->
            if (msg.id == messageId) {
                msg.copy(content = msg.content + chunk)
            } else msg
        }
    }

    private fun finalizeAiMessage(messageId: String) {
        _messages.value = _messages.value.map { msg ->
            if (msg.id == messageId) {
                msg.copy(isStreaming = false)
            } else msg
        }
        saveCacheToLocal() // 👈 AI 回复完毕后，状态变更为非 streaming 并归档存盘
    }

    private fun updateSessionTitleIfFirstMessage(sessionId: String, content: String) {
        val isFirst = _messages.value.none { it.sessionId == sessionId }
        if (isFirst) {
            val title = if (content.length > 10) content.take(10) + "..." else content
            _sessions.value = _sessions.value.map {
                if (it.id == sessionId) it.copy(title = title) else it
            }
        }
    }
}
