/**
 * ChatGPT工具
 * @author zhaoxianlie
 */

import AI from './fh.ai.js';

new Vue({
    el: '#pageContainer',
    data: {
        prompt: '',
        demos: [
            '用Js写一个冒泡排序的Demo',
            'Js里的Fetch API是怎么用的',
            '帮我写一个单网页版的俄罗斯方块游戏',
            '我开发了一个浏览器插件，是专门为HR自动找简历的，现在请你帮我用SVG绘制一个插件的ICON，不需要问我细节，直接生成'
        ],
        initMessage: {
            id:'id-test123',
            sendTime:'2022/12/20 12:12:12',
            message: '你好，可以告诉我你是谁吗？我该怎么和你沟通？',
            respTime: '2022/12/20 12:12:13',
            respContent: '你好，我是FeHelper智能助理，由OpenAI提供技术支持；你可以在下面的输入框向我提问，我会尽可能回答你~~~'
        },
        respResult:{
            id: '',
            sendTime:'',
            message:'',
            respTime:'',
            respContent:''
        },
        currentSession: [],
        history:[],
        tempId:'',
        hideDemo: false,
        undergoing: false,
        messages: [],
        showHistoryPanel: false
    },
    computed: {
        groupedHistory() {
            // 按日期分组，主题为message前20字
            const groups = {};
            this.history.forEach(item => {
                const date = item.sendTime ? item.sendTime.split(' ')[0] : '未知日期';
                if (!groups[date]) groups[date] = [];
                groups[date].push({
                    ...item,
                    theme: item.message ? item.message.slice(0, 20) : ''
                });
            });
            return groups;
        }
    },
    watch: {
        history: {
            handler(val) {
                localStorage.setItem('fh-aiagent-history', JSON.stringify(val));
            },
            deep: true
        }
    },
    mounted: function () {
        this.$refs.prompt.focus();
        this.hideDemo = !!(new URL(location.href)).searchParams.get('hideDemo');
        // 加载本地历史
        const local = localStorage.getItem('fh-aiagent-history');
        if(local){
            try {
                this.history = JSON.parse(local);
            } catch(e) {}
        }
        this.loadPatchHotfix();
    },
    methods: {

        loadPatchHotfix() {
            // 页面加载时自动获取并注入页面的补丁
            chrome.runtime.sendMessage({
                type: 'fh-dynamic-any-thing',
                thing: 'fh-get-tool-patch',
                toolName: 'aiagent'
            }, patch => {
                if (patch) {
                    if (patch.css) {
                        const style = document.createElement('style');
                        style.textContent = patch.css;
                        document.head.appendChild(style);
                    }
                    if (patch.js) {
                        try {
                            if (window.evalCore && window.evalCore.getEvalInstance) {
                                window.evalCore.getEvalInstance(window)(patch.js);
                            }
                        } catch (e) {
                            console.error('aiagent补丁JS执行失败', e);
                        }
                    }
                }
            });
        },

        // 这个代码，主要用来判断大模型返回的内容是不是包含完整的代码块
        validateCodeBlocks(content) {
            let backticksCount = 0;
            let inCodeBlock = false;
            let codeBlockStartIndex = -1;
        
            for (let i = 0; i < content.length; i++) {
                // 检查当前位置是否是三个连续的反引号
                if (content.startsWith('```', i)) {
                    backticksCount++;
                    i += 2; // 跳过接下来的两个字符，因为它们也是反引号的一部分
        
                    // 如果我们遇到了奇数个反引号序列，那么我们进入了代码块
                    if (backticksCount % 2 !== 0) {
                        inCodeBlock = true;
                        codeBlockStartIndex = i - 2;
                    } else { // 否则，我们离开了代码块
                        inCodeBlock = false;
                        if (codeBlockStartIndex === -1 || codeBlockStartIndex > i) {
                            return false; // 这意味着有不匹配的反引号
                        }
                        codeBlockStartIndex = -1;
                    }
                }
            }
        
            // 如果最终 backticksCount 是偶数，则所有代码块都正确关闭
            return backticksCount % 2 === 0 && !inCodeBlock;
        },

        sendMessage(prompt){
            if(this.undergoing) return;
            if(this.respResult.id){
                // 先存储上一轮对话到历史
                this.history.push({
                    id: this.respResult.id,
                    sendTime: this.respResult.sendTime,
                    message: this.respResult.message,
                    respTime: this.respResult.respTime,
                    respContent: this.respResult.respContent
                });
            }

            this.undergoing = true;
            let sendTime = (new Date()).format('yyyy/MM/dd HH:mm:ss');
            this.$nextTick(() => {
                this.scrollToBottom();
            });

            this.tempId = '';
            let respContent = '';

            // 1. 先把用户输入 push 到 messages
            this.messages.push({ role: 'user', content: prompt });
            // 新增：用户消息push到currentSession
            this.currentSession.push({
                role: 'user',
                id: 'user-' + Date.now(),
                time: sendTime,
                content: prompt
            });

            AI.askCoderLLM(this.messages, (respJson, done) => {
                if(done){
                    this.undergoing = false;
                    if(this.respResult.id && this.respResult.respContent){
                        const tempDiv = document.createElement('div');
                        tempDiv.innerHTML = this.respResult.respContent;
                        const plainText = tempDiv.textContent || tempDiv.innerText || '';
                        this.messages.push({ role: 'assistant', content: plainText });
                        this.history.push({
                            id: this.respResult.id,
                            sendTime: this.respResult.sendTime,
                            message: this.respResult.message,
                            respTime: this.respResult.respTime,
                            respContent: this.respResult.respContent
                        });
                    }
                    this.$nextTick(() => {
                        document.querySelectorAll('.x-xcontent pre code').forEach((block) => {
                            hljs.highlightBlock(block);
                            insertCodeToolbar(block);
                        });
                        this.scrollToBottom();
                    });
                    return;
                }
                let id = respJson.id;
                let rawContent = respJson.content || '';
                // 检查多轮代码补全场景
                const lastAssistantMsg = this.currentSession.slice().reverse().find(m => m.role === 'assistant');
                const lastIsCodeBlock = lastAssistantMsg && /```\s*$/.test(lastAssistantMsg.content.trim());
                const thisIsCodeBlock = /^```/.test(rawContent.trim());
                if (lastIsCodeBlock && !thisIsCodeBlock) {
                    rawContent = '```js\n' + rawContent.trim() + '\n```';
                }
                respContent = rawContent;
                if(!this.validateCodeBlocks(respContent)) {
                    respContent += '\n```';
                }
                respContent = marked(respContent);
                if(this.tempId !== id) {
                    this.tempId = id;
                    let dateTime = new Date(respJson.created * 1000);
                    let respTime = dateTime.format('yyyy/MM/dd HH:mm:ss');
                    this.respResult = { id,sendTime,message:prompt,respTime,respContent };
                    // 新增：助手回复push到currentSession
                    this.currentSession.push({
                        role: 'assistant',
                        id,
                        time: respTime,
                        content: respContent
                    });
                }else{
                    this.respResult.respContent = respContent;
                    // 更新最后一条助手消息内容
                    if(this.currentSession.length && this.currentSession[this.currentSession.length-1].role==='assistant'){
                        this.currentSession[this.currentSession.length-1].content = respContent;
                    }
                }
                this.$nextTick(() => this.scrollToBottom());
            });            
        },

        scrollToBottom(){
            this.$refs.boxResult.scrollTop = this.$refs.boxResult.scrollHeight;
        },
        goChat(){
            this.sendMessage(this.prompt);
            this.$nextTick(() => this.prompt='');
        },

        openOptionsPage: function(event) {
            event.preventDefault();
            event.stopPropagation();
            chrome.runtime.openOptionsPage();
        },

        openDonateModal: function(event ){
            event.preventDefault();
            event.stopPropagation();
            chrome.runtime.sendMessage({
                type: 'fh-dynamic-any-thing',
                thing: 'open-donate-modal',
                params: { toolName: 'aiagent' }
            });
        },

        loadHistory(item) {
            // 渲染到主面板
            this.respResult = {
                id: item.id,
                sendTime: item.sendTime,
                message: item.message,
                respTime: item.respTime,
                respContent: item.respContent
            };
            this.showHistoryPanel = false;
            this.$nextTick(() => this.scrollToBottom());
        },

        startNewChat(event) {
            event && event.preventDefault();
            this.messages = [];
            this.respResult = {
                id: '',
                sendTime: '',
                message: '',
                respTime: '',
                respContent: ''
            };
            this.currentSession = [];
            this.showHistoryPanel = false;
            this.$nextTick(() => {
                this.$forceUpdate();
                this.scrollToBottom();
            });
        },

        onHistoryClick(event) {
            event.preventDefault();
            event.stopPropagation();
            this.showHistoryPanel = !this.showHistoryPanel;
        },

        onPromptKeydown(e) {
            if (e.key === 'Enter') {
                if (e.shiftKey) {
                    // 允许换行
                    return;
                } else {
                    // 阻止默认换行，发送消息
                    e.preventDefault();
                    this.goChat();
                }
            }
        }
    }

});

