<template>
    <div class="chat-page">
        <div class="left-panel">
            <UserCard @load="onLoadUserList" :cardlist="userList" height="calc(100vh - 120px)" @change="onSelectUser" />
        </div>
        <div class="right-panel">
            <div class="chat-body" ref="chatBody" @scroll="handleScroll">
                <!-- 加载更多提示 -->
                <div v-if="loadingMore" class="loading-more">加载中...</div>
                
                <ChatRecord :msgList="messages" :sendeInfo="sendeInfo" msgType="user" @retry="handleRetry" />
            </div>

            <div class="chat-footer">
                <div class="footer-left" style="">
                    <div class="upload-row" style="display:flex; align-items:center; gap:12px;margin-left: 6px;position: relative; top: 10px;">
                        <el-icon style="font-size:24px;cursor:pointer" @click="triggerImageInput">
                            <svg class="icon" aria-hidden="true">
                                <use xlink:href="#icon-tupian1"></use>
                            </svg>
                        </el-icon>
                        <input ref="imageInput" type="file" accept="image/*" style="display:none"
                            @change="handleImageChange" />
                        <V3Emoji @click-emoji="onEmojiSelect" :recent="true"></V3Emoji>
                    </div>
                    <el-input type="textarea" v-model="draft" placeholder="输入消息..." rows="2" style="flex:1"
                        @keydown="handleInputKeydown" />
                </div>
                <!-- 添加发送按钮 -->
                <!-- <el-button type="primary" @click="send">发送</el-button> -->
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick, watch, onUnmounted } from 'vue'
import ChatRecord from '@/components/ChatRecord/index.vue'
import UserCard from '@/components/UserCard/index.vue'
import UserMessage from '@/components/UserMessage/index.vue'
import mihoutai from '@/assets/images/mihoutai.png'
import V3Emoji from "vue3-emoji";
import { getUserList, send_message, get_messages } from '@/api/chat'
import { useRoute } from 'vue-router'
import { uploadFile } from '@/api/upload'
import { ElMessage } from 'element-plus'

const route = useRoute()

// 好友列表数据
const userList = ref([
    { user_id: 'u1', user_name: '张三', user_avatar: '' },
    { user_id: 'u2', user_name: '李四', user_avatar: '' },
    { user_id: 'u3', user_name: '王五', user_avatar: '' },
])

const activeUser = ref({})
const messages = ref([])
const draft = ref('')
const imageInput = ref(null)
const chatBody = ref(null)

// 发送者信息
const sendeInfo = reactive({
    userInfo: { user_id: '', user_name: '', user_avatar: '' },
    robotInfo: { wx_id: '', head_url: '' }
})

// 消息分页查询参数
const msgQuery = reactive({
    page: 1,
    page_size: 190,
    app_id: route.query.app_id,
    user_id: ''
})

// 状态变量
const loadingMore = ref(false)
const noMoreMessages = ref(false)
const isAutoScroll = ref(true) // 是否自动滚动到底部
const messageTimer = ref(null) // 定时器实例

// 选择用户
const onSelectUser = (id) => {
    const u = userList.value.find((it) => it.user_id == id)
    if (u) {
        userList.value.forEach((it) => (it.active = it.user_id === id))
        activeUser.value = u
        sendeInfo.userInfo = { user_id: u.user_id, user_name: u.user_name, user_avatar: u.user_avatar }
        sendeInfo.robotInfo = { wx_id: 'robot', head_url: mihoutai }

        // 重置消息列表和分页
        messages.value = []
        msgQuery.page = 1
        msgQuery.user_id = u.user_id
        noMoreMessages.value = false

        // 保持原有行为：先滚动到底部再加载（不 await），以免改变用户可感知的交互顺序
        scrollToBottom()
        getMessages()

        // 重启定时器
        restartMessageTimer()
    }
}


let msgTotal = 0
// 获取消息（区分加载历史和最新消息）
// isHistory: 是否为向上翻页加载历史
// pageOverride: 可选的临时 page 值（不会修改 msgQuery.page），用于定时拉取最新时使用 page=1
const getMessages = async (isHistory = true, pageOverride = null) => {
    if (loadingMore.value) return
    if (isHistory && noMoreMessages.value) return
    if (!msgQuery.user_id) return

    loadingMore.value = true
    const queryPage = pageOverride ?? msgQuery.page
    const query = { ...msgQuery, page: queryPage }

    try {
        const res = await get_messages({ ...query })
        msgTotal = res.total || 0
        const list = res.list || []

        if (list.length > 0) {
            const newMessages = list.map(item => {
                try { item.content = JSON.parse(item.content) } catch (e) { /* keep original */ }
                return item
            })

            if (isHistory) {
                // 在向上加载历史时，需要在 prepend 前记录 scrollHeight 以便恢复视图位置
                const el = chatBody.value
                const prevScrollHeight = el ? el.scrollHeight : 0

                if (queryPage === 1) {
                    // 第一次加载（第一页）直接替换
                    messages.value = newMessages
                } else {
                    // 向上翻页，prepend
                    messages.value = [...newMessages, ...messages.value]
                    // 等待 DOM 更新后恢复滚动位置，避免跳动
                    await nextTick()
                    if (el) {
                        // 保持用户看到原来位置（新内容高度增加导致的偏移）
                        el.scrollTop = el.scrollHeight - prevScrollHeight
                    }
                }
            } else {
                // 拉取最新消息（追加到末尾），避免重复
                const existIds = new Set(messages.value.map(m => m.id || m._id))
                const unique = newMessages.filter(m => !(existIds.has(m.id || m._id)))
                if (unique.length) messages.value = [...messages.value, ...unique]
            }

            // 使用 total 判断是否还有更多历史消息（仅在已知 total 时判断）
            if (msgTotal && isHistory) {
                noMoreMessages.value = messages.value.length >= msgTotal
            } else if (list.length < msgQuery.page_size && isHistory) {
                // 如果后端没有 total，退回到 page_size 判断
                noMoreMessages.value = true
            }

            // 非历史加载且处于自动滚动状态时滚到底部
            if (!isHistory && isAutoScroll.value) {
                await scrollToBottom()
            }
        } else if (isHistory) {
            noMoreMessages.value = true
        }
    } catch (err) {
        // 可扩展错误处理
    } finally {
        loadingMore.value = false

        // 如果是向上翻页（非第一页）并且 prepend 后视图仍然靠近顶部，自动继续翻页
        try {
            if (isHistory && queryPage !== 1) {
                await nextTick()
                const el2 = chatBody.value
                const nearTop = el2 ? el2.scrollTop <= 50 : false
                if (nearTop && !noMoreMessages.value) {
                    // 继续加载下一页历史（递增 page）
                    msgQuery.page = msgQuery.page + 1
                    await getMessages(true)
                }
            }
        } catch (e) {
            // 忽略自动加载中的错误，保持用户可见性
        }
    }
}

// 滚动事件处理
const handleScroll = (e) => {
    const { scrollTop, scrollHeight, clientHeight } = e.target
    const isNearBottom = scrollHeight - scrollTop - clientHeight < 50 // 距离底部小于50px视为在底部

    // 更新自动滚动状态
    isAutoScroll.value = isNearBottom

    // 控制定时器
    if (isNearBottom && !messageTimer.value && msgQuery.user_id) {
        // 在底部且无定时器，启动定时器
        startMessageTimer()
    } else if (!isNearBottom && messageTimer.value) {
        // 不在底部且有定时器，停止定时器
        stopMessageTimer()
    }

    // 滚动到顶部时加载更多历史消息
    if (scrollTop <= 0 && !loadingMore.value && !noMoreMessages.value) {
        loadMoreMessages()
    }
}

