<template>
    <div class="flex flex-col session" style="height: 100vh">
        <div class="py-2 px-3 text-black text-center shrink-0 doc-nav-bar">
            <span @click="onBack" class="text-12 back-bt" v-if='showNav()'>
                <doc-icon type="doc-left2" />
            </span>
            <span>{{ targetName }}</span>
        </div>
        <div class="p-3 grow overflow-y-auto content">
            <van-list
                v-model:loading="loading"
                :finished="finished"
                finished-text="没有更多消息了"
                direction="up"
                :disabled="scrollDisabled"
                @load="loadHistory"
            >
                <div v-for="item in msgs" :key="item.time"
                    :class="['flex msg-row', item.from === accountId ? 'self' : 'target']">
                    <div class="shrink-0 avatar">
                        <img src="@/assets/image/residentWX/avatar-doctor.svg" alt="" v-show="item.from !== accountId">
                    </div>
                    <div class="msg-cont">
                        <span v-if="item.type === 'text'" style="white-space: pre-wrap;">{{ item.text }}</span>
                        <FileView v-else-if="['image', 'file'].includes(item.type)" :file="item.file"
                            @viewImage="viewImage"/>
                    </div>
                    <div class="shrink-0 avatar">
                        <div v-show="item.from === accountId">
                            <img src="@/assets/image/residentWX/avatar-woman.png" alt="" v-if="targetGender == 2">
                            <img src="@/assets/image/residentWX/avatar-man.png" alt="" v-else>
                        </div>
                    </div>
                </div>
            </van-list>
            <div ref="bottom"></div>
        </div>
        <div class="shrink-0 px-3 py-2 footer">
            <van-field type="textarea" rows="1"
                :autosize="{ minHeight: 24, maxHeight: 76 }"
                maxlength="500"
                v-model="inputValue"
                center
            >   
                <template #left-icon>
                    <div style="color: #555; font-size: .2rem" class="mr-1"
                        @click="() => visible = true">
                        <doc-icon type="plus-circle"/>
                    </div>
                </template>
                <template #button>
                    <van-button size="small" type="primary"
                        @click="sendMsg">发送</van-button>
                </template>
            </van-field>
        </div>
        <input type="file"
            :accept="sendType == 'image' ? '.jpg,.jpeg,.png,.gif' : '*'"
            ref="fileElem"
            style="display: none;"
            @change="handleFiles"
            :key="inputKey">
        
        <van-action-sheet
            v-model:show="visible"
            :actions="actionsList"
            cancel-text="取消"
            close-on-click-action
            @select="fileSelect"
        />
    </div>
</template>

<script>
import { useStore } from '@/residentWX/store'
import NIM from '@yxim/nim-web-sdk/dist/SDK/NIM_Web_NIM.js'
import { showNotify, showToast, showImagePreview, showSuccessToast, showFailToast  } from 'vant'
import { getAccount } from '@/api/residentWX/nim.js'
import FileView from './FileView.vue'

// 6c51376a55f54b2fa586d7b4c85757f8
const APPKEY = '8cee1ccf8ab46779976091db68a67955'