// 工具函数：复制和运行
function copyCode(code) {
    if (navigator.clipboard) {
        navigator.clipboard.writeText(code);
    } else {
        const textarea = document.createElement('textarea');
        textarea.value = code;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        document.body.removeChild(textarea);
    }
}

// 新增：为代码块插入工具栏
function insertCodeToolbar(block) {
    // 检查是否已插入按钮，避免重复
    if (block.parentNode.querySelector('.fh-code-toolbar')) return;

    // 创建工具栏
    const toolbar = document.createElement('div');
    toolbar.className = 'fh-code-toolbar';
    toolbar.style.cssText = 'position:absolute;bottom:6px;right:12px;z-index:10;display:flex;gap:8px;';

    // 复制按钮
    const btnCopy = document.createElement('button');
    btnCopy.innerText = '复制';
    btnCopy.className = 'fh-btn-copy';
    btnCopy.style.cssText = 'padding:2px 8px;font-size:12px;cursor:pointer;';
    btnCopy.onclick = (e) => {
        e.stopPropagation();
        copyCode(block.innerText);
        // 复制成功反馈
        const oldText = btnCopy.innerText;
        btnCopy.innerText = '已复制';
        btnCopy.disabled = true;
        setTimeout(() => {
            btnCopy.innerText = oldText;
            btnCopy.disabled = false;
        }, 1000);
    };

    // 运行按钮
    const lang = (block.className || '').toLowerCase();
    let btnRun = document.createElement('button');
    btnRun.className = 'fh-btn-run';
    btnRun.style.cssText = 'padding:2px 8px;font-size:12px;cursor:pointer;';
    let shouldAppendBtnRun = true;
    if (lang.includes('lang-javascript') || lang.includes('lang-js')) {
        btnRun.innerText = 'Console运行';
        btnRun.onclick = (e) => {
            e.stopPropagation();
            copyCode(block.innerText);
            btnRun.innerText = '已复制到剪贴板';
            btnRun.disabled = true;
            setTimeout(() => {
                btnRun.innerText = 'Console运行';
                btnRun.disabled = false;
            }, 1200);
            showToast('代码已复制到剪贴板，请按F12打开开发者工具，切换到Console粘贴回车即可运行！');
        };
    } else if (lang.includes('lang-html')) {
        btnRun.innerText = '下载并运行';
        btnRun.onclick = (e) => {
            e.stopPropagation();
            const blob = new Blob([block.innerText], {type: 'text/html'});
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'fehelper-demo.html';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            btnRun.innerText = '已下载';
            btnRun.disabled = true;
            setTimeout(() => {
                btnRun.innerText = '下载并运行';
                btnRun.disabled = false;
            }, 1200);
            showToast('HTML文件已下载，请双击打开即可运行！');
        };
    } else if (lang.includes('lang-xml') || lang.includes('lang-svg')) {
        // 检查内容是否为svg
        const codeText = block.innerText.trim();
        if (/^<svg[\s\S]*<\/svg>$/.test(codeText)) {
            btnRun.innerText = '点击预览';
            btnRun.onclick = (e) => {
                e.stopPropagation();
                // 弹窗预览svg
                const modal = document.createElement('div');
                modal.style.cssText = 'position:fixed;left:0;top:0;width:100vw;height:100vh;background:rgba(0,0,0,0.5);z-index:999999;display:flex;align-items:center;justify-content:center;';
                const inner = document.createElement('div');
                inner.style.cssText = 'background:#fff;width:400px;height:400px;border-radius:10px;box-shadow:0 2px 16px rgba(0,0,0,0.18);position:relative;display:flex;align-items:center;justify-content:center;';
                const closeBtn = document.createElement('button');
                closeBtn.innerText = '×';
                closeBtn.style.cssText = 'position:absolute;top:8px;right:12px;width:32px;height:32px;font-size:22px;line-height:28px;background:transparent;border:none;cursor:pointer;color:#888;z-index:2;';
                closeBtn.onclick = () => document.body.removeChild(modal);
                const img = document.createElement('img');
                img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(codeText)));
                img.alt = 'SVG预览';
                img.style.cssText = 'max-width:90%;max-height:90%;display:block;border:1px solid #eee;background:#fafbfc;';
                inner.appendChild(closeBtn);
                inner.appendChild(img);
                modal.appendChild(inner);
                document.body.appendChild(modal);
            };
        } else {
            btnRun.remove();
            shouldAppendBtnRun = false;
        }
    } else {
        btnRun.remove();
        shouldAppendBtnRun = false;
    }

    toolbar.appendChild(btnCopy);
    if (shouldAppendBtnRun) {
        toolbar.appendChild(btnRun);
    }

    // 让pre相对定位，插入工具栏到底部
    const pre = block.parentNode;
    pre.style.position = 'relative';
    pre.appendChild(toolbar);
}

// 页面内Toast提示
function showToast(msg) {
    let toast = document.createElement('div');
    toast.className = 'fh-toast';
    toast.innerText = msg;
    toast.style.cssText = `
        position:fixed;left:50%;top:80px;transform:translateX(-50%);
        background:rgba(0,0,0,0.85);color:#fff;padding:10px 24px;
        border-radius:6px;font-size:16px;z-index:99999;box-shadow:0 2px 8px rgba(0,0,0,0.2);
        transition:opacity 0.3s;opacity:1;
    `;
    document.body.appendChild(toast);
    setTimeout(() => {
        toast.style.opacity = '0';
        setTimeout(() => document.body.removeChild(toast), 300);
    }, 1800);
}


