// Storage module for Overleaf Chrome Extension
// 本地文档存储管理器和豆包翻译服务

// Backend API URL configuration
const BACKEND_API_URL = 'https://overleaf.top';

// 支持本地存储的文本文件扩展名
const TEXT_FILE_EXTENSIONS = ['.tex', '.txt', '.bib', '.sty', '.cls', '.bst', '.md', '.json', '.xml', '.csv'];

// 支持边写边译功能的文件扩展名（只有 .tex 和 .txt）
const LIVE_TRANSLATION_EXTENSIONS = ['.tex', '.txt'];

/**
 * 检查文件是否为文本文件（支持本地存储）
 * @param {string} filename - 文件名
 * @returns {boolean}
 */
function isTextFile(filename) {
    if (!filename) return false;
    const lowerName = filename.toLowerCase();
    return TEXT_FILE_EXTENSIONS.some(ext => lowerName.endsWith(ext));
}

/**
 * 检查文件是否支持边写边译功能
 * 只有 .tex 和 .txt 文件支持边写边译
 * @param {string} filename - 文件名
 * @returns {boolean}
 */
function isLiveTranslationFile(filename) {
    if (!filename) return false;
    const lowerName = filename.toLowerCase();
    return LIVE_TRANSLATION_EXTENSIONS.some(ext => lowerName.endsWith(ext));
}

// =================== 本地文档存储管理器 ===================
const localDocStorage = {
    // 存储键前缀
    STORAGE_PREFIX: 'overleaf_doc_',

    /**
     * 获取项目的存储键
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @returns {string} 存储键
     */
    getStorageKey(projectId, filename) {
        return `${this.STORAGE_PREFIX}${projectId}_${filename}`;
    },

    /**
     * 保存中文文档到本地存储
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @param {string} content - 文档内容
     * @returns {Promise<boolean>} 是否保存成功
     */
    async save(projectId, filename, content) {
        console.log(`[LocalDocStorage] save called: projectId=${projectId}, filename=${filename}, contentLength=${content?.length}`);

        if (!projectId || !filename || content === undefined || content === null) {
            console.error(`[LocalDocStorage] Save failed - missing params: projectId=${projectId}, filename=${filename}, hasContent=${content !== undefined && content !== null}`);
            return false;
        }

        try {
            const key = this.getStorageKey(projectId, filename);
            const data = {
                projectId,
                filename,
                content,
                savedAt: Date.now(),
                lineCount: content.split('\n').length
            };
            await chrome.storage.local.set({ [key]: data });
            console.log(`[LocalDocStorage] ✓ Saved: ${filename} (${content.length} chars, ${data.lineCount} lines)`);
            return true;
        } catch (error) {
            console.error('[LocalDocStorage] ✗ Error saving document:', error);
            return false;
        }
    },

    /**
     * 从本地存储加载中文文档
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @returns {Promise<Object|null>} 文档数据或null
     */
    async load(projectId, filename) {
        try {
            const key = this.getStorageKey(projectId, filename);
            const result = await chrome.storage.local.get(key);
            if (result[key]) {
                console.log(`[LocalDocStorage] Loaded: ${filename}`);
                return result[key];
            }
            return null;
        } catch (error) {
            console.error('[LocalDocStorage] Error loading document:', error);
            return null;
        }
    },

    /**
     * 更新文档的特定行
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @param {Object} lineUpdates - {行号: 翻译内容} 格式的更新
     * @returns {Promise<string|null>} 更新后的完整内容或null
     */
    async updateLines(projectId, filename, lineUpdates) {
        try {
            const doc = await this.load(projectId, filename);
            if (!doc) {
                console.error('[LocalDocStorage] No document found to update');
                return null;
            }

            const lines = doc.content.split('\n');

            for (const [lineNum, translatedText] of Object.entries(lineUpdates)) {
                const idx = parseInt(lineNum) - 1;  // 行号从1开始，数组索引从0开始
                if (idx >= 0 && idx < lines.length) {
                    lines[idx] = translatedText;
                }
            }

            const updatedContent = lines.join('\n');
            await this.save(projectId, filename, updatedContent);

            return updatedContent;
        } catch (error) {
            console.error('[LocalDocStorage] Error updating lines:', error);
            return null;
        }
    },

    /**
     * 检查是否存在已保存的文档
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @returns {Promise<boolean>}
     */
    async has(projectId, filename) {
        const doc = await this.load(projectId, filename);
        return doc !== null;
    },

    /**
     * 获取项目的所有已保存文档列表
     * @param {string} projectId - 项目ID（可选，不传则获取所有项目）
     * @returns {Promise<Array>} 文档列表
     */
    async list(projectId = null) {
        try {
            const allData = await chrome.storage.local.get(null);
            const docs = [];

            for (const [key, value] of Object.entries(allData)) {
                if (key.startsWith(this.STORAGE_PREFIX)) {
                    if (!projectId || value.projectId === projectId) {
                        docs.push({
                            key,
                            projectId: value.projectId,
                            filename: value.filename,
                            savedAt: value.savedAt,
                            lineCount: value.lineCount,
                            contentLength: value.content?.length || 0
                        });
                    }
                }
            }

            return docs.sort((a, b) => b.savedAt - a.savedAt);
        } catch (error) {
            console.error('[LocalDocStorage] Error listing documents:', error);
            return [];
        }
    },

    /**
     * 删除文档
     * @param {string} projectId - 项目ID
     * @param {string} filename - 文件名
     * @returns {Promise<boolean>}
     */
    async delete(projectId, filename) {
        try {
            const key = this.getStorageKey(projectId, filename);
            await chrome.storage.local.remove(key);
            console.log(`[LocalDocStorage] Deleted: ${filename}`);
            return true;
        } catch (error) {
            console.error('[LocalDocStorage] Error deleting document:', error);
            return false;
        }
    },

    /**
     * 获取存储使用情况
     * @returns {Promise<Object>} {used: bytes, total: bytes}
     */
    async getStorageUsage() {
        try {
            const bytesInUse = await chrome.storage.local.getBytesInUse(null);
            return {
                used: bytesInUse,
                usedMB: (bytesInUse / 1024 / 1024).toFixed(2)
            };
        } catch (error) {
            console.error('[LocalDocStorage] Error getting storage usage:', error);
            return { used: 0, usedMB: '0' };
        }
    }
};

