import React from "react";
import { fmtClock, fmtDate } from "./time";
import { LoadingTitle } from "./loading-indicator";
import { errorMessage, requestJson as requestUniDeskJson } from "./unidesk-error";
import { UniDeskErrorBanner } from "./unidesk-error-banner";
import { useNotification } from "./notification-context";

type AnyRecord = Record<string, any>;

const h = React.createElement;
const { useEffect } = React;
const useState: any = React.useState;

function requestJson(path: string, options: AnyRecord = {}): Promise<any> {
  return requestUniDeskJson(path, { failureFields: ["ok", "success"], ...options });
}

function baiduApi(apiBaseUrl: string, path: string): string {
  return `${apiBaseUrl}/microservices/baidu-netdisk/proxy${path}`;
}

function numberText(value: any): string {
  const number = Number(value);
  return Number.isFinite(number) ? number.toLocaleString("zh-CN") : "--";
}

function fmtBytes(value: any): string {
  const bytes = Number(value);
  if (!Number.isFinite(bytes) || bytes <= 0) return "--";
  const units = ["B", "KB", "MB", "GB", "TB"];
  let current = bytes;
  let index = 0;
  while (current >= 1024 && index < units.length - 1) {
    current /= 1024;
    index += 1;
  }
  return `${current.toFixed(index === 0 ? 0 : 1)} ${units[index]}`;
}

function StatusBadge({ status, children }: AnyRecord) {
  const normalized = String(status || "unknown").toLowerCase();
  return h("span", { className: `status-badge ${normalized}` }, children || status || "unknown");
}

function MetricCard({ label, value, hint, tone }: AnyRecord) {
  return h("article", { className: `metric-card ${tone || ""}` },
    h("div", { className: "metric-label" }, label),
    h("div", { className: "metric-value" }, value),
    h("div", { className: "metric-hint" }, hint),
  );
}

function Panel({ title, eyebrow, actions, children, className, loading }: AnyRecord) {
  return h("section", { className: `panel ${className || ""}` },
    h("div", { className: "panel-head" },
      h("div", null,
        eyebrow ? h("p", { className: "panel-eyebrow" }, eyebrow) : null,
        h(LoadingTitle, { title, loading }),
      ),
      actions ? h("div", { className: "panel-actions" }, actions) : null,
    ),
    h("div", { className: "panel-body" }, children),
  );
}

function RawButton({ title, data, onOpen, testId }: AnyRecord) {
  return h("button", {
    type: "button",
    className: "ghost-btn",
    "data-testid": testId,
    onClick: (event: any) => {
      event?.stopPropagation?.();
      onOpen(title, data);
    },
  }, "查看原始JSON");
}

function EmptyState({ title, text }: AnyRecord) {
  return h("div", { className: "empty-state" }, h("strong", null, title), h("span", null, text));
}

function DocLinkCard({ title, text, href, badge, testId }: AnyRecord) {
  return h("a", {
    className: "doc-link-card",
    href,
    target: "_blank",
    rel: "noreferrer",
    "data-testid": testId,
  },
    h("span", null, badge || "DOC"),
    h("strong", null, title),
    h("p", null, text),
    h("code", null, href),
  );
}

function microserviceRuntime(service: any): AnyRecord {
  return service?.runtime && typeof service.runtime === "object" && !Array.isArray(service.runtime) ? service.runtime : {};
}

function microserviceBackend(service: any): AnyRecord {
  return service?.backend && typeof service.backend === "object" && !Array.isArray(service.backend) ? service.backend : {};
}

function microserviceRepository(service: any): AnyRecord {
  return service?.repository && typeof service.repository === "object" && !Array.isArray(service.repository) ? service.repository : {};
}

function filesFromPayload(payload: any): any[] {
  return Array.isArray(payload?.files) ? payload.files : [];
}

function jobsFromPayload(payload: any): any[] {
  return Array.isArray(payload?.jobs) ? payload.jobs : [];
}

function pathParent(path: string, root: string): string {
  if (!path || path === root) return root;
  const withoutSlash = path.replace(/\/+$/u, "");
  const parent = withoutSlash.slice(0, withoutSlash.lastIndexOf("/")) || root;
  return parent.length < root.length ? root : parent;
}