// 加载更多历史消息
const loadMoreMessages = () => {
    if (msgQuery.user_id && !loadingMore.value && !noMoreMessages.value) {
        msgQuery.page++
        getMessages(true)
    }
}

// 发送消息
const send = () => {
    if (!activeUser.value.user_id) {
        ElMessage({ type: 'warning', message: '请先选择一个联系人' })
        return
    }
    if (!draft.value) return
    
    const content = draft.value
    const id = Date.now() + Math.random()
    const msg = {
        _id: id,
        _sending: true,
        _failed: false,
        sender_name: '机器人',
        msg_type: 0,
        content: { messages: content },
        send_time: '刚刚',
        "sender_id": "888888",
        "sender_name": "平台",
        "msg_type": 1
    }
    messages.value.push(msg)
    draft.value = ''
    
    // 发送后强制滚动到底部并设置自动滚动状态
    scrollToBottom()
    isAutoScroll.value = true
    
    // 发送到服务器
    send_message({
        app_id: route.query.app_id,
        content: JSON.stringify({
            messages: content
        }),
        msg_type: 1,
        to_user_id: activeUser.value.user_id
    }).then(() => {
        msg._sending = false
        msg._failed = false
    }).catch(() => {
        msg._sending = false
        msg._failed = true
        ElMessage({ type: 'error', message: '消息发送失败' })
    })
}

// 键盘事件处理
const handleInputKeydown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault()
        send()
    }
}

// 图片上传相关
const triggerImageInput = () => {
    imageInput.value && imageInput.value.click()
}

const handleImageChange = (e) => {
    const file = e.target.files[0]
    if (!file) return
    
    // 本地预览
    const url = URL.createObjectURL(file)
    const id = Date.now() + Math.random()
    const msg = {
        _id: id,
        _sending: true,
        _failed: false,
        sender_id: '888888',
        sender_name: '平台',
        msg_type: 2,
        content: { messages: url },
        send_time: '刚刚'
    }
    messages.value.push(msg)
    e.target.value = ''
    
    // 滚动到底部
    setTimeout(() => scrollToBottom(), 100)
    isAutoScroll.value = true
    
    // 上传文件
    const form = new FormData()
    form.append('file', file)
    form.append('app_id', route.query.app_id)
    form.append('msg_type', 2)
    form.append('to_user_id', activeUser.value.user_id)
    uploadFile(form, import.meta.env.VITE_APP_BASE_API + 'admin/upload/image').then((resp) => {
        send_message({
            app_id: route.query.app_id,
            content: JSON.stringify({ messages: import.meta.env.VITE_APP_BASE_API + resp.preview_image_url }),
            msg_type: 2,
            to_user_id: activeUser.value.user_id
        }).then(() => {
            msg._sending = false
            msg._failed = false
        }).catch(() => {
            msg._sending = false
            msg._failed = true
            ElMessage({ type: 'error', message: '图片发送失败' })
        })
    })
}

// 重发消息
const handleRetry = (id) => {
    const msg = messages.value.find((m) => m._id === id)
    if (!msg) return
    
    msg._failed = false
    msg._sending = true
    
    if (msg.msg_type === 0) {
        send_message({ 
            app_id: route.query.app_id, 
            content: msg.content.content, 
            msg_type: 1, 
            to_user_id: activeUser.value.user_id 
        }).then(() => { 
            msg._sending = false 
        }).catch(() => { 
            msg._sending = false; 
            msg._failed = true; 
            ElMessage({ type: 'error', message: '重发失败' }) 
        })
    } else if (msg.msg_type === 2) {
        const form = new FormData()
        form.append('file', msg.content.file)
        form.append('app_id', route.query.app_id)
        form.append('msg_type', 2)
        form.append('to_user_id', activeUser.value.user_id)
        send_message(form).then(() => { 
            msg._sending = false 
        }).catch(() => { 
            msg._sending = false; 
            msg._failed = true; 
            ElMessage({ type: 'error', message: '重发失败' }) 
        })
    }
}

