(function(){
    if(!window.StudioI18n) return;
    const translations = new Map(Object.entries({
        "个人信息":"Profile",
        "我的团队":"My Team",
        "管理后台":"Admin Console",
        "进入用户端":"User Workspace",
        "退出登录":"Log Out",
        "提示词":"Prompt",
        "分镜提示词":"Storyboard Prompts",
        "选择系统提供的模板，将小说或剧本转换为分镜提示词":"Choose a template to convert a novel or script into storyboard prompts",
        "清空":"Clear",
        "小说 / 剧本转分镜":"Novel / Script to Storyboard",
        "先选择分镜模板，再粘贴小说、剧本或故事正文。AI 会按照模板要求输出分镜提示词。":"Choose a storyboard template, then paste your novel, script, or story. AI will generate storyboard prompts using the template.",
        "读取分镜模板...":"Loading storyboard templates...",
        "在这里粘贴小说、剧本或故事正文...":"Paste a novel, script, or story here...",
        "正在检查使用权限":"Checking access",
        "请稍候":"Please wait",
        "提示词功能未开通":"Prompt feature unavailable",
        "当前账户没有提示词使用权限，或权限已经到期。":"This account does not have prompt access, or access has expired.",
        "请联系服务方开通后再使用。":"Contact the service administrator to enable it.",
        "无法加载提示词功能":"Could not load Prompt",
        "请先在 API 设置添加聊天模型":"Add a chat model in API Settings first",
        "暂时没有可用模板":"No templates available",
        "暂无聊天模型":"No chat models",
        "复制分镜提示词":"Copy Storyboard Prompt",
        "请先选择分镜提示词模板":"Select a storyboard prompt template first",
        "正在根据模板生成分镜提示词...":"Generating storyboard prompts from the template...",
        "视频生成":"Video Generation",
        "剩余积分":"Credits",
        "视频提示词":"Video Prompt",
        "描述主体动作、场景、镜头运动、光影和风格... 输入 @ 引用下方素材":"Describe motion, scene, camera movement, lighting, and style... Type @ to reference media below",
        "参考素材（可选）":"Reference Media (Optional)",
        "图片":"Images",
        "添加图片":"Add Image",
        "视频":"Videos",
        "音频":"Audio",
        "最多 9 图 + 3 视频 + 3 音频":"Up to 9 images + 3 videos + 3 audio files",
        "生成参数":"Generation Settings",
        "请先配置视频 API":"Configure a video API first",
        "正在加载视频平台...":"Loading video platforms...",
        "正在加载视频模型...":"Loading video models...",
        "生成视频":"Generate Video",
        "正在创建视频任务":"Creating video task",
        "下载视频":"Download Video",
        "生成记录":"Generation History",
        "暂无视频模型":"No video models",
        "视频服务暂未配置":"Video service is not configured",
        "请输入视频提示词":"Enter a video prompt",
        "暂无可用视频模型":"No video models available",
        "正在上传素材并创建任务":"Uploading media and creating task",
        "视频生成中，请耐心等待":"Generating video. Please wait.",
        "视频生成失败，积分已自动退回":"Video generation failed. Credits were refunded.",
        "复用":"Reuse",
        "下载":"Download",
        "素材库":"Assets",
        "资产库":"Asset Library",
        "资产库管理":"Asset Library Manager",
        "素材库管理":"Asset Manager",
        "资产层级":"Asset Hierarchy",
        "先选库，再选分组":"Select a library, then a group",
        "按库、分组、内容和预览管理素材与提示词。":"Manage media and prompts by library, group, content, and preview.",
        "准备就绪":"Ready",
        "刷新":"Refresh",
        "刷新列表":"Refresh List",
        "排序方式":"Sort Order",
        "打开回收站":"Open Trash",
        "图片资产":"Image Assets",
        "提示词库":"Prompt Libraries",
        "画布资产":"Canvas Assets",
        "本地素材":"Local Media",
        "管理图片资产库和提示词库":"Manage image asset libraries and prompt libraries",
        "导出到资产库":"Export to Asset Library",
        "新资产库":"New Asset Library",
        "新建资产库":"New Asset Library",
        "新提示词库":"New Prompt Library",
        "新增提示词":"Add Prompt",
        "默认资产库":"Default Asset Library",
        "系统提示词库":"System Prompt Library",
        "当前分组还没有资产":"No assets in this group",
        "暂无本地素材，请在素材库管理中上传":"No local media. Upload files in Asset Manager.",
        "本地素材请在素材库管理中上传":"Upload local media in Asset Manager",
        "已保存到资产库":"Saved to Asset Library",
        "当前提示词库为空":"This prompt library is empty",
        "提示词预览":"Prompt Preview",
        "选择一条提示词查看全文":"Select a prompt to view its full content",
        "暂无可预览提示词":"No prompt available for preview",
        "编辑提示词":"Edit Prompt",
        "在当前库内保存":"Save in the current library",
        "名称":"Name",
        "备注":"Notes",
        "正向提示词":"Positive Prompt",
        "负向提示词":"Negative Prompt",
        "资产库名称":"Asset Library Name",
        "提示词库名称":"Prompt Library Name",
        "提示词名称":"Prompt Name",
        "新提示词":"New Prompt",
        "新模板":"New Template",
        "我的提示词预设":"My Prompt Presets",
        "请选择可编辑的提示词库":"Select an editable prompt library",
        "当前提示词为空":"The current prompt is empty",
        "系统提示词":"System Prompts",
        "工作流":"Workflows",
        "暂无工作流分组":"No workflow groups",
        "新分组":"New Group",
        "分组名称":"Group Name",
        "保存":"Save",
        "删除":"Delete",
        "编辑":"Edit",
        "重命名":"Rename",
        "取消":"Cancel",
        "确定":"Confirm",
        "关闭":"Close",
        "搜索":"Search",
        "全部":"All",
        "上传":"Upload",
        "上传文件":"Upload Files",
        "批量管理":"Batch Manage",
        "上传到当前分组":"Upload to Current Group",
        "拖入文件或点击上传":"Drop files here or click to upload",
        "当前分组还没有素材，可以上传，或从智能画布输出保存到素材库。":"This group has no media yet. Upload files or save output from Smart Canvas.",
        "素材预览":"Media Preview",
        "选择一个素材查看详情":"Select an item to view details",
        "暂无可预览素材":"No media available for preview",
        "新建分组":"New Group",
        "未选择":"Not selected",
        "加载中...":"Loading...",
        "暂无内容":"No content"
    }));
    const textOriginal = new WeakMap();
    const attrOriginal = new WeakMap();
    const ignored = new Set(["SCRIPT","STYLE","TEXTAREA","INPUT","CODE","PRE"]);
    let applying = false;

    function translateText(value){
        const raw = String(value || "");
        const trimmed = raw.trim();
        if(!trimmed) return raw;
        let translated = translations.get(trimmed);
        const assetCount = trimmed.match(/^(.+) \/ (\d+) 个素材$/);
        if(!translated && assetCount){
            translated = `${translations.get(assetCount[1]) || assetCount[1]} / ${assetCount[2]} items`;
        }
        if(!translated){
            translated = trimmed
                .replace(/^任务 (.+) 已提交，已扣 (\d+) 积分$/, "Task $1 submitted. $2 credits charged.")
                .replace(/^任务状态：(.+)$/, "Task status: $1")
                .replace(/^图片 (\d+)$/, "Image $1")
                .replace(/^已上传 (\d+) 个媒体文件到云端，首个链接已复制。链接约 3 天有效。$/, "Uploaded $1 media files. The first URL was copied and is valid for about 3 days.")
                .replace(/^已选择 (\d+) 个节点，(\d+) 条连线$/, "$1 nodes and $2 connections selected")
                .replace(/^共 (\d+) 个$/, "$1 total")
                .replace(/^(\d+) 个$/, "$1 items");
        }
        if(!translated || translated === trimmed) return raw;
        return raw.replace(trimmed, translated);
    }

    function translateNode(node, english){
        if(node.nodeType === Node.TEXT_NODE){
            if(!node.parentElement || ignored.has(node.parentElement.tagName)) return;
            if(node.parentElement.tagName === "OPTION" && !node.parentElement.hasAttribute("data-ui-fixed")) return;
            if(!textOriginal.has(node)) textOriginal.set(node, node.nodeValue);
            const original = textOriginal.get(node);
            node.nodeValue = english ? translateText(original) : original;
            return;
        }
        if(node.nodeType !== Node.ELEMENT_NODE) return;
        ["placeholder","title","aria-label"].forEach(attr => {
            if(!node.hasAttribute(attr)) return;
            let saved = attrOriginal.get(node);
            if(!saved){ saved = {}; attrOriginal.set(node, saved); }
            if(!(attr in saved)) saved[attr] = node.getAttribute(attr);
            node.setAttribute(attr, english ? translateText(saved[attr]) : saved[attr]);
        });
        if(ignored.has(node.tagName) && !(node.tagName === "OPTION" && node.hasAttribute("data-ui-fixed"))) return;
        node.childNodes.forEach(child => translateNode(child, english));
    }

    function apply(root=document){
        if(applying) return;
        applying = true;
        try {
            translateNode(root.documentElement || root, StudioI18n.lang() === "en");
        } finally {
            applying = false;
        }
    }

    const observer = new MutationObserver(records => {
        if(applying) return;
        const english = StudioI18n.lang() === "en";
        records.forEach(record => record.addedNodes.forEach(node => translateNode(node, english)));
    });
    function startObserver(){
        apply();
        if(document.body) observer.observe(document.body, {childList:true, subtree:true});
    }
    if(document.readyState === "loading"){
        document.addEventListener("DOMContentLoaded", startObserver, {once:true});
    }else{
        startObserver();
    }
    window.addEventListener("studio-lang-change", () => apply());
    window.addEventListener("message", event => {
        if(event.data?.type !== "studio-lang") return;
        StudioI18n.set(event.data.lang);
    });
})();