export default {
    components: {
        FileView
    },
    inject:['showNav'],
    data() {
        return {
            store: useStore(),
            accountId: '',
            token: '',
            msgs: [],
            // 输入的信息
            inputValue: '',
            // 是否已连接
            isConnect: false,
            // 加载聊天记录
            loading: false,
            // 是否加载完成
            finished: false,
            scrollDisabled: true,
            // image file
            sendType: 'image',
            inputKey: 1,
            // 上传功能面板
            visible: false,
            actionsList: [
                { name: '上传图片', type: 'image' },
                { name: '上传文件', type: 'file' }
            ]
        }
    },
    setup() {
        return {
            nim: null
        }
    },
    computed: {
        userInfo() {
            return this.store.userInfo
        },
        // 聊天对象
        targetName() {
            return this.$route.query.name
        },
        // 聊天对象性别
        targetGender() {
            return this.$route.query.gender
        },
        targetId() {
            return `doc_${this.$route.params.id}`.toLocaleLowerCase()
        }
    },
    created() {
        this.init()
    },
    methods: {
        init() {
            getAccount(this.userInfo.idCard).then(res => {
                console.log('getAccount ===========>', res)
                const result = res.data || {}
                this.accountId = result.accountId
                this.token = result.yunxinToken
                this.connect()
            })
        },
        // 连接到im服务
        connect() {
            if (!this.accountId || !this.token) {
                showNotify({ type: 'warning', message: '聊天服务连接失败', duration: 0 })
                return 
            }
            this.isConnect = false
            this.finished = false
            this.nim = NIM.getInstance({
                debug: false,
                appKey: APPKEY,
                account: this.accountId,
                token: this.token,
                onconnect: () => {
                    console.log('连接成功 ================>')
                    this.isConnect = true
                    this.getLocalMsgs()
                    this.toBottom('instant')
                    setTimeout(() => {
                        // 开启滚动加载
                        this.scrollDisabled = false
                    }, 1000);
                },
                onwillreconnect: (obj) => {
                    console.log('即将重连')
                    console.log(obj.retryCount)
                    console.log(obj.duration)
                },
                ondisconnect: (error) => {
                    // showNotify({ type: 'warning', message: '连接失败', duration: 0 })
                    console.warn('连接失败 ===============>')
                },
                onmsg: (msg) => {
                    console.log('收到新消息===========>', msg);
                    if (msg.from === this.targetId) {
                        this.msgs.push(msg)
                        this.toBottom()
                    }
                },
                onofflinemsgs: (obj) => {
                    console.log('收到离线消息===========>', obj);
                    if (obj.to === this.targetId) {
                        this.msgs.push(...obj.msgs)
                        this.toBottom()
                    }
                }
            })
        },
        // 发送信息
        sendMsg() {
            if (!this.inputValue) {
                showToast('不能发送空消息')
                return
            }
            if (!this.nim) return
            let msg = this.nim.sendText({
                scene: 'p2p',
                to: this.targetId,
                text: this.inputValue,
                done: function sendMsgDone (error, msg) {
                    console.log('sendText ================>', error, msg)
                }
            })
            this.pushMsg(msg)
            this.inputValue = ''
        },
        pushMsg(msg) {
            this.msgs.push(msg)
            this.toBottom()
        },
        toBottom(behavior = 'smooth') {
            const dom = this.$refs.bottom
            setTimeout(() => {
                dom && dom.scrollIntoView({block: 'start', behavior})
            }, 300)
        },
        // 加载本地消息
        getLocalMsgs() {
            const msg = this.msgs[0] || {}
            this.loading = true
            this.nim.getLocalMsgs({
                sessionId: `p2p-${this.targetId}`,
                limit: 40,
                end: msg.time,
                done: (error, obj) => {
                    // console.log('获取本地消息' + (!error?'成功':'失败'), error, obj)
                    const msgs = obj.msgs || []
                    this.loading = false
                    if (!msgs.length) {
                        this.finished = true
                        return
                    }
                    msgs.sort((a, b) => {
                        return a.time - b.time
                    })
                    this.msgs = msgs.concat(this.msgs)
                }
            })
        },
        loadHistory() {
            this.getLocalMsgs()
        },
        handleFiles() {
            let files = this.$refs['fileElem'].files
            if (files.length <= 0) {
                this.$message.info('未选中文件，请尝试重新选择')
                return
            }
            if (files[0].size / 1024 / 1024 > 100) {
                this.$message.info('文件大小不能超过100M')
                return
            }
            this.upload(files[0])
        },
        upload(file, hash) {
            if (!this.nim) return
            // 先上传再发送
            const tempMsg = {
                from: this.accountId,
                text: '上传中...',
                time: +new Date(),
                percentage: 0,
                type: 'text'
            }
            this.pushMsg(tempMsg)
            this.nim.previewFile({
                type: this.sendType,
                blob: file,
                // fastPass: { md5: hash },
                uploadprogress: function(obj) {
                    console.log('文件总大小: ' + obj.total + 'bytes');
                    console.log('已经上传的大小: ' + obj.loaded + 'bytes');
                    console.log('上传进度: ' + obj.percentage);
                    console.log('上传进度文本: ' + obj.percentageText);
                    tempMsg.percentage = obj.percentage
                },
                done: (error, file) => {
                    this.inputKey = Math.random().toString(16).substring(2, 6)
                    if (!error) {
                        const msg = this.nim.sendFile({
                            scene: 'p2p',
                            to: this.targetId,
                            file: file
                        })
                        console.log('正在发送p2p image消息, id=' + msg.idClient)
                        this.pushMsg(msg)
                        this.msgs = this.msgs.filter(e => e.time !== tempMsg.time)
                    } else {
                        const msg = this.nim.sendText({
                            scene: 'p2p',
                            to: this.targetId,
                            text: '文件上传失败！',
                            isLocal: true,
                            custom: { type: 'file', status: 'fail' }
                        })
                        this.pushMsg(msg)
                    }
                }
            })

        },
        fileSelect(action) {
            this.sendType = action.type
            const dom = this.$refs['fileElem']
            setTimeout(() => {
                dom && dom.click()
            }, 100)
        },
        // 图片查看
        viewImage(file) {
            const currt = file.url
            const tempList = this.msgs.filter(e => ['file', 'image'].includes(e.type)).map(e => e.file)
            const imageList = []
            tempList.forEach(e => {
                const array = ['JPG', 'PNG', 'JEPG', 'GIF']
                if (array.includes(e.type) || array.includes(e.ext.toLocaleUpperCase())) {
                    imageList.push(e.url)
                }
            })
            console.log('imageList', imageList)
            const index = imageList.indexOf(currt) || 0
            showImagePreview({
                images: imageList,
                startPosition: index,
                closeable: true
            })
        },
        clearMsg() {
            this.nim.deleteLocalMsgsBySession({
                scene: 'p2p',
                to: this.targetId,
                delLastMsg: true,
                done: (error) => {
                    if (error) {
                        showFailToast('删除失败')
                    } else {
                        showSuccessToast('删除成功')
                        this.msgs = []
                    }
                }
            });
        },
        clearAllMsg() {
            this.nim.deleteAllLocalMsgs({
                done: (error) => {
                    if (error) {
                        showFailToast('删除失败')
                    } else {
                        showSuccessToast('删除成功')
                    }
                }
            })
        },
        onBack() {
            this.$router.replace({ name: 'residentWX-nim' })
        }
    },
    beforeUnmount() {
        if (this.nim) {
            this.nim.destroy({
                done: function (err) {
                    console.log('nim 断开连接')
                }
            })
        }
        
    }
}
</script>

<style lang="less" scoped>
@import url('../utils/common.less');

.footer {
    border-top: 1px solid #3C3C431C;
    background-color: #eeeeee66;
    .van-cell {
        padding: 0;
        background: transparent;
    }
}
.content {
    background-color: #f5f5f5;
    .msg-row {
        align-items: flex-start;
        margin-bottom: 12px;
    }
    .msg-cont {
        display: inline-block;
        
        line-height: 1.5;
        padding: 8px;
        border-radius: 4px;
        position: relative;
        word-break: break-all;
        &::before {
            content: '';
            display: inline-block;
            width: 4px;
            height: 4px;
            transform: rotate(45deg);
            position: absolute;
            right: -2px;
            top: 16px;
        }
    }
    .avatar {
        width: 38px;
        img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    }
    .self {
        justify-content: flex-end;
        .msg-cont {
            margin-right: 12px;
            background-color: #91d5ff;
            &::before {
                right: -2px;
                background-color: #91d5ff;
            }
        }
    }
    .target {
        justify-content: flex-start;
        .msg-cont {
            margin-left: 12px;
            background-color: #fff;
            &::before {
                left: -2px;
                background-color: #fff;
            }
        }
    }
}
</style>
