import React, { createContext, useContext, useEffect, useMemo, useState } from "react";

export type Language = "en" | "zh";

export type TranslationKey =
  | "workspace"
  | "project"
  | "runs"
  | "localDev"
  | "navAssets"
  | "navWorkflows"
  | "navRuns"
  | "navExplore"
  | "navLabels"
  | "navAdmin"
  | "language"
  | "english"
  | "chinese"
  | "assetsTitle"
  | "assetsDescription"
  | "localPath"
  | "registerLocalPath"
  | "noAssetsYet"
  | "type"
  | "source"
  | "detected"
  | "pending"
  | "topLevelEntries"
  | "notAvailable"
  | "loadingAssetDetail"
  | "assetId"
  | "status"
  | "sourcePath"
  | "probeAgain"
  | "createExploreArtifact"
  | "openExploreView"
  | "probeSummary"
  | "warnings"
  | "none"
  | "recommendedNodes"
  | "noProbeReportYet"
  | "workflowsTitle"
  | "createWorkflow"
  | "noWorkflowsYet"
  | "latestVersion"
  | "workflowEditor"
  | "runAsset"
  | "saveWorkflowVersion"
  | "triggerWorkflowRun"
  | "reloadLatestSaved"
  | "openLatestRun"
  | "selectAssetBeforeRun"
  | "nodeLibrary"
  | "nodeLibraryHint"
  | "canvas"
  | "canvasHint"
  | "dragNodeToCanvas"
  | "latestSavedVersions"
  | "draftStatus"
  | "draftSynced"
  | "draftUnsaved"
  | "nodeConfiguration"
  | "category"
  | "definition"
  | "executorType"
  | "runtimeTarget"
  | "artifactTitle"
  | "pythonCodeHook"
  | "nodeNoHook"
  | "selectNode"
  | "removeNode"
  | "workflowCreatedName"
  | "noAssetsAvailable"
  | "runsTitle"
  | "runsDescription"
  | "noRunsYet"
  | "createdAt"
  | "inputAssets"
  | "runDetail"
  | "workflow"
  | "startedAt"
  | "finishedAt"
  | "runDuration"
  | "runSummary"
  | "cancelRun"
  | "retryRun"
  | "runGraph"
  | "boundAssets"
  | "selectedTask"
  | "executor"
  | "executorConfig"
  | "codeHook"
  | "duration"
  | "summary"
  | "error"
  | "retryTask"
  | "artifacts"
  | "noTaskArtifactsYet"
  | "stdout"
  | "stderr"
  | "executionLog"
  | "resultPreview"
  | "noStdout"
  | "noStderr"
  | "noTaskLogs"
  | "noTasksCreated"
  | "loadingRun"
  | "exploreTitle"
  | "exploreEmpty"
  | "loadingArtifact"
  | "bootstrappingLocalWorkspace"
  | "failedLoadAssets"
  | "failedRegisterAsset"
  | "failedLoadWorkflows"
  | "failedLoadWorkflow"
  | "failedLoadRuns"
  | "failedLoadRunDetail"
  | "failedLoadTaskArtifacts"
  | "failedCancelRun"
  | "failedRetryRun"
  | "failedRetryTask"
  | "failedLoadArtifact"
  | "failedBootstrap"
  | "validatedAssetCount"
  | "loadedAssetCount"
  | "success"
  | "failed"
  | "running"
  | "queued"
  | "cancelled"
  | "totalTasks"
  | "stdoutLines"
  | "stderrLines"
  | "successCount"
  | "failedCount"
  | "runningCount"
  | "cancelledCount"
  | "artifactsCount"
  | "viaExecutor"
  | "assetCount"
  | "artifactCount"
  | "invalidConnectionMissingEndpoint"
  | "invalidConnectionSelf"
  | "invalidConnectionDuplicate"
  | "invalidConnectionSourceDisallowsOutgoing"
  | "invalidConnectionTargetDisallowsIncoming"
  | "invalidConnectionTargetAlreadyHasIncoming"
  | "invalidConnectionCycle";

