/**
 * 聊天数据全量导出器
 * 分页拉取群聊/私聊消息并导出为JSON，零上传
 * 支持：全量导出（不限200条）、日期筛选、搜索会话列表
 */
const fs = require('fs');
const path = require('path');

module.exports = {
    name: '聊天数据导出器',
    description: '全量拉取群聊/私聊消息并导出为JSON，零上传',
    version: '1.0.0-local',

    async init(config, pluginManager) {
        console.log('[ChatExporter] 初始化全量数据导出器...');
        this._pm = pluginManager;
        this._cacheDir = path.join(__dirname, 'cache');
        if (!fs.existsSync(this._cacheDir)) fs.mkdirSync(this._cacheDir, { recursive: true });
        this._instance = { panel: null, isExporting: false };
        this._injectStyles();
        this._observeConversation();
        return this._instance;
    },

    _injectStyles() {
        if (document.querySelector('#chat-exporter-styles')) return;
        const style = document.createElement('style');
        style.id = 'chat-exporter-styles';
        style.textContent = `
            #cep-panel{position:fixed;top:80px;right:20px;width:460px;max-height:85vh;background:#ffffff;border-radius:16px;box-shadow:0 8px 32px rgba(0,0,0,.15);z-index:99999;overflow-y:auto;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC',sans-serif;animation:cep-slide-in .25s ease;}
            @keyframes cep-slide-in{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}
            #cep-panel:hover{box-shadow:0 12px 40px rgba(0,0,0,.2)}
            #cep-panel .cep-header{padding:14px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e5e5e7}
            #cep-panel .cep-header-title{font-weight:700;font-size:17px;color:#1d1d1f}
            #cep-panel .cep-header-close{background:#f0f0f0;border:none;color:#666;width:28px;height:28px;border-radius:50%;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center}
            #cep-panel .cep-header-close:hover{background:#e0e0e0}
            #cep-panel .cep-body{padding:16px 20px}
            #cep-panel .cep-desc{color:#86868b;font-size:13px;line-height:1.5;margin:0 0 14px}
            #cep-panel .cep-form-row{display:flex;gap:12px;margin-bottom:14px}
            #cep-panel .cep-form-label{font-size:13px;color:#1d1d1f;font-weight:500;display:flex;align-items:center;gap:6px}
            #cep-panel .cep-form-input{width:70px;height:32px;border:1.5px solid #d0d0d0;border-radius:8px;padding:0 10px;font-size:13px;outline:none}
            #cep-panel .cep-form-input:focus{border-color:#3478F6}
            #cep-panel .cep-btn{width:100%;height:40px;background:linear-gradient(135deg,#3478F6,#2563EB);color:#fff;border:none;border-radius:10px;font-size:14px;font-weight:600;cursor:pointer;margin-bottom:8px}
            #cep-panel .cep-btn:hover{background:linear-gradient(135deg,#2563EB,#1D4ED8);box-shadow:0 4px 12px rgba(52,120,246,.3)}
            #cep-panel .cep-btn-secondary{background:#f0f0f0;color:#333}
            #cep-panel .cep-btn-secondary:hover{background:#e5e5e5;box-shadow:none}
            #cep-panel .cep-status{margin-top:10px;font-size:13px;color:#86868b;text-align:center;min-height:20px}
            #cep-panel .cep-status.success{color:#34C759}
            #cep-panel .cep-status.error{color:#FF3B30}
            #cep-panel .cep-log{margin-top:10px;max-height:180px;overflow-y:auto;background:#f8f8fa;padding:12px;border-radius:10px;font-size:12px;font-family:'SF Mono',Menlo,Consolas,monospace;white-space:pre-wrap;color:#555;border:1px solid #e5e5e7}
            #cep-panel .cep-conv-list{margin-top:12px;max-height:260px;overflow-y:auto;border:1px solid #e5e5e7;border-radius:10px}
            #cep-panel .cep-conv-search{width:100%;padding:10px 14px;border:none;border-bottom:1px solid #e5e5e7;font-size:13px;outline:none;box-sizing:border-box;border-radius:10px 10px 0 0}
            #cep-panel .cep-conv-item{padding:10px 14px;cursor:pointer;border-bottom:1px solid #f0f0f0;font-size:13px;color:#1d1d1f}
            #cep-panel .cep-conv-item:hover{background:#f0f5ff}
            #cep-panel .cep-conv-type{display:inline-block;padding:1px 6px;border-radius:4px;font-size:11px;font-weight:500;margin-right:6px}
            #cep-panel .cep-conv-type-private{background:#e8f5e9;color:#2e7d32}
            #cep-panel .cep-conv-type-group{background:#e3f2fd;color:#1565c0}
        `;
        document.head.appendChild(style);
    },

    
    /**
     * 监听 DOM 变化和 hash 切换，持续同步工具栏按钮
     * （与 group-ai-summary、group-summary-local 相同的模式）
     */
    _observeConversation() {
        const self = this;
        const check = () => self._syncButton();

        // 监听 hash 变化（SPA 导航）
        window.addEventListener('hashchange', check);
        this._hashHandler = check;

        // MutationObserver 监听 DOM 重建
        this._observer = new MutationObserver(check);
        const startObs = () => {
            const app = document.querySelector('#app') || document.body;
            self._observer.observe(app, { childList: true, subtree: true });
            check();
        };
        setTimeout(startObs, 3000);
    },

    /**
     * 同步工具栏按钮：检测 .rong-tools 是否存在，不存在则等待，存在则注入
     * 可被 MutationObserver / hashchange 反复调用
     */
    _syncButton() {
        var self = this;
        var toolbar = document.querySelector('.rong-tools');
        if (!toolbar) return;

        // 已经注入过则跳过
        if (toolbar.querySelector('#chat-exporter-btn')) return;

        var btn = document.createElement('button');
        btn.id = 'chat-exporter-btn';
        btn.title = '导出聊天数据';
        btn.style.cssText = 'width:28px;height:28px;border:0;margin-left:8px;background:transparent;cursor:pointer;background-size:22px 22px;background-repeat:no-repeat;background-position:center;border-radius:8px;transition:transform 0.15s;padding:0;';

        var dc = '#808CA4', hc = '#3A6EE7';
        var svgPath = '<path d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32v242.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c0-26.5 21.5-48 48-48h8l176 0c26.5 0 48 21.5 48 48l0 128c0 26.5-21.5 48-48 48l-192 0c-26.5 0-48-21.5-48-48l0-128z"/>';
        var mkSvg = function(c) { return '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512" fill="'+c+'">' + svgPath + '</svg>'; };
        var toBg = function(c) { return 'url("data:image/svg+xml;base64,' + btoa(mkSvg(c)) + '")'; };
        btn.style.backgroundImage = toBg(dc);
        btn.addEventListener('mouseenter', function() { this.style.backgroundImage = toBg(hc); this.style.transform = 'scale(1.15)'; });
        btn.addEventListener('mouseleave', function() { this.style.backgroundImage = toBg(dc); this.style.transform = 'scale(1)'; });
        btn.onclick = function(e) { e.preventDefault(); e.stopPropagation(); self._togglePanel(); };
        toolbar.appendChild(btn);
        console.log('[ChatExporter] 📌 已注入导出按钮到工具栏');
    },

    _togglePanel() {
        try {
            const panel = document.querySelector('#cep-panel');
            if (panel) {
                panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
                return;
            }
            this._createPanel();
        } catch(e) { console.error('[ChatExporter] togglePanel error:', e); }
    },

    _createPanel() {
        const self = this;
        const panel = document.createElement('div');
        panel.id = 'cep-panel';
        panel.innerHTML = `
            <div class="cep-header">
                <div class="cep-header-title">📥 聊天数据导出器</div>
                <button class="cep-header-close" id="cep-close">✕</button>
            </div>
            <div class="cep-body">
                <p class="cep-desc">全量导出当前会话消息为JSON，支持分页拉取。<br>零上传 · 数据不出本机</p>
                <div class="cep-form-row">
                    <label class="cep-form-label">开始日期 <input id="cep-date-start" type="date" class="cep-form-input" style="width:130px;"></label>
                    <label class="cep-form-label">结束日期 <input id="cep-date-end" type="date" class="cep-form-input" style="width:130px;"></label>
                </div>
                <div class="cep-form-row">
                    <label class="cep-form-label">每页条数 <input id="cep-pagesize" type="number" value="200" min="50" max="200" class="cep-form-input"></label>
                    <label class="cep-form-label">最大页数 <input id="cep-maxpages" type="number" value="500" min="1" max="2000" class="cep-form-input"></label>
                </div>
                <button id="cep-export" class="cep-btn">📤 导出当前会话</button>
                <button id="cep-export-conv" class="cep-btn cep-btn-secondary">📋 从列表选择会话</button>
                <div id="cep-status" class="cep-status"></div>
                <div id="cep-log" class="cep-log" style="display:none;"></div>
                <div id="cep-conv-list" class="cep-conv-list" style="display:none;"></div>
            </div>
        `;
        document.body.appendChild(panel);
        self._instance.panel = panel;

        document.getElementById('cep-close').onclick = function() { panel.style.display = 'none'; };
        document.getElementById('cep-export').onclick = function() { self._exportCurrent(); };
        document.getElementById('cep-export-conv').onclick = function() { self._showConvList(); };
    },

    _log(msg) {
        const logEl = document.querySelector('#cep-log');
        if (logEl) {
            logEl.style.display = 'block';
            logEl.textContent += `[${new Date().toLocaleTimeString()}] ${msg}\n`;
            logEl.scrollTop = logEl.scrollHeight;
        }
    },

    _setStatus(text, type) {
        const el = document.querySelector('#cep-status');
        if (el) {
            el.className = 'cep-status' + (type ? ' ' + type : '');
            el.textContent = text;
        }
    },

    _parseRoute() {
        const hash = window.location.hash || '';
        const match = hash.match(/conversation\/(\d+)\/([^/?]+)/);
        if (!match) return null;
        return { conversationType: parseInt(match[1], 10), targetId: match[2] };
    },

    async _exportCurrent() {
        const route = this._parseRoute();
        if (!route) {
            document.querySelector('#cep-status').textContent = '❌ 请先打开一个会话';
            return;
        }
        const convTitle = document.querySelector('.rong-conversation-title');
        const title = convTitle ? convTitle.textContent.trim() : route.targetId;
        await this._doExport(route.conversationType, route.targetId, title);
    },

    async _showConvList() {
        const listEl = document.querySelector('#cep-conv-list');
        if (!listEl) return;
        listEl.style.display = 'block';
        listEl.innerHTML = '<div style="padding:16px;text-align:center;color:#86868b;">正在加载会话列表...</div>';

        try {
            const RongIMLib = window.RongIMLib;
            if (!RongIMLib || !RongIMLib.RongIMClient) {
                listEl.innerHTML = '<div style="padding:16px;text-align:center;color:#FF3B30;">❌ 融云 SDK 未就绪</div>';
                return;
            }

            const convList = await new Promise((resolve, reject) => {
                RongIMLib.RongIMClient.getInstance().getConversationList(
                    { onSuccess: (list) => resolve(list || []), onError: reject },
                    [1, 3], 100
                );
            });

            if (!convList || convList.length === 0) {
                listEl.innerHTML = '<div style="padding:16px;text-align:center;color:#86868b;">暂无会话</div>';
                return;
            }

            let html = '<input id="cep-search" class="cep-conv-search" placeholder="🔍 搜索会话...">';
            convList.forEach((conv) => {
                const isPrivate = conv.conversationType === 1;
                const typeClass = isPrivate ? 'cep-conv-type-private' : 'cep-conv-type-group';
                const typeLabel = isPrivate ? '私聊' : '群聊';
                const title = conv.conversationTitle || conv.targetId;
                html += `<div class="cep-conv-item" data-type="${conv.conversationType}" data-id="${conv.targetId}" data-title="${title}">
                    <span class="cep-conv-type ${typeClass}">${typeLabel}</span>${title}</div>`;
            });
            listEl.innerHTML = html;

            listEl.querySelectorAll('.cep-conv-item').forEach(el => {
                el.addEventListener('click', async () => {
                    try {
                        const type = parseInt(el.dataset.type);
                        const id = el.dataset.id;
                        const title = el.dataset.title;
                        listEl.style.display = 'none';
                        await this._doExport(type, id, title);
                    } catch (e) {
                        console.error('[ChatExporter] 导出失败:', e);
                        this._log('❌ 导出失败: ' + e.message);
                    }
                });
            });

            const searchEl = listEl.querySelector('#cep-search');
            if (searchEl) {
                searchEl.addEventListener('input', () => {
                    const q = searchEl.value.toLowerCase();
                    listEl.querySelectorAll('.cep-conv-item').forEach(el => {
                        el.style.display = el.textContent.toLowerCase().includes(q) ? '' : 'none';
                    });
                });
            }
        } catch (e) {
            console.error('[ChatExporter] 加载会话列表失败:', e);
            listEl.innerHTML = `<div style="padding:16px;text-align:center;color:#FF3B30;">❌ 加载失败: ${e.message}</div>`;
        }
    },

    async _doExport(conversationType, targetId, title) {
        if (this._instance.isExporting) return;
        this._instance.isExporting = true;

        const pageSize = parseInt(document.querySelector('#cep-pagesize').value) || 200;
        const maxPages = parseInt(document.querySelector('#cep-maxpages').value) || 500;
        const RongIMLib = window.RongIMLib;
        const RongIMClient = RongIMLib.RongIMClient;
        const myId = RongIMClient.getInstance().getCurrentUserId();

        // 日期范围过滤
        const dateStartEl = document.querySelector('#cep-date-start');
        const dateEndEl = document.querySelector('#cep-date-end');
        const startTime = dateStartEl && dateStartEl.value ? new Date(dateStartEl.value + 'T00:00:00').getTime() : 0;
        const endTime = dateEndEl && dateEndEl.value ? new Date(dateEndEl.value + 'T23:59:59').getTime() : Infinity;
        const hasDateFilter = startTime > 0 || endTime < Infinity;
        if (hasDateFilter) {
            const s = startTime > 0 ? new Date(startTime).toLocaleDateString('zh-CN') : '不限';
            const e = endTime < Infinity ? new Date(endTime).toLocaleDateString('zh-CN') : '不限';
            this._log(`日期过滤: ${s} ~ ${e}`);
        }

        this._log(`开始导出: [${conversationType === 1 ? '私聊' : '群聊'}] ${title} (conversationType=${conversationType}, targetId=${targetId})`);
        this._setStatus('正在拉取消息...');

        const allMessages = [];
        let oldestId = 0;
        let page = 0;
        let totalFetched = 0;
        let totalKept = 0;

        try {
            while (page < maxPages) {
                const msgs = await new Promise((resolve, reject) => {
                    RongIMClient.getInstance().getHistoryMessages(
                        conversationType, targetId, oldestId, pageSize,
                        { onSuccess: (list) => resolve(list || []), onError: reject }
                    );
                });

                totalFetched += msgs.length;
                if (msgs.length === 0) break;

                for (const msg of msgs) {
                    // 日期范围过滤
                    if (hasDateFilter) {
                        const msgTime = msg.sentTime || 0;
                        if (msgTime < startTime || msgTime > endTime) {
                            totalKept += 0;
                            continue;
                        }
                    }

                    // 根据消息类型提取有意义的文本内容
                    const msgType = msg.objectName || msg.messageType || '';
                    let content = '';
                    let isNonText = false;
                    if (msg.content) {
                        if (msgType === 'RC:TxtMsg' || msgType === 'RC:ReferenceMessage') {
                            content = msg.content.content || '';
                        } else if (msgType === 'RC:ImgMsg') {
                            content = '[图片]';
                            isNonText = true;
                        } else if (msgType === 'RC:FileMsg') {
                            content = '[文件] ' + (msg.content.name || '');
                            isNonText = true;
                        } else if (msgType === 'RC:VcMsg' || msgType === 'RC:HQVCMsg') {
                            content = '[语音消息]';
                            isNonText = true;
                        } else if (msgType === 'RC:SightMsg') {
                            content = '[短视频]';
                            isNonText = true;
                        } else if (msgType === 'RC:ImgTextMsg' || msgType === 'RC:PSImgTxtMsg' || msgType === 'RC:PSMultiImgTxtMsg') {
                            content = '[图文消息] ' + (msg.content.title || '');
                        } else if (msgType === 'RC:CombineMsg' || msgType === 'RC:CombineV2Msg') {
                            content = '[合并转发] ' + (msg.content.name || msg.content.title || '');
                        } else if (msg.content.content && msg.content.content.length < 500 && !msg.content.content.startsWith('data:') && !msg.content.content.startsWith('/9j/')) {
                            content = msg.content.content;
                        } else if (msg.content.name) {
                            content = '[文件] ' + msg.content.name;
                            isNonText = true;
                        } else {
                            content = '[' + (msgType || '非文本消息') + ']';
                            isNonText = true;
                        }
                    } else {
                        content = '[空消息]';
                        isNonText = true;
                    }
                    totalKept++;
                    allMessages.push({
                        id: msg.messageId || msg.messageUId,
                        time: msg.sentTime,
                        timeStr: new Date(msg.sentTime).toLocaleString('zh-CN'),
                        sender: msg.senderUserName || msg.senderUserId,
                        senderId: msg.senderUserId,
                        content: content,
                        type: msgType,
                        isMine: msg.senderUserId === myId,
                        isAtMe: !isNonText && !!(content && content.includes && content.includes('@'))
                    });
                }

                oldestId = msgs[msgs.length - 1].messageId;
                page++;
                this._setStatus(`第 ${page} 页，已获取 ${allMessages.length} 条消息...`);
                this._log(`第 ${page} 页: 本页拉取 ${msgs.length} 条, 保留 ${allMessages.length} 条 (已拉取 ${totalFetched}, 已保留 ${totalKept})`);

                if (msgs.length < pageSize) break;
            }

            allMessages.sort((a, b) => a.time - b.time);

            this._log(`拉取结束: totalFetched=${totalFetched}, totalKept=${totalKept}`);

            // 解析用户ID为真实姓名
            this._setStatus('正在解析用户信息...');
            this._log('正在解析用户ID为姓名...');
            const userIds = [...new Set(allMessages.map(m => m.senderId))];
            const userMap = await this._resolveUsers(userIds);
            for (const m of allMessages) {
                const info = userMap[m.senderId];
                if (info) {
                    m.sender = info.name || info.alias || m.senderId;
                    if (info.alias && info.name) m.senderAlias = info.alias;
                }
            }
            this._log(`已解析 ${Object.keys(userMap).length} 个用户`);

            const participants = new Set(allMessages.map(m => m.senderId));
            const exportData = {
                exportTime: new Date().toISOString(),
                conversation: { type: conversationType === 1 ? '私聊' : '群聊', targetId, targetName: title, conversationType, rawType: conversationType },
                stats: {
                    totalFetched: totalFetched,
                    totalKept: totalKept,
                    totalMessages: allMessages.length,
                    myMessages: allMessages.filter(m => m.isMine).length,
                    otherMessages: allMessages.filter(m => !m.isMine).length,
                    participants: participants.size,
                    dateFilter: hasDateFilter ? { startTime, endTime } : null,
                    timeRange: allMessages.length > 0 ? {
                        start: allMessages[0].timeStr,
                        end: allMessages[allMessages.length - 1].timeStr
                    } : null
                },
                messages: allMessages
            };

            const safeTitle = title.replace(/[^a-zA-Z0-9\u4e00-\u9fa5_-]/g, '_').substring(0, 30);
            const filename = `export_${safeTitle}_${new Date().toISOString().replace(/[:.]/g, '').substring(0, 15)}.json`;
            const filepath = path.join(this._cacheDir, filename);
            fs.writeFileSync(filepath, JSON.stringify(exportData, null, 2), 'utf-8');

            this._log(`✅ 导出完成: ${allMessages.length} 条消息 → ${filename}`);
            this._setStatus(`✅ 导出完成！${allMessages.length} 条消息`, 'success');

            try {
                const { shell } = require('electron');
                shell.showItemInFolder(filepath);
            } catch (e) {}

        } catch (e) {
            console.error('[ChatExporter] 导出失败:', e);
            this._log(`❌ 导出失败: ${e.message}`);
            this._setStatus('❌ 导出失败', 'error');
        } finally {
            this._instance.isExporting = false;
        }
    },

    /**
     * 批量解析用户ID为姓名
     * 使用 RongIM.dataModel.User.get() 查询
     */
    _resolveUsers(userIds) {
        return new Promise((resolve) => {
            const RongIM = window.RongIM;
            if (!RongIM || !RongIM.dataModel || !RongIM.dataModel.User) {
                resolve({});
                return;
            }
            const map = {};
            let done = 0;
            const total = userIds.length;
            if (total === 0) { resolve(map); return; }

            const timeout = setTimeout(() => resolve(map), 15000);

            userIds.forEach(uid => {
                try {
                    RongIM.dataModel.User.get(uid, (err, user) => {
                        done++;
                        if (!err && user) {
                            map[uid] = { name: user.name || '', alias: user.alias || '' };
                        }
                        if (done >= total) {
                            clearTimeout(timeout);
                            resolve(map);
                        }
                    });
                } catch (e) {
                    done++;
                    if (done >= total) {
                        clearTimeout(timeout);
                        resolve(map);
                    }
                }
            });
        });
    },

    destroy() {
        if (this._instance.panel) this._instance.panel.remove();
        const btn = document.querySelector('#chat-exporter-btn');
        if (btn) btn.remove();
        if (this._hashHandler) window.removeEventListener('hashchange', this._hashHandler);
        if (this._observer) this._observer.disconnect();
        console.log('[ChatExporter] 已销毁');
    }
};