// 豆包翻译服务
const doubaoTranslator = {
    // 最小翻译字符数阈值，小于此值的行将跳过翻译
    MIN_TRANSLATE_LENGTH: 3,
    // 请求超时时间（毫秒）- 600秒（10分钟）
    REQUEST_TIMEOUT: 600000,

    /**
     * 判断一行是否需要翻译
     * @param {string} line - 行内容
     * @returns {boolean} - 是否需要翻译
     */
    shouldTranslateLine(line) {
        // 去除首尾空白后，长度小于阈值的行跳过翻译
        const trimmed = line.trim();
        return trimmed.length >= this.MIN_TRANSLATE_LENGTH;
    },

    /**
     * 将文本转换为行号字典格式，并分离需要翻译和跳过的行
     * @param {string} text - 文本内容
     * @param {number} startLineId - 起始行号
     * @returns {Object} - { toTranslate: {行号: 内容}, skipped: {行号: 内容} }
     */
    textToLinesDict(text, startLineId = 1) {
        const lines = text.split('\n');
        const toTranslate = {};
        const skipped = {};

        for (let i = 0; i < lines.length; i++) {
            const lineId = String(startLineId + i);
            const line = lines[i];

            if (this.shouldTranslateLine(line)) {
                toTranslate[lineId] = line;
            } else {
                // 跳过的行保留原内容
                skipped[lineId] = line;
            }
        }

        return { toTranslate, skipped };
    },

    /**
     * 将行号字典转换回文本
     * @param {Object} linesDict - {行号: 内容} 格式的字典
     * @returns {string} - 合并后的文本
     */
    linesDictToText(linesDict) {
        // 按行号排序后合并
        const sortedKeys = Object.keys(linesDict).sort((a, b) => parseInt(a) - parseInt(b));
        return sortedKeys.map(key => linesDict[key]).join('\n');
    },

    /**
     * 合并翻译结果和跳过的行
     * @param {Object} translatedLines - 翻译后的行 {行号: 内容}
     * @param {Object} skippedLines - 跳过的行 {行号: 内容}
     * @returns {Object} - 合并后的完整行字典
     */
    mergeLines(translatedLines, skippedLines) {
        return { ...translatedLines, ...skippedLines };
    },

    /**
     * 带超时的 fetch 请求
     * @param {string} url - 请求URL
     * @param {Object} options - fetch 选项
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise<Response>}
     */
    async fetchWithTimeout(url, options, timeout = this.REQUEST_TIMEOUT) {
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), timeout);

        try {
            const response = await fetch(url, {
                ...options,
                signal: controller.signal
            });
            clearTimeout(timeoutId);
            return response;
        } catch (error) {
            clearTimeout(timeoutId);
            if (error.name === 'AbortError') {
                throw new Error(`请求超时（${timeout / 1000}秒）`);
            }
            throw error;
        }
    },

    /**
     * 中文翻译为英文
     * @param {string} text - 待翻译的中文文本
     * @param {number} startLineId - 起始行号
     * @param {number} endLineId - 结束行号（未使用，保留兼容）
     * @param {string} model - 模型名称（可选）
     * @param {string} reasoningEffort - 思考程度 (minimal, low, medium, high)（可选）
     * @returns {Promise<{translated_text: string, translated_lines: Object, consumed_points: number, remaining_tokens: number}>}
     */
    async translateZhToEn(text, startLineId = 1, endLineId = 0, model = null, reasoningEffort = null) {
        console.log('[Doubao Translator] Translating Chinese to English, model:', model, ', reasoningEffort:', reasoningEffort);

        // 将文本转换为行号字典格式，分离需要翻译和跳过的行
        const { toTranslate, skipped } = this.textToLinesDict(text, startLineId);
        const toTranslateCount = Object.keys(toTranslate).length;
        const skippedCount = Object.keys(skipped).length;

        console.log('[Doubao Translator] Lines to translate:', toTranslateCount, ', Skipped lines:', skippedCount);

        // 如果没有需要翻译的行，直接返回原内容
        if (toTranslateCount === 0) {
            console.log('[Doubao Translator] No lines need translation, returning original content');
            return {
                success: true,
                translated_lines: skipped,
                translated_text: this.linesDictToText(skipped),
                consumed_points: 0,
                remaining_tokens: undefined,
                input_tokens: 0,
                output_tokens: 0,
                total_tokens: 0
            };
        }

        const requestBody = { lines: toTranslate };
        if (model) {
            requestBody.model = model;
        }
        if (reasoningEffort) {
            requestBody.reasoning_effort = reasoningEffort;
        }

        const response = await this.fetchWithTimeout(`${BACKEND_API_URL}/api/translate/zh-to-en`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            credentials: 'include',
            body: JSON.stringify(requestBody)
        });

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({}));
            throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`);
        }

        const result = await response.json();

        // 合并翻译结果和跳过的行
        if (result.translated_lines) {
            result.translated_lines = this.mergeLines(result.translated_lines, skipped);
            result.translated_text = this.linesDictToText(result.translated_lines);
        }

        return result;
    },

    /**
     * 英文翻译为中文
     * @param {string} text - 待翻译的英文文本
     * @param {number} startLineId - 起始行号
     * @param {number} endLineId - 结束行号（未使用，保留兼容）
     * @param {string} model - 模型名称（可选）
     * @param {string} reasoningEffort - 思考程度 (minimal, low, medium, high)（可选）
     * @returns {Promise<{translated_text: string, translated_lines: Object, consumed_points: number, remaining_tokens: number}>}
     */
    async translateEnToZh(text, startLineId = 1, endLineId = 0, model = null, reasoningEffort = null) {
        console.log('[Doubao Translator] Translating English to Chinese, model:', model, ', reasoningEffort:', reasoningEffort);

        // 将文本转换为行号字典格式，分离需要翻译和跳过的行
        const { toTranslate, skipped } = this.textToLinesDict(text, startLineId);
        const toTranslateCount = Object.keys(toTranslate).length;
        const skippedCount = Object.keys(skipped).length;

        console.log('[Doubao Translator] Lines to translate:', toTranslateCount, ', Skipped lines:', skippedCount);

        // 如果没有需要翻译的行，直接返回原内容
        if (toTranslateCount === 0) {
            console.log('[Doubao Translator] No lines need translation, returning original content');
            return {
                success: true,
                translated_lines: skipped,
                translated_text: this.linesDictToText(skipped),
                consumed_points: 0,
                remaining_tokens: undefined,
                input_tokens: 0,
                output_tokens: 0,
                total_tokens: 0
            };
        }

        const requestBody = { lines: toTranslate };
        if (model) {
            requestBody.model = model;
        }
        if (reasoningEffort) {
            requestBody.reasoning_effort = reasoningEffort;
        }

        const response = await this.fetchWithTimeout(`${BACKEND_API_URL}/api/translate/en-to-zh`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            credentials: 'include',
            body: JSON.stringify(requestBody)
        });

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({}));
            throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`);
        }

        const result = await response.json();

        // 合并翻译结果和跳过的行
        if (result.translated_lines) {
            result.translated_lines = this.mergeLines(result.translated_lines, skipped);
            result.translated_text = this.linesDictToText(result.translated_lines);
        }

        return result;
    }
};

/**
 * 将文本按段落分割（以空行为分隔符）
 * @param {string} content - 文档内容
 * @returns {Array<{text: string}>} - 段落数组
 */
function splitIntoParagraphs(content) {
    // 按连续的空行分割段落
    const rawParagraphs = content.split(/\n\s*\n/);
    const paragraphs = [];

    for (const para of rawParagraphs) {
        const trimmed = para.trim();
        if (trimmed) {
            paragraphs.push({ text: trimmed });
        }
    }

    return paragraphs;
}