const TRANSLATIONS: Record<Language, Record<TranslationKey, string>> = {
  en: {
    workspace: "Workspace",
    project: "Project",
    runs: "Runs",
    localDev: "Local Dev",
    navAssets: "Assets",
    navWorkflows: "Workflows",
    navRuns: "Runs",
    navExplore: "Explore",
    navLabels: "Labels",
    navAdmin: "Admin",
    language: "Language",
    english: "English",
    chinese: "中文",
    assetsTitle: "Assets",
    assetsDescription:
      "Register local folders, archives, or dataset files, then probe them into managed asset metadata.",
    localPath: "Local Path",
    registerLocalPath: "Register Local Path",
    noAssetsYet: "No assets have been registered yet.",
    type: "Type",
    source: "Source",
    detected: "Detected",
    pending: "pending",
    topLevelEntries: "Top-level entries",
    notAvailable: "n/a",
    loadingAssetDetail: "Loading asset detail...",
    assetId: "Asset ID",
    status: "Status",
    sourcePath: "Source path",
    probeAgain: "Probe Again",
    createExploreArtifact: "Create Explore Artifact",
    openExploreView: "Open Explore View",
    probeSummary: "Probe Summary",
    warnings: "Warnings",
    none: "none",
    recommendedNodes: "Recommended nodes",
    noProbeReportYet: "No probe report yet.",
    workflowsTitle: "Workflows",
    createWorkflow: "Create Workflow",
    noWorkflowsYet: "No workflows yet.",
    latestVersion: "Latest version",
    workflowEditor: "Workflow Editor",
    runAsset: "Run Asset",
    saveWorkflowVersion: "Save Workflow Version",
    triggerWorkflowRun: "Trigger Workflow Run",
    reloadLatestSaved: "Reload Latest Saved",
    openLatestRun: "Open Latest Run",
    selectAssetBeforeRun: "Select an asset before triggering a workflow run.",
    nodeLibrary: "Node Library",
    nodeLibraryHint: "Click to append or drag a node onto the canvas.",
    canvas: "Canvas",
    canvasHint: "Drag nodes freely, connect handles, zoom, and pan.",
    dragNodeToCanvas: "Drop the node here to place it on the canvas.",
    latestSavedVersions: "Latest saved versions",
    draftStatus: "Draft status",
    draftSynced: "synced",
    draftUnsaved: "unsaved changes",
    nodeConfiguration: "Node Configuration",
    category: "Category",
    definition: "Definition",
    executorType: "Executor Type",
    runtimeTarget: "Runtime Target",
    artifactTitle: "Artifact Title",
    pythonCodeHook: "Python Code Hook",
    nodeNoHook: "This node does not expose a code hook in V1.",
    selectNode: "Select a node.",
    removeNode: "Remove Node",
    workflowCreatedName: "Delivery Normalize {count}",
    noAssetsAvailable: "No assets available",
    runsTitle: "Runs",
    runsDescription: "Recent workflow executions for the current project.",
    noRunsYet: "No workflow runs yet.",
    createdAt: "Created at",
    inputAssets: "Input assets",
    runDetail: "Run Detail",
    workflow: "Workflow",
    startedAt: "Started at",
    finishedAt: "Finished at",
    runDuration: "Run duration",
    runSummary: "Run summary",
    cancelRun: "Cancel Run",
    retryRun: "Retry Run",
    runGraph: "Run Graph",
    boundAssets: "Bound assets",
    selectedTask: "Selected Task",
    executor: "Executor",
    executorConfig: "Executor config",
    codeHook: "Code hook",
    duration: "Duration",
    summary: "Summary",
    error: "Error",
    retryTask: "Retry Task",
    artifacts: "Artifacts",
    noTaskArtifactsYet: "No task artifacts yet.",
    stdout: "Stdout",
    stderr: "Stderr",
    executionLog: "Execution Log",
    resultPreview: "Result Preview",
    noStdout: "No stdout lines.",
    noStderr: "No stderr lines.",
    noTaskLogs: "No task logs yet.",
    noTasksCreated: "No tasks created.",
    loadingRun: "Loading run...",
    exploreTitle: "Explore",
    exploreEmpty: "Create an artifact from asset detail to inspect it here.",
    loadingArtifact: "Loading artifact...",
    bootstrappingLocalWorkspace: "Bootstrapping local workspace...",
    failedLoadAssets: "Failed to load assets",
    failedRegisterAsset: "Failed to register local asset",
    failedLoadWorkflows: "Failed to load workflows",
    failedLoadWorkflow: "Failed to load workflow",
    failedLoadRuns: "Failed to load runs",
    failedLoadRunDetail: "Failed to load run detail",
    failedLoadTaskArtifacts: "Failed to load task artifacts",
    failedCancelRun: "Failed to cancel run",
    failedRetryRun: "Failed to retry run",
    failedRetryTask: "Failed to retry task",
    failedLoadArtifact: "Failed to load artifact",
    failedBootstrap: "Failed to bootstrap local context",
    validatedAssetCount: "validated {count} asset{suffix}",
    loadedAssetCount: "loaded {count} bound asset{suffix}",
    success: "success",
    failed: "failed",
    running: "running",
    queued: "queued",
    cancelled: "cancelled",
    totalTasks: "{count} total tasks",
    stdoutLines: "{count} stdout lines",
    stderrLines: "{count} stderr lines",
    successCount: "{count} success",
    failedCount: "{count} failed",
    runningCount: "{count} running",
    cancelledCount: "{count} cancelled",
    artifactsCount: "artifacts {count}",
    viaExecutor: "{outcome} via {executor}",
    assetCount: "assets {count}",
    artifactCount: "artifacts {count}",
    invalidConnectionMissingEndpoint: "The connection is missing a valid source or target node.",
    invalidConnectionSelf: "A node cannot connect to itself.",
    invalidConnectionDuplicate: "This edge already exists.",
    invalidConnectionSourceDisallowsOutgoing: "Export nodes cannot create outgoing connections in V1.",
    invalidConnectionTargetDisallowsIncoming: "Source nodes cannot accept incoming connections.",
    invalidConnectionTargetAlreadyHasIncoming: "This node already has an upstream connection in V1.",
    invalidConnectionCycle: "This edge would create a cycle.",
  },
  zh: {
    workspace: "工作空间",
    project: "项目",
    runs: "运行",
    localDev: "本地开发",
    navAssets: "数据资产",
    navWorkflows: "工作流",
    navRuns: "运行记录",
    navExplore: "查看",
    navLabels: "标注",
    navAdmin: "管理",
    language: "语言",
    english: "English",
    chinese: "中文",
    assetsTitle: "数据资产",
    assetsDescription: "注册本地目录、压缩包或数据集文件，并将其探测为受管资产元数据。",
    localPath: "本地路径",
    registerLocalPath: "注册本地路径",
    noAssetsYet: "还没有注册任何资产。",
    type: "类型",
    source: "来源",
    detected: "识别结果",
    pending: "待探测",
    topLevelEntries: "顶层条目",
    notAvailable: "暂无",
    loadingAssetDetail: "正在加载资产详情...",
    assetId: "资产 ID",
    status: "状态",
    sourcePath: "源路径",
    probeAgain: "重新探测",
    createExploreArtifact: "创建查看产物",
    openExploreView: "打开查看页",
    probeSummary: "探测摘要",
    warnings: "告警",
    none: "无",
    recommendedNodes: "推荐节点",
    noProbeReportYet: "还没有探测报告。",
    workflowsTitle: "工作流",
    createWorkflow: "新建工作流",
    noWorkflowsYet: "还没有工作流。",
    latestVersion: "最新版本",
    workflowEditor: "工作流编辑器",
    runAsset: "运行资产",
    saveWorkflowVersion: "保存工作流版本",
    triggerWorkflowRun: "触发工作流运行",
    reloadLatestSaved: "重新加载最新保存版本",
    openLatestRun: "打开最新运行",
    selectAssetBeforeRun: "触发工作流运行前请先选择资产。",
    nodeLibrary: "节点面板",
    nodeLibraryHint: "支持点击追加，也支持将节点拖入画布指定位置。",
    canvas: "画布",
    canvasHint: "支持自由拖动节点、拖拽连线、缩放和平移。",
    dragNodeToCanvas: "将节点拖放到这里即可在画布中创建。",
    latestSavedVersions: "最近保存版本",
    draftStatus: "草稿状态",
    draftSynced: "已同步",
    draftUnsaved: "有未保存修改",
    nodeConfiguration: "节点配置",
    category: "分类",
    definition: "定义",
    executorType: "执行器类型",
    runtimeTarget: "运行目标",
    artifactTitle: "产物标题",
    pythonCodeHook: "Python 代码钩子",
    nodeNoHook: "该节点在 V1 中不开放代码钩子。",
    selectNode: "请选择一个节点。",
    removeNode: "删除节点",
    workflowCreatedName: "交付标准化 {count}",
    noAssetsAvailable: "没有可用资产",
    runsTitle: "运行记录",
    runsDescription: "当前项目最近的工作流执行记录。",
    noRunsYet: "还没有工作流运行记录。",
    createdAt: "创建时间",
    inputAssets: "输入资产",
    runDetail: "运行详情",
    workflow: "工作流",
    startedAt: "开始时间",
    finishedAt: "结束时间",
    runDuration: "运行时长",
    runSummary: "运行摘要",
    cancelRun: "取消运行",
    retryRun: "重试运行",
    runGraph: "运行图",
    boundAssets: "绑定资产",
    selectedTask: "当前任务",
    executor: "执行器",
    executorConfig: "执行器配置",
    codeHook: "代码钩子",
    duration: "耗时",
    summary: "摘要",
    error: "错误",
    retryTask: "重试任务",
    artifacts: "产物",
    noTaskArtifactsYet: "当前任务还没有产物。",
    stdout: "标准输出",
    stderr: "标准错误",
    executionLog: "执行日志",
    resultPreview: "结果预览",
    noStdout: "没有标准输出。",
    noStderr: "没有标准错误。",
    noTaskLogs: "当前任务还没有日志。",
    noTasksCreated: "还没有生成任务。",
    loadingRun: "正在加载运行...",
    exploreTitle: "查看",
    exploreEmpty: "先在资产详情或运行详情里创建产物，再来这里查看。",
    loadingArtifact: "正在加载产物...",
    bootstrappingLocalWorkspace: "正在初始化本地工作空间...",
    failedLoadAssets: "加载资产失败",
    failedRegisterAsset: "注册本地资产失败",
    failedLoadWorkflows: "加载工作流失败",
    failedLoadWorkflow: "加载工作流失败",
    failedLoadRuns: "加载运行列表失败",
    failedLoadRunDetail: "加载运行详情失败",
    failedLoadTaskArtifacts: "加载任务产物失败",
    failedCancelRun: "取消运行失败",
    failedRetryRun: "重试运行失败",
    failedRetryTask: "重试任务失败",
    failedLoadArtifact: "加载产物失败",
    failedBootstrap: "初始化本地上下文失败",
    validatedAssetCount: "已校验 {count} 个资产",
    loadedAssetCount: "已加载 {count} 个绑定资产",
    success: "成功",
    failed: "失败",
    running: "运行中",
    queued: "排队中",
    cancelled: "已取消",
    totalTasks: "共 {count} 个任务",
    stdoutLines: "{count} 条标准输出",
    stderrLines: "{count} 条标准错误",
    successCount: "{count} 个成功",
    failedCount: "{count} 个失败",
    runningCount: "{count} 个运行中",
    cancelledCount: "{count} 个已取消",
    artifactsCount: "产物 {count}",
    viaExecutor: "{outcome}，执行器 {executor}",
    assetCount: "资产 {count}",
    artifactCount: "产物 {count}",
    invalidConnectionMissingEndpoint: "该连线缺少有效的起点或终点节点。",
    invalidConnectionSelf: "节点不能连接自己。",
    invalidConnectionDuplicate: "这条连线已经存在。",
    invalidConnectionSourceDisallowsOutgoing: "V1 中导出节点不允许继续向外连线。",
    invalidConnectionTargetDisallowsIncoming: "数据源节点不允许接收入边。",
    invalidConnectionTargetAlreadyHasIncoming: "V1 中该节点只能保留一条上游入边。",
    invalidConnectionCycle: "这条连线会形成环路。",
  },
};