function pathJoin(base: string, name: string): string {
  const safeName = String(name || "").replace(/^\/+|\/+$/gu, "");
  return `${base.replace(/\/+$/u, "")}/${safeName}`;
}

function rootDisplayName(root: string): string {
  return root === "/" ? "/" : root.split("/").filter(Boolean).pop() || root;
}

function ProgressBar({ percent }: AnyRecord) {
  const value = Math.max(0, Math.min(100, Number(percent) || 0));
  return h("div", { className: "baidu-progress" }, h("span", { style: { width: `${value}%` } }), h("em", null, `${value.toFixed(1)}%`));
}

export function BaiduNetdiskPage({ microservices, onRaw, apiBaseUrl = "/api" }: AnyRecord) {
  const service = microservices.find((item: any) => item.id === "baidu-netdisk") || null;
  const [state, setState] = useState({ loading: false, actionLoading: false, error: "", message: "", health: null, account: null, files: null, transfers: null, logs: null, selfTest: null, refreshedAt: null });
  const [currentDir, setCurrentDir] = useState("/");
  const [deviceSession, setDeviceSession] = useState(null);
  const [folderName, setFolderName] = useState("");
  const [uploadForm, setUploadForm] = useState({ localPath: "sample.txt", remotePath: "/sample.txt" });
  const [downloadForm, setDownloadForm] = useState({ fsId: "", localPath: "downloads/" });
  const { addNotification } = useNotification();

  const appRoot = state.health?.baidu?.appRoot || state.account?.rootPath || "/";

  useEffect(() => {
    setUploadForm((prev: any) => {
      const legacyDefaults = new Set(["/sample.txt", "/apps/UniDeskBaiduNetdisk/sample.txt"]);
      if (prev.remotePath && !legacyDefaults.has(prev.remotePath)) return prev;
      const remotePath = pathJoin(appRoot, "sample.txt");
      return prev.remotePath === remotePath ? prev : { ...prev, remotePath };
    });
  }, [appRoot]);

  async function loadFiles(dir = currentDir): Promise<void> {
    const targetDir = dir || appRoot;
    const files = await requestJson(baiduApi(apiBaseUrl, `/api/files?dir=${encodeURIComponent(targetDir)}&limit=100`));
    setState((prev: any) => ({ ...prev, files }));
  }

  async function loadTransfers(): Promise<void> {
    const transfers = await requestJson(baiduApi(apiBaseUrl, "/api/transfers?limit=80"));
    setState((prev: any) => ({ ...prev, transfers }));
  }

  async function load(): Promise<void> {
    if (!service) return;
    setState((prev: any) => ({ ...prev, loading: true, error: "", message: "" }));
    try {
      const health = await requestJson(`${apiBaseUrl}/microservices/baidu-netdisk/health`);
      const root = health?.baidu?.appRoot || appRoot;
      let account: any = null;
      let files: any = null;
      if (health?.auth?.loggedIn) {
        account = await requestJson(baiduApi(apiBaseUrl, "/api/account?refresh=1"));
        const dir = currentDir && currentDir.startsWith(root) ? currentDir : root;
        setCurrentDir(dir);
        files = await requestJson(baiduApi(apiBaseUrl, `/api/files?dir=${encodeURIComponent(dir)}&limit=100`));
      } else {
        setCurrentDir(root);
      }
      const transfers = await requestJson(baiduApi(apiBaseUrl, "/api/transfers?limit=80"));
      const logs = await requestJson(baiduApi(apiBaseUrl, "/logs?limit=60"));
      setState((prev: any) => ({ ...prev, loading: false, health, account: account?.account || null, files, transfers, logs, refreshedAt: new Date() }));
    } catch (err) {
      setState((prev: any) => ({ ...prev, loading: false, error: errorMessage(err, "百度网盘服务加载失败") }));
    }
  }

  async function startLogin(): Promise<void> {
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      const result = await requestJson(baiduApi(apiBaseUrl, "/api/auth/device/start"), { method: "POST", body: {} });
      setDeviceSession(result.session || null);
      setState((prev: any) => ({ ...prev, actionLoading: false, message: "设备码已生成，请扫码授权" }));
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "创建设备码失败") }));
    }
  }

  async function pollLogin(manual = false): Promise<void> {
    if (!deviceSession?.id) return;
    if (manual) setState((prev: any) => ({ ...prev, actionLoading: true, error: "" }));
    try {
      const result = await requestJson(baiduApi(apiBaseUrl, `/api/auth/device/status?sessionId=${encodeURIComponent(deviceSession.id)}`));
      setDeviceSession(result.session || null);
      if (result.session?.status === "succeeded") {
        setState((prev: any) => ({ ...prev, actionLoading: false, message: "授权成功，正在刷新账号与文件列表" }));
        await load();
      } else if (manual) {
        setState((prev: any) => ({ ...prev, actionLoading: false }));
      }
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "轮询登录状态失败") }));
    }
  }

  async function logout(): Promise<void> {
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, "/api/auth/logout"), { method: "POST", body: {} });
      setDeviceSession(null);
      setState((prev: any) => ({ ...prev, actionLoading: false, account: null, files: null, message: "本地 token 已清除" }));
      await load();
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "退出登录失败") }));
    }
  }

  async function createFolder(event: any): Promise<void> {
    event.preventDefault();
    const name = folderName.trim();
    if (!name) return;
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, "/api/folders"), { method: "POST", body: { path: pathJoin(currentDir, name) } });
      setFolderName("");
      setState((prev: any) => ({ ...prev, actionLoading: false, message: "文件夹已创建" }));
      await loadFiles(currentDir);
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "创建文件夹失败") }));
    }
  }

  async function deleteRemote(path: string): Promise<void> {
    if (!path) return;
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, "/api/files/manage"), { method: "POST", body: { opera: "delete", filelist: [{ path }], async: 1 } });
      setState((prev: any) => ({ ...prev, actionLoading: false, message: "删除任务已提交" }));
      await loadFiles(currentDir);
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "删除失败") }));
    }
  }

  async function submitUpload(event: any): Promise<void> {
    event.preventDefault();
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, "/api/transfers/upload-from-path"), { method: "POST", body: uploadForm });
      setState((prev: any) => ({ ...prev, actionLoading: false, message: "上传任务已入队" }));
      await loadTransfers();
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "上传任务创建失败") }));
    }
  }

  async function submitDownload(event: any): Promise<void> {
    event.preventDefault();
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, "/api/transfers/download-to-path"), { method: "POST", body: downloadForm });
      setState((prev: any) => ({ ...prev, actionLoading: false, message: "下载任务已入队" }));
      await loadTransfers();
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "下载任务创建失败") }));
    }
  }

  async function transferAction(id: string, action: "cancel" | "retry"): Promise<void> {
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "" }));
    try {
      await requestJson(baiduApi(apiBaseUrl, `/api/transfers/${encodeURIComponent(id)}/${action}`), { method: "POST", body: {} });
      setState((prev: any) => ({ ...prev, actionLoading: false, message: action === "cancel" ? "已请求取消任务" : "任务已重新入队" }));
      await loadTransfers();
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "任务操作失败") }));
    }
  }

  async function runSelfTest(): Promise<void> {
    setState((prev: any) => ({ ...prev, actionLoading: true, error: "", message: "正在运行上传/下载自测..." }));
    try {
      const selfTest = await requestJson(baiduApi(apiBaseUrl, "/api/self-test"), { method: "POST", body: {} });
      setState((prev: any) => ({ ...prev, actionLoading: false, selfTest, message: `上传/下载自测通过：${selfTest.remotePath || ""}` }));
      await loadFiles(currentDir);
      await loadTransfers();
    } catch (err) {
      setState((prev: any) => ({ ...prev, actionLoading: false, error: errorMessage(err, "上传/下载自测失败") }));
    }
  }

  useEffect(() => {
    if (!service) return undefined;
    load();
    return undefined;
  }, [service?.id, service?.runtime?.providerStatus]);

  useEffect(() => {
    if (!deviceSession?.id || deviceSession.status !== "pending") return undefined;
    const timer = window.setInterval(() => void pollLogin(false), Math.max(5000, Number(deviceSession.pollIntervalSeconds || 5) * 1000));
    return () => window.clearInterval(timer);
  }, [deviceSession?.id, deviceSession?.status, deviceSession?.pollIntervalSeconds]);

  useEffect(() => {
    if (!service) return undefined;
    const timer = window.setInterval(() => void loadTransfers(), 5000);
    return () => window.clearInterval(timer);
  }, [service?.id]);

  if (!service) return h(EmptyState, { title: "Baidu Netdisk 未登记", text: "请在 config.json 的 microservices 中登记用户服务 id=baidu-netdisk" });

  const runtime = microserviceRuntime(service);
  const repository = microserviceRepository(service);
  const backend = microserviceBackend(service);
  const health = state.health || {};
  const account = state.account || health.auth?.account || null;
  const auth = health.auth || {};
  const files = filesFromPayload(state.files);
  const jobs = jobsFromPayload(state.transfers);
  const quota = account?.quota || {};
  const loggedIn = Boolean(auth.loggedIn || account);
  const configured = Boolean(auth.configured);

  return h("div", { className: "baidu-netdisk-page", "data-testid": "baidu-netdisk-page" },
    h(Panel, {
      title: "Baidu Netdisk 工作台",
      eyebrow: "Containerized Storage Gateway",
      loading: state.loading,
      actions: h("div", { className: "panel-actions" },
        h("a", { className: "ghost-btn", href: "/docs/issue/baidu-netdisk-env-setup.md", target: "_blank", rel: "noreferrer", "data-testid": "baidu-netdisk-config-doc-link" }, "配置文档"),
        h("button", { type: "button", className: "ghost-btn", onClick: load, disabled: state.loading, "data-testid": "baidu-netdisk-refresh" }, state.loading ? "刷新中" : "刷新"),
        h(RawButton, { title: "Baidu Netdisk 用户服务", data: service, onOpen: onRaw, testId: "raw-baidu-netdisk-service" }),
      ),
    },
      h("div", { className: "baidu-netdisk-hero" },
        h("div", null,
          h("div", { className: "node-version-line" },
            h(StatusBadge, { status: runtime.providerStatus === "online" ? "online" : "warn" }, runtime.providerStatus || "unknown"),
            h("span", null, service.providerId),
            h(StatusBadge, { status: backend.public ? "warn" : "private" }, backend.public ? "公网暴露" : "仅 UniDesk frontend 代理访问"),
          ),
          h("p", { className: "muted paragraph" }, service.description),
        ),
        h("div", { className: "microservice-ref-card" },
          h("span", null, "Repo"),
          h("strong", null, repository.url || "--"),
          h("code", null, repository.commitId || "--"),
        ),
        h("div", { className: "microservice-ref-card" },
          h("span", null, "Private Backend"),
          h("strong", null, `${backend.nodeBindHost || "--"}:${backend.nodePort || "--"}`),
          h("code", null, `${repository.composeFile || "--"} / ${repository.composeService || "--"}`),
        ),
      ),
      h(UniDeskErrorBanner, { error: state.error, wide: true }),
    ),
    h("div", { className: "metric-grid" },
      h(MetricCard, { label: "Health", value: health.ok ? "OK" : "--", hint: health.storage?.postgres || "postgres", tone: health.ok ? "ok" : "warn" }),
      h(MetricCard, { label: "OAuth", value: configured ? "已配置" : "待配置", hint: configured ? "client + secret + token key" : "需要设置 UNIDESK_BAIDU_NETDISK_*", tone: configured ? "ok" : "warn" }),
      h(MetricCard, { label: "Login", value: loggedIn ? "已登录" : "未登录", hint: account?.username || "Device Code QR", tone: loggedIn ? "ok" : "warn" }),
      h(MetricCard, { label: "Work Root", value: rootDisplayName(appRoot), hint: appRoot }),
      h(MetricCard, { label: "Quota", value: fmtBytes(quota.used), hint: quota.total ? `${quota.usedPercent || 0}% / ${fmtBytes(quota.total)}` : "授权后刷新" }),
      h(MetricCard, { label: "Transfers", value: numberText(jobs.length), hint: `running ${state.transfers?.counts?.running || 0} / failed ${state.transfers?.counts?.failed || 0}` }),
    ),
    h(Panel, { title: "文件浏览器", eyebrow: currentDir, className: "baidu-files-panel", loading: state.loading,
      actions: h("div", { className: "panel-actions inline-actions" },
        h("button", { type: "button", className: "ghost-btn", onClick: () => { const parent = pathParent(currentDir, appRoot); setCurrentDir(parent); void loadFiles(parent); }, disabled: !loggedIn || currentDir === appRoot }, "上级"),
        h("button", { type: "button", className: "ghost-btn", onClick: () => loadFiles(currentDir), disabled: !loggedIn }, "刷新文件"),
        h(RawButton, { title: "Baidu Files", data: state.files, onOpen: onRaw, testId: "raw-baidu-files" }),
      ),
    },
      h("form", { className: "baidu-pathbar", onSubmit: (event: any) => { event.preventDefault(); void loadFiles(currentDir); } },
        h("input", { value: currentDir, onChange: (event: any) => setCurrentDir(event.target.value), disabled: !loggedIn }),
        h("button", { type: "submit", className: "ghost-btn", disabled: !loggedIn }, "打开路径"),
      ),
      h("form", { className: "baidu-pathbar", onSubmit: createFolder },
        h("input", { value: folderName, onChange: (event: any) => setFolderName(event.target.value), placeholder: "新文件夹名称", disabled: !loggedIn }),
        h("button", { type: "submit", className: "primary-btn", disabled: !loggedIn || !folderName.trim() }, "新建文件夹"),
      ),
      !loggedIn ? h(EmptyState, { title: "等待授权", text: "登录后通过 /api/files 读取工作目录文件列表" }) : files.length === 0 ? h(EmptyState, { title: "目录为空", text: "可以从 staging 目录上传文件或新建文件夹" }) :
        h("div", { className: "table-wrap", "data-testid": "baidu-netdisk-file-table" }, h("table", null,
          h("thead", null, h("tr", null, h("th", null, "名称"), h("th", null, "类型"), h("th", null, "大小"), h("th", null, "修改时间"), h("th", null, "fs_id"), h("th", null, "操作"))),
          h("tbody", null, files.map((file: any) => h("tr", { key: file.fsId || file.path },
            h("td", null, h("strong", null, file.serverFilename || file.path), h("code", null, file.path || "--")),
            h("td", null, h(StatusBadge, { status: file.isDir ? "queued" : "private" }, file.isDir ? "DIR" : "FILE")),
            h("td", null, file.isDir ? "--" : fmtBytes(file.size)),
            h("td", null, file.serverMtime ? fmtDate(file.serverMtime * 1000) : "--"),
            h("td", null, h("code", null, file.fsId || "--")),
            h("td", null, h("div", { className: "inline-actions" },
              file.isDir ? h("button", { type: "button", className: "ghost-btn", onClick: () => { setCurrentDir(file.path); void loadFiles(file.path); } }, "打开") :
                h("button", { type: "button", className: "ghost-btn", onClick: () => setDownloadForm((prev: any) => ({ ...prev, fsId: file.fsId })) }, "填入下载"),
              h("button", { type: "button", className: "ghost-btn", onClick: () => deleteRemote(file.path), disabled: state.actionLoading }, "删除"),
            )),
          ))),
        )),
    ),
    h("div", { className: "baidu-netdisk-grid" },
      h(Panel, {
        title: "配置与文档",
        eyebrow: "Deployment References",
        className: "baidu-docs-panel",
        actions: h("div", { className: "panel-actions inline-actions" },
          h("a", { className: "ghost-btn", href: "/docs/issue/baidu-netdisk-env-setup.md", target: "_blank", rel: "noreferrer" }, "打开环境配置"),
          h("a", { className: "ghost-btn", href: "/docs/issue/baidu-netdisk-user-service.md", target: "_blank", rel: "noreferrer" }, "打开服务方案"),
        ),
      },
        h("p", { className: "muted paragraph" }, configured
          ? "OAuth 运行时变量已配置；如需轮换密钥、迁移部署或排查代理边界，可直接打开下面的项目内文档。"
          : "首次使用请先按环境变量配置文档填入百度应用 client id / secret，然后重建 baidu-netdisk 服务并刷新本页。"),
        h("div", { className: "baidu-doc-grid", "data-testid": "baidu-netdisk-doc-links" },
          h(DocLinkCard, {
            title: "环境变量配置",
            text: "填写 UNIDESK_BAIDU_NETDISK_CLIENT_ID、CLIENT_SECRET、TOKEN_KEY，并执行重建与健康检查。",
            href: "/docs/issue/baidu-netdisk-env-setup.md",
            badge: "SETUP",
            testId: "baidu-netdisk-env-doc-card",
          }),
          h(DocLinkCard, {
            title: "服务方案与 API",
            text: "说明 OAuth Device Code、根目录工作区、staging 上传下载任务和后端 API 设计。",
            href: "/docs/issue/baidu-netdisk-user-service.md",
            badge: "DESIGN",
          }),
          h(DocLinkCard, {
            title: "用户服务安全边界",
            text: "查看 UniDesk microservice 私有代理、允许路径、frontendOnly 和密钥边界规则。",
            href: "/docs/reference/microservices.md",
            badge: "REF",
          }),
          h(DocLinkCard, {
            title: "部署与重建流程",
            text: "查看 server rebuild、Compose 编排、健康检查和交付验证的长期规则。",
            href: "/docs/reference/deployment.md",
            badge: "DEPLOY",
          }),
          h(DocLinkCard, {
            title: "CLI 验证命令",
            text: "查看 microservice health/proxy、server rebuild、job status 等命令入口。",
            href: "/docs/reference/cli.md",
            badge: "CLI",
          }),
          h(DocLinkCard, {
            title: "百度设备码模式",
            text: "打开百度官方 OAuth Device Code 文档，对照扫码登录和轮询参数。",
            href: "https://pan.baidu.com/union/doc/fl1x114ti",
            badge: "OFFICIAL",
          }),
        ),
      ),
      h(Panel, {
        title: "设备码登录",
        eyebrow: "OAuth Device Code",
        className: "baidu-login-panel",
        loading: state.actionLoading,
        actions: h("div", { className: "panel-actions inline-actions" },
          h("button", { type: "button", className: "primary-btn", onClick: startLogin, disabled: state.actionLoading || !configured, "data-testid": "baidu-netdisk-start-login" }, "生成二维码"),
          deviceSession?.id ? h("button", { type: "button", className: "ghost-btn", onClick: () => pollLogin(true), disabled: state.actionLoading }, "检查状态") : null,
          loggedIn ? h("button", { type: "button", className: "ghost-btn", onClick: logout, disabled: state.actionLoading }, "清除本地登录") : null,
          h(RawButton, { title: "Baidu Device Session", data: deviceSession || auth.latestSession, onOpen: onRaw, testId: "raw-baidu-device-session" }),
        ),
      },
        h("div", { className: "baidu-login-card", "data-testid": "baidu-netdisk-login-card" },
          h("div", { className: "baidu-qr-frame" },
            deviceSession?.qrcodeUrl
              ? h("img", { src: deviceSession.qrcodeUrl, alt: "百度网盘设备码授权二维码", "data-testid": "baidu-netdisk-qrcode" })
              : h(EmptyState, { title: configured ? "等待二维码" : "OAuth 未配置", text: configured ? "点击生成二维码后使用百度网盘或百度 App 扫码" : "设置 client id、secret 和 token key 后重建服务" }),
          ),
          h("div", { className: "claudeqq-login-copy" },
            h("div", { className: "node-version-line" },
              h(StatusBadge, { status: loggedIn ? "online" : deviceSession?.status === "pending" ? "warn" : "unknown" }, loggedIn ? "已登录" : deviceSession?.status || "未开始"),
              h("span", null, deviceSession?.secondsRemaining !== undefined ? `${deviceSession.secondsRemaining}s` : "--"),
              h("span", null, "scope basic,netdisk"),
            ),
            h("p", { className: "muted paragraph" }, loggedIn
              ? "access token / refresh token 已加密保存到 PostgreSQL；前端只看到脱敏登录态。"
              : "后端使用百度 OAuth Device Code 轮询换取 token；二维码过期后重新生成即可。"),
            h("div", { className: "microservice-ref-card" }, h("span", null, "User Code"), h("strong", null, deviceSession?.userCode || "--"), h("code", null, deviceSession?.verificationUrl || "https://openapi.baidu.com/device")),
            h("div", { className: "microservice-ref-card" }, h("span", null, "Expires"), h("strong", null, deviceSession?.expiresAt ? fmtDate(deviceSession.expiresAt) : "--"), h("code", null, deviceSession?.error || "no token exposed")),
          ),
        ),
      ),
      h(Panel, { title: "账号与容量", eyebrow: state.refreshedAt ? `Updated ${fmtClock(state.refreshedAt)}` : "Account", loading: state.loading,
        actions: h("div", { className: "panel-actions inline-actions" }, h(RawButton, { title: "Baidu Account", data: account, onOpen: onRaw, testId: "raw-baidu-account" })),
      },
        account ? h("div", { className: "baidu-account-card" },
          h("div", { className: "node-version-line" }, h(StatusBadge, { status: "online" }, "connected"), h("span", null, account.baiduUid || "--"), h("span", null, `VIP ${account.vipType ?? "--"}`)),
          h("h3", null, account.username || "Baidu Netdisk"),
          h("p", { className: "muted paragraph" }, `工作目录固定在 ${account.rootPath || appRoot}；v1 上传/下载只读写容器 staging 目录，不把大文件字节流穿过 UniDesk proxy。`),
          h("div", { className: "quota-bar" }, h("span", { style: { width: `${Math.max(0, Math.min(100, Number(quota.usedPercent || 0)))}%` } })),
          h("div", { className: "microservice-ref-card" }, h("span", null, "Quota"), h("strong", null, `${fmtBytes(quota.used)} / ${fmtBytes(quota.total)}`), h("code", null, `${quota.usedPercent || 0}% used`)),
        ) : h(EmptyState, { title: "尚未登录", text: "扫码授权后这里会显示账号、UID、会员状态和容量" }),
      ),
      h(Panel, { title: "传输任务", eyebrow: "staging path jobs", className: "baidu-transfers-panel", loading: state.actionLoading,
        actions: h("div", { className: "panel-actions inline-actions" },
          h("button", { type: "button", className: "primary-btn", onClick: runSelfTest, disabled: !loggedIn || state.actionLoading, "data-testid": "baidu-netdisk-self-test" }, "运行自测"),
          h("button", { type: "button", className: "ghost-btn", onClick: loadTransfers }, "刷新任务"),
          h(RawButton, { title: "Baidu Transfers", data: state.transfers, onOpen: onRaw, testId: "raw-baidu-transfers" }),
        ),
      },
        h("div", { className: "baidu-transfer-forms" },
          h("form", { className: "stack-form", onSubmit: submitUpload, "data-testid": "baidu-upload-form" },
            h("label", null, "容器 staging 文件", h("input", { value: uploadForm.localPath, onChange: (event: any) => setUploadForm((prev: any) => ({ ...prev, localPath: event.target.value })), placeholder: "sample.txt" })),
            h("label", null, "百度网盘目标路径", h("input", { value: uploadForm.remotePath, onChange: (event: any) => setUploadForm((prev: any) => ({ ...prev, remotePath: event.target.value })), placeholder: pathJoin(appRoot, "sample.txt") })),
            h("button", { type: "submit", className: "primary-btn", disabled: !loggedIn || state.actionLoading }, "上传 staging 文件"),
          ),
          h("form", { className: "stack-form", onSubmit: submitDownload, "data-testid": "baidu-download-form" },
            h("label", null, "文件 fs_id", h("input", { value: downloadForm.fsId, onChange: (event: any) => setDownloadForm((prev: any) => ({ ...prev, fsId: event.target.value })), placeholder: "从文件表填入" })),
            h("label", null, "保存到 staging 路径", h("input", { value: downloadForm.localPath, onChange: (event: any) => setDownloadForm((prev: any) => ({ ...prev, localPath: event.target.value })), placeholder: "downloads/" })),
            h("button", { type: "submit", className: "primary-btn", disabled: !loggedIn || !downloadForm.fsId || state.actionLoading }, "下载到 staging"),
          ),
        ),
        state.selfTest ? h("div", { className: "baidu-account-card", "data-testid": "baidu-netdisk-self-test-result" },
          h("div", { className: "node-version-line" },
            h(StatusBadge, { status: state.selfTest.ok ? "online" : "warn" }, state.selfTest.ok ? "self-test ok" : "self-test"),
            h("span", null, fmtBytes(state.selfTest.sizeBytes)),
          ),
          h("h3", null, state.selfTest.remotePath || "Baidu self-test"),
          h("div", { className: "microservice-ref-card" }, h("span", null, "fs_id"), h("strong", null, state.selfTest.fsId || "--"), h("code", null, state.selfTest.downloadedPath || "--")),
          h("div", { className: "microservice-ref-card" }, h("span", null, "MD5"), h("strong", null, state.selfTest.downloadedMd5 || "--"), h("code", null, state.selfTest.expectedMd5 || "--")),
          h(RawButton, { title: "Baidu Self Test", data: state.selfTest, onOpen: onRaw, testId: "raw-baidu-self-test" }),
        ) : null,
        jobs.length === 0 ? h(EmptyState, { title: "暂无传输任务", text: "上传/下载任务会在后端容器内执行，避免大文件穿过 UniDesk proxy" }) :
          h("div", { className: "table-wrap", "data-testid": "baidu-transfer-table" }, h("table", null,
            h("thead", null, h("tr", null, h("th", null, "状态"), h("th", null, "方向"), h("th", null, "路径"), h("th", null, "进度"), h("th", null, "时间"), h("th", null, "操作"))),
            h("tbody", null, jobs.map((job: any) => h("tr", { key: job.id },
              h("td", null, h(StatusBadge, { status: job.status }, job.status)),
              h("td", null, job.direction),
              h("td", null, h("strong", null, job.remotePath || job.fsId || "--"), h("code", null, job.localPath || "--"), job.error ? h("span", { className: "form-error" }, job.error) : null),
              h("td", null, h(ProgressBar, { percent: job.progressPercent }), h("span", { className: "muted" }, `${fmtBytes(job.bytesDone)} / ${fmtBytes(job.sizeBytes)}`)),
              h("td", null, fmtDate(job.updatedAt)),
              h("td", null, h("div", { className: "inline-actions" },
                ["queued", "running"].includes(job.status) ? h("button", { type: "button", className: "ghost-btn", onClick: () => transferAction(job.id, "cancel") }, "取消") : null,
                ["failed", "canceled"].includes(job.status) ? h("button", { type: "button", className: "ghost-btn", onClick: () => transferAction(job.id, "retry") }, "重试") : null,
                h(RawButton, { title: `Transfer ${job.id}`, data: job, onOpen: onRaw }),
              )),
            ))),
          )),
      ),
      h(Panel, { title: "安全与日志", eyebrow: "redacted diagnostics", className: "baidu-wide-panel", loading: state.loading,
        actions: h("div", { className: "panel-actions inline-actions" }, h(RawButton, { title: "Baidu Health", data: health, onOpen: onRaw, testId: "raw-baidu-health" }), h(RawButton, { title: "Baidu Logs", data: state.logs, onOpen: onRaw, testId: "raw-baidu-logs" })),
      },
        h("div", { className: "policy-grid" },
          h("article", null, h("b", null, "私有后端"), h("span", null, "4244 只在 Compose 网络 expose，浏览器经 UniDesk 同源代理访问")),
          h("article", null, h("b", null, "Token 加密"), h("span", null, "access/refresh token 使用 BAIDU_NETDISK_TOKEN_KEY 加密后写入 PostgreSQL")),
          h("article", null, h("b", null, "无浏览器大文件流"), h("span", null, "上传/下载以容器 staging 目录为边界，避免 proxy 文本通道传输大字节流")),
        ),
      ),
    ),
  );
}
