<template>
    <div class="chatbox" v-show="isShow">
        <el-button type="primary" plain class="clear-btn" @click="handleClear">
            <SvgIcon name="elementDelete" />
        </el-button>
        <div class="messages">
            <div v-for="(msg, index) in messages" :key="index" class="message">
                <div v-if="msg.key == 0" class="message-sender">
                    <div><span>{{ msg.text }}</span> </div>
                </div>
                <div v-else class="message-receiver">
                    <div v-show="msg.text ? msg.text : curGetMsg"><span
                            v-html="msg.text ? marked(msg.text) : curGetMsg ? marked(curGetMsg) : ''"></span>
                    </div>
                </div>
            </div>
        </div>
        <div class="input-area">
            <textarea v-model="newMessage" placeholder="输入消息..."></textarea>
            <el-button type="primary" @click="sendMessage">发送</el-button>
        </div>
    </div>
</template>

<script>
import { reactive, ref, toRefs } from 'vue';
import { marked } from 'marked';

export default {
    props: {
        isShow: {
            type: Boolean,
            default: false,
        }
    },
    setup() {
        const messages = ref([]);
        const newMessage = ref('');
        const state = reactive({
            curGetMsg: '',
            marked,
        })

        const handleClear = () => {
            messages.value = [];
        }

        const sendMessage = () => {
            if (newMessage.value.trim()) {
                messages.value.push({ text: newMessage.value, key: 0 });
                // 发送消息到服务器


                const ctx = []
                let tempObj
                messages.value.length > 1 && messages.value.forEach((msg) => {
                    if (msg.key == 0) {
                        tempObj = { question: msg.text, answer: '' }
                    }
                    if (msg.key == 1) {
                        tempObj.answer = msg.text
                        ctx.push(tempObj)
                    }
                })

                const postData = ctx.length ? { prompt: newMessage.value, stream: 1, context: ctx } : { prompt: newMessage.value, stream: 1 };
                const url = '/api/utils/aigc';
                const options = {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(postData)
                };
                fetch(url, options)
                    .then(response => {
                        if (response.headers.get('Content-Type').includes('text/event-stream')) {
                            const reader = response.body.getReader();
                            return new ReadableStream({
                                start(controller) {
                                    function push() {
                                        reader.read().then(({ done, value }) => {
                                            if (done) {
                                                controller.close();
                                                messages.value.forEach((msg) => {
                                                    if (msg.key == 1 && msg.text == '') {
                                                        msg.text = state.curGetMsg;
                                                        state.curGetMsg = '';
                                                    }
                                                })
                                                return;
                                            }
                                            const dataChunks = new TextDecoder().decode(value).split('\n\n');
                                            dataChunks.forEach(chunk => {
                                                if (chunk.includes('data:')) {
                                                    const jsonData = chunk.split('data: ')[1];
                                                    // 在这里处理解析后的JSON数据
                                                    state.curGetMsg += jsonData;
                                                    controller.enqueue(jsonData);
                                                }
                                            });
                                            push();
                                        }).catch(error => {
                                            console.error('读取流时出错:', error);
                                            controller.error(error);
                                        });
                                    }
                                    push();
                                },
                            });

                        } else {
                            // 如果不是 text/event-stream 格式，按照常规方式处理响应
                            return response.json();
                        }
                    })
                    .catch(error => console.error('请求出错:', error));
                newMessage.value = '';
                messages.value.push({ key: 1, text: '' });
            }
        };

        return {
            messages,
            newMessage,
            sendMessage,
            handleClear,
            ...toRefs(state)
        };
    },
};
</script>

<style scoped>
.chatbox {
    padding: 10px;
    padding-top: 30px;
    width: 30%;
    height: 468px;
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 20%;
    right: 100px;
    background: #fff;
    border-radius: 6px;
    box-shadow: 0px 3px 20px #ccc;
    z-index: 9999;
}

.clear-btn {
    position: absolute;
    top: 10px;
    right: 10px;
}


.clear-btn {
    position: absolute;
    top: 10px;
    right: 10px;
}

.messages {
    flex: 1;
    overflow-y: auto;
    margin-bottom: 10px;
}

.message {
    margin: 5px 0;
}

.input-area {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

textarea {
    padding: 10px;
    width: 100%;
    border: none;
    /* 取消textarea右下角控制工具 */
    resize: none;
}

.message-sender,
.message-receiver {
    display: flex;
    margin-bottom: 20px;
}

.message-sender {
    justify-content: flex-end;
}

.message-sender>div,
.message-receiver>div {
    border-radius: 6px;
    padding: 10px;
    line-height: 27px;
}

.message-sender>div {
    background: #dce2ff;
}

.message-receiver>div {
    background: #e9e8ed;
}
</style>