const BUILTIN_NODE_TRANSLATIONS: Record<string, { en: { name: string; description: string }; zh: { name: string; description: string } }> = {
  "source-asset": {
    en: { name: "Source Asset", description: "Load an uploaded asset or registered storage path." },
    zh: { name: "数据源", description: "加载上传资产或已注册的存储路径。" },
  },
  "extract-archive": {
    en: { name: "Extract Archive", description: "Expand a compressed archive into a managed folder artifact." },
    zh: { name: "解压归档", description: "将压缩包展开成受管目录产物。" },
  },
  "rename-folder": {
    en: { name: "Rename Delivery Folder", description: "Rename the top-level delivery folder to the business naming convention." },
    zh: { name: "重命名交付目录", description: "将顶层交付目录重命名为业务命名规范。" },
  },
  "validate-structure": {
    en: { name: "Validate Structure", description: "Validate required directories and metadata files." },
    zh: { name: "校验目录结构", description: "校验必需目录和元数据文件。" },
  },
  "validate-metadata": {
    en: { name: "Validate Metadata", description: "Validate meta.json, intrinsics.json, and video_meta.json." },
    zh: { name: "校验元数据", description: "校验 meta.json、intrinsics.json 和 video_meta.json。" },
  },
  "export-delivery-package": {
    en: { name: "Export Delivery Package", description: "Produce the final delivery package artifact for upload." },
    zh: { name: "导出交付包", description: "生成最终交付包产物用于上传或交付。" },
  },
};

