import { defineStore } from 'pinia'
import { ElMessage } from 'element-plus'

export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
    state: () => ({
        // 基础状态
        isGenerating: false,
        isShowProcess: false, // 初始隐藏执行步骤面板
        isShowSteps: false, // 步骤侧边栏显隐控制
        isShowClauseTranslation: false, // 翻译侧边栏显隐控制
        isEditMode: false,
        writtingTitle: '',
        descText: '',
        reportContent: '', // 报文内容（核心）
        curTempTitle: '政令',
        tempActiveIndex: 0,
        curAgentTool: '',
        uploadFileList: [],
        // 路由相关状态
        _isDisableTemplate: false,
        routeQuery: {},
        // 步骤日志（用于流式更新）
        processLog: '',

        // 条款翻译相关状态
        clauseTranslationMessages: [], // 存收到的条款翻译消息
        highlightClauseId: null, // 当前高亮的条款 ID (clause_number)
        isShowOriginal: true, // 是否显示原文内容

        // 静态数据
        tabList: [
            { name: '写报', active: true },
            { name: '收藏', active: false },
            { name: '问答', active: false }
        ],
        tempList: [
            { title: '政令', desc: '基于政令内容生成各维度的综合分析报告' },
            { title: '法案', desc: '基于政令内容生成各维度的综合分析报告' },
            { title: '智库', desc: '基于智库内容生成各维度的综合分析报告' },
            { title: '清单', desc: '基于清单内容生成各维度的综合分析报告' }
        ],

        // 内部控制器
        abortController: null
    }),

    getters: {
        isDisableTemplate: (state) => state._isDisableTemplate,

        formattedTime: () => {
            const now = new Date()
            const pad = n => n.toString().padStart(2, '0')
            return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
        }
    },

    actions: {
        // ========== 基础状态修改 ==========
        toggleEditMode() {
            this.isEditMode = !this.isEditMode
        },

        resetGenerateState() {
            this.isGenerating = false;
            this.isShowProcess = false;
            this.isShowSteps = false;
            this.curAgentTool = '';
            this.processLog = '';
            this.clauseTranslationMessages = [];
            this.isShowClauseTranslation = false;
            this.highlightClauseId = null;
            this.isShowOriginal = true;
            this.abortController?.abort();
            this.abortController = null;
        },

        updateTempActiveIndex(index, title) {
            this.tempActiveIndex = index;
            this.curTempTitle = title;
        },

        // ========== 路由参数处理 ==========
        async setRouteParams(query) {
            this.routeQuery = { ...query };
            this._isDisableTemplate = Object.keys(query).length > 0;

            if (Object.keys(query).length > 0) {
                const { topic, fileId } = query;
                if (topic) {
                    this.curTempTitle = topic;
                    this.tempActiveIndex = this.tempList.findIndex(item => item.title === topic);
                }

                // 如果携带 fileId：外部跳转仅回填/锁定参数，不自动生成
                if (fileId) {
                    this.curTempTitle = topic || '政令';
                    this.tempActiveIndex = this.tempList.findIndex(item => item.title === this.curTempTitle);

                    // 初始标题设为空，待点击生成后从接口获取并清洗
                    this.writtingTitle = '';
                }
            }
        },

        // ========== 内部工具函数 (抽取的公共逻辑) ==========
        _cleanTitle(title) {
            return (title || '').replace(/[^\u4e00-\u9fa5]/g, '');
        },

        async _fetchBusinessData({ url, payload, typeName }) {
            this.isGenerating = true;
            this.isShowProcess = true;
            this.processLog = `${this.formattedTime}:正在获取${typeName}数据...\r\n`;

            try {
                const response = await fetch(url, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(payload)
                });

                const data = await response.json();

                if (data.status === 'success' && data.result) {
                    this.processLog += `${this.formattedTime}:${typeName}数据获取成功，开始生成写报...\r\n`;
                    
                    // 清洗标题
                    this.writtingTitle = this._cleanTitle(data.result['报告标题']);
                    
                    // 触发 AI 生成
                    await this.fetchReportData({
                        query: this.writtingTitle,
                        desc: this.descText,
                        topic: this.curTempTitle,
                        result: data.result
                    });
                } else {
                    throw new Error(data.error_log?.join(', ') || `获取${typeName}数据失败`);
                }
            } catch (error) {
                console.error(`获取${typeName}数据异常:`, error);
                ElMessage.error(`获取${typeName}数据失败: ${error.message}`);
                this.resetGenerateState();
            }
        },

        // ========== 获取业务数据并触发生成 (业务封装) ==========
        async fetchOrderReportData(orderId) {
            await this._fetchBusinessData({
                url: '/reportData/get-order-report-data',
                payload: { order_id: Number(orderId) },
                typeName: '政令'
            });
        },

        async fetchBillReportData(billId) {
            await this._fetchBusinessData({
                url: '/reportData/get-bill-report-data',
                payload: { bill_id: billId },
                typeName: '法案'
            });
        },

        async fetchListReportData(sancDate) {
            await this._fetchBusinessData({
                url: '/reportData/get-sanc-list-report-data',
                payload: { sanc_date: sancDate },
                typeName: '实体清单'
            });
        },

        // ========== 文件上传相关 ==========
        handleExceed(files, uploadRef) {
            if (uploadRef) {
                uploadRef.clearFiles();
                const file = files[0];
                file.uid = Date.now();
                uploadRef.handleStart(file);
            }
        },

        handleFileChange(file, files) {
            this.uploadFileList = files.length > 1 ? [file] : files;
        },

        // ========== PDF 解析 SSE（仅更新执行步骤） ==========
        async fetchPdfData(selectedFile) {
            if (this.abortController) this.abortController.abort();
            this.abortController = new AbortController();
            this.processLog = '';

            try {
                const formData = new FormData();
                formData.append('pdf', selectedFile);

                const { fetchEventSource } = await import('@microsoft/fetch-event-source');
                await fetchEventSource('/pdfSse/api/v1/order/pdf/extract/report/sse', {
                    method: 'POST',
                    body: formData,
                    signal: this.abortController.signal,
                    headers: { Accept: 'text/event-stream', 'Cache-Control': 'no-cache' },
                    openWhenHidden: true,
                    retryDelay: 1000,
                    maxRetries: 3,
                    onopen: async (response) => {
                        if (response.ok && response.headers.get('content-type')?.includes('text/event-stream')) {
                        } else {
                            ElMessage.warning('SSE连接格式异常，即将断开');
                            this.abortController.abort();
                        }
                    },
                    onmessage: async (event) => {
                        if (!event || !event.data || event.data.trim() === '') return;

                        let jsonData = null;
                        try {
                            jsonData = JSON.parse(event.data.trim());
                        } catch (parseError) {
                            console.warn('SSE消息JSON解析失败', parseError, event.data);
                            return;
                        }

                        switch (event.event) {
                            case 'progress':
                                // 仅更新执行步骤
                                if (jsonData.message) {
                                    this.processLog += `${this.formattedTime}:${jsonData.message}\r\n`;
                                }
                                break;
                            case 'clause_translation':
                                // 保存条款翻译消息并显示侧边栏
                                if (jsonData) {
                                    this.clauseTranslationMessages.push(jsonData);
                                    this.isShowClauseTranslation = true;
                                    this.isShowSteps = true; // 翻译出现时，步骤侧边栏也显示
                                }
                                break;
                            case 'result':
                                if (jsonData && Object.keys(jsonData).length) {
                                    await this.fetchReportData({
                                        query: this.writtingTitle,
                                        desc: this.descText,
                                        topic: this.curTempTitle,
                                        result: jsonData
                                    });
                                }
                                break;
                            default:
                                console.debug('未处理的SSE事件类型', event.event);
                                break;
                        }
                    },
                    onerror: (error) => {
                        console.error('SSE连接错误', error);
                        ElMessage.warning('写报生成报错!');
                        if (error.name !== 'AbortError') return true;
                        this.resetGenerateState();
                    },
                    onclose: () => {
                        console.log('SSE连接正常关闭');
                        this.isGenerating = false;
                    }
                });
            } catch (error) {
                if (error.name !== 'AbortError') {
                    ElMessage.error(`PDF解析请求失败：${error.message}`);
                    console.error('PDF SSE请求异常', error);
                }
                this.resetGenerateState();
                throw error;
            }
        },

        // ========== AI 生成报文 SSE（更新报文内容 + 执行步骤） ==========
        async fetchReportData(params) {
            if (this.abortController) this.abortController.abort();
            this.abortController = new AbortController();
            this.processLog = '';

            // 用于把 SSE 的分片内容先聚合，再按“句子/段落边界”一次性提交到 reportContent
            // 这样可以还原老版“一句完整再显示”的渲染效果，避免分片逐条渲染
            let streamBuffer = '';
            let lastFlushedIndex = 0;

            const flushToReport = (force = false) => {
                // 强制 flush 时，把剩余 buffer 全部提交；否则只提交到 lastFlushedIndex
                const endIndex = force ? streamBuffer.length : lastFlushedIndex;
                if (endIndex <= 0) return;

                const chunk = streamBuffer.slice(0, endIndex);
                if (!chunk) return;

                this.reportContent += chunk;
                streamBuffer = streamBuffer.slice(endIndex);
                lastFlushedIndex = 0;

                if (this.reportContent.includes('./out/img')) {
                    this.reportContent = this.reportContent.replaceAll('./out/img', 'http://172.19.21.9:8003/out/img');
                }
            };

            // 尝试找到一个“合适的边界”再 flush：
            // 1) 中文/英文句末标点 + 可选换行
            // 2) 双换行（段落）
            // 3) markdown 列表/标题等常见行结束
            const updateFlushIndexByBoundary = () => {
                // 优先按段落（双换行）
                const paraIdx = streamBuffer.lastIndexOf('\n\n');
                if (paraIdx !== -1) {
                    lastFlushedIndex = Math.max(lastFlushedIndex, paraIdx + 2);
                }

                // 其次按句末标点
                // eslint-disable-next-line no-useless-escape
                const sentenceRe = /[。！？!?；;](?:\s|\n|$)/g;
                let m;
                while ((m = sentenceRe.exec(streamBuffer)) !== null) {
                    lastFlushedIndex = Math.max(lastFlushedIndex, m.index + m[0].length);
                }

                // 再次按单行结束（避免长时间不刷新）
                const lineIdx = streamBuffer.lastIndexOf('\n');
                if (lineIdx !== -1 && streamBuffer.length > 200) {
                    lastFlushedIndex = Math.max(lastFlushedIndex, lineIdx + 1);
                }
            };

            try {
                const { fetchEventSource } = await import('@microsoft/fetch-event-source');
                await fetchEventSource('/sseWrite/api/v1/workflow/invoke', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(params),
                    signal: this.abortController.signal,
                    openWhenHidden: true,
                    onopen: (res) => {
                        console.log('流式回答开始', res);
                    },
                    onmessage: (res) => {
                        if (!res.data) return;

                        let msgData;
                        try {
                            msgData = JSON.parse(res.data);
                        } catch (e) {
                            return;
                        }

                        const str = msgData.data || '';

                        if (msgData.event_type === 'stream_agent_out') {
                            if (str !== '[DONE]') {
                                // SSE 分片先进入 buffer（仅用于报文内容）
                                streamBuffer += str;
                                updateFlushIndexByBoundary();
                                flushToReport(false);
                            } else {
                                // 结束时把剩余内容强制 flush
                                flushToReport(true);
                                this.isGenerating = false;
                                this.isShowSteps = false; // 报文生成结束后关闭步骤侧边栏
                                ElMessage.success('报文生成结束');
                                // 这里不再调用 resetGenerateState，因为可能需要保留翻译内容
                            }
                        } else if (msgData.event_type === 'workflow_complete') {
                            // complete 也做一次强制 flush，避免尾巴丢失
                            flushToReport(true);
                            this.isGenerating = false;
                            this.isShowSteps = false; // 报文生成结束后关闭步骤侧边栏
                            ElMessage.success('报文生成结束');
                        } else if ((msgData.event_type || '').toLowerCase().includes('error')) {
                            // 优先从 data.error 获取详细错误描述
                            const errorMsg = msgData.data?.error || str || '生成失败';
                            ElMessage.error('生成失败：' + errorMsg);
                            this.resetGenerateState();
                        } else {
                            // 老版 --index.vue 行为：步骤栏直接追加服务端发来的完整步骤内容，不加时间戳、不强行换行
                            // 这样可以避免 SSE 分片导致的“步骤破碎”（一条步骤被拆成多条显示）
                            if (str) {
                                this.processLog += str;
                            }
                            this.curAgentTool = msgData.tool || '无';
                        }
                    },
                    onerror: (error) => {
                        ElMessage.warning('写报生成报错!');
                        this.resetGenerateState();
                        throw new Error(error);
                    }
                });
            } catch (error) {
                ElMessage.warning('写报生成报错!');
                this.resetGenerateState();
                throw error;
            }
        },

        // ========== 业务入口 ==========
        async generateReport() {
            // 路由参数优先
            this.isGenerating = true;
            this.isShowProcess = true;

            if (Object.keys(this.routeQuery).length !== 0) {
                const { fileId, topic } = this.routeQuery;

                // 外部跳转：根据 topic 决定调用哪种数据获取接口，再触发生成
                if (fileId) {
                    if (this.curTempTitle === '法案') {
                        await this.fetchBillReportData(fileId);
                    } else if (this.curTempTitle === '清单') {
                        await this.fetchListReportData(fileId);
                    } else {
                        await this.fetchOrderReportData(fileId);
                    }
                    return;
                }

                // 兼容：若仅有 routeQuery 但无 fileId，则直接走原生成接口
                const params = {
                    query: this.writtingTitle,
                    desc: this.descText,
                    topic: this.curTempTitle,
                    report_id: fileId
                };
                await this.fetchReportData(params);
            } else {
                // 政令模板需要先解析PDF
                if (this.curTempTitle === '政令') {
                    if (this.uploadFileList.length === 0) {
                        throw new Error('请上传政令文件');
                    }
                    const rawFile = this.uploadFileList[0].raw;
                    if (!rawFile) {
                        throw new Error('文件解析失败，请重新选择');
                    }
                    await this.fetchPdfData(rawFile);
                } else {
                    const params = {
                        query: this.writtingTitle,
                        desc: this.descText,
                        topic: this.curTempTitle
                    };
                    await this.fetchReportData(params);
                }
            }
        },

        // ========== 导出Markdown ==========
        exportContent() {
            if (!this.reportContent) {
                ElMessage.warning('暂无可导出的报文内容');
                return;
            }
            const blob = new Blob([this.reportContent], { type: 'text/markdown' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `markdown-${new Date().getTime()}.md`;
            a.click();
            URL.revokeObjectURL(url);
        },

        // ========== 清理 ==========
        cleanup() {
            this.resetGenerateState();
        }
    }
});