// 滚动到底部
const scrollToBottom = async () => {
    await nextTick()
    const el = chatBody.value
    if (!el) return
    try {
        el.scrollTop = el.scrollHeight
    } catch (e) {
        // 忽略错误
    }
}

// 表情选择
const onEmojiSelect = (emoji) => {
    draft.value = (draft.value || '') + emoji
}

// 获取用户列表
const params = reactive({
    page: 1,
    page_size: 20,
    app_id: route.query.app_id
})

const getUsers = (append = false) => {
    getUserList(params).then((res) => {
        if (append) {
            userList.value = userList.value.concat(res.list || [])
        } else {
            userList.value = res.list || []
        }
        // 首次加载且没有选中用户时，默认选中第一个
        if (!append && userList.value.length && !activeUser.value.user_id) {
            onSelectUser(userList.value[0].user_id)
        }
    })
}

// 加载更多用户
const onLoadUserList = async () => {
    params.page = params.page + 1
    await getUsers(true)
    await nextTick()
    const el = document.querySelector('.left-panel .infinite-list')
    if (el) {
        el.scrollTop = el.scrollHeight
    }
}

// 定时器相关函数
const startMessageTimer = () => {
    // 清除现有定时器
    if (messageTimer.value) {
        clearInterval(messageTimer.value)
    }

    // 每秒获取一次最新消息，不修改 msgQuery.page，使用 pageOverride=1
    messageTimer.value = setInterval(() => {
        if (!msgQuery.user_id) return
        getMessages(false, 1)
    }, 1000)
}

const stopMessageTimer = () => {
    if (messageTimer.value) {
        clearInterval(messageTimer.value)
        messageTimer.value = null
    }
}

const restartMessageTimer = () => {
    stopMessageTimer()
    if (msgQuery.user_id) {
        startMessageTimer()
    }
}

// 组件挂载时
onMounted(() => {
    getUsers()
    
    // 监听窗口关闭，清理定时器
    window.addEventListener('beforeunload', stopMessageTimer)
})

// 组件卸载时清理定时器
onUnmounted(() => {
    stopMessageTimer()
})

// 监听活跃用户变化，重启定时器
watch(activeUser, (newVal) => {
    if (newVal.user_id) {
        restartMessageTimer()
    } else {
        stopMessageTimer()
    }
})
</script>

<style scoped lang="scss">
.chat-page {
    display: flex;
    height: calc(100vh - 64px);
}

:deep(.el-textarea__inner) {
    background-color: transparent;
    padding-left: 8px !important;
}

.left-panel {
    width: 280px;
    border-right: 1px solid var(--el-border-color);
    background: var(--el-bg-color);
    display: flex;
    flex-direction: column;
}

.left-header {
    height: 60px;
    line-height: 60px;
    padding: 0 16px;
    font-weight: 600;
}

.right-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.chat-header {
    height: 64px;
    display: flex;
    align-items: center;
    padding: 0 16px;
    border-bottom: 1px solid var(--el-border-color);
}

.chat-header .avatar {
    width: 40px;
    height: 40px;
    margin-right: 12px;
}

.chat-body {
    flex: 1;
    padding: 16px;
    overflow: auto;
    background: #f5f7fa;
}

// 加载更多样式
.loading-more {
    text-align: center;
    padding: 10px;
    color: #666;
    font-size: 14px;
}

.chat-footer {
    height: 96px;
    padding: 5px 15px;
    border-top: 1px solid var(--el-border-color);
    display: flex;
    align-items: center;
    gap: 10px;
    padding-top: 10px;
}

.chat-footer .footer-left {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.chat-footer .el-button {
    height: 40px;
    align-self: flex-end;
}

.chat-footer .actions {
    display: flex;
    align-items: center
}
</style>