type InterpolationValues = Record<string, string | number>;

function interpolate(template: string, values?: InterpolationValues) {
  if (!values) {
    return template;
  }
  return template.replace(/\{(\w+)\}/gu, (_match, key) => String(values[key] ?? ""));
}

export function translate(
  language: Language,
  key: TranslationKey,
  values?: InterpolationValues,
) {
  return interpolate(TRANSLATIONS[language][key], values);
}

export function getInitialLanguage(): Language {
  if (typeof window === "undefined") {
    return "zh";
  }
  const stored = window.localStorage.getItem("emboflow-language");
  if (stored === "en" || stored === "zh") {
    return stored;
  }
  return window.navigator.language.toLowerCase().startsWith("zh") ? "zh" : "en";
}

export function localizeNodeDefinition<T extends { id: string; name?: string; description?: string; category?: string }>(
  language: Language,
  definition: T,
) {
  const localized = BUILTIN_NODE_TRANSLATIONS[definition.id];
  const categoryMap = {
    Source: language === "zh" ? "数据源" : "Source",
    Transform: language === "zh" ? "处理" : "Transform",
    Inspect: language === "zh" ? "检查" : "Inspect",
    Annotate: language === "zh" ? "标注" : "Annotate",
    Export: language === "zh" ? "导出" : "Export",
    Utility: language === "zh" ? "工具" : "Utility",
  } as const;
  return {
    ...definition,
    name: localized ? localized[language].name : definition.name,
    description: localized ? localized[language].description : definition.description,
    category:
      definition.category && definition.category in categoryMap
        ? categoryMap[definition.category as keyof typeof categoryMap]
        : definition.category,
  };
}

type I18nContextValue = {
  language: Language;
  setLanguage: (language: Language) => void;
  t: (key: TranslationKey, values?: InterpolationValues) => string;
};

const I18nContext = createContext<I18nContextValue | null>(null);

export function I18nProvider(props: React.PropsWithChildren) {
  const [language, setLanguage] = useState<Language>(() => getInitialLanguage());

  useEffect(() => {
    if (typeof document !== "undefined") {
      document.documentElement.lang = language === "zh" ? "zh-CN" : "en";
    }
    if (typeof window !== "undefined") {
      window.localStorage.setItem("emboflow-language", language);
    }
  }, [language]);

  const value = useMemo<I18nContextValue>(
    () => ({
      language,
      setLanguage,
      t: (key, values) => translate(language, key, values),
    }),
    [language],
  );

  return <I18nContext.Provider value={value}>{props.children}</I18nContext.Provider>;
}

export function useI18n() {
  const context = useContext(I18nContext);
  if (!context) {
    throw new Error("useI18n must be used within I18nProvider");
  }
  return context;
}
