(function () {
  "use strict";

  const cfg = window.ADMIN_APP_CONFIG || {};
  const root = document.getElementById("admin-app");

  if (!root) {
    return;
  }

  const state = {
    token: readToken(),
    user: null,
    route: "overview",
    busy: false,
    message: "",
    messageType: "info",
    modal: null,
    configTab: "site",
    sidebarGroups: {
      dashboard: true,
      infrastructure: true,
      business: true,
      operations: true,
      system: true
    },
    pagination: {},
    dashboard: null,
    system: null,
    config: null,
    nodes: [],
    groups: [],
    routes: [],
    plans: [],
    orders: { list: [], pagination: null },
    coupons: [],
    users: { list: [], pagination: null },
    tickets: { list: [], pagination: null },
    realname: { list: [], pagination: null },
    devices: { list: [], pagination: null },
    ipv6: { list: [], pagination: null },
    expandedNodes: new Set(),
    prevUser: null,
    prevRoute: null
  };

  const ROUTE_META = {
    overview: { title: "总览", description: "查看收入、用户和流量概况。" },
    "dashboard-node": { title: "节点状态", description: "查看节点在线状态、负载和推送情况。" },
    "node-manage": { title: "节点管理", description: "管理服务节点、可见性以及父子节点关系。" },
    "node-group": { title: "权限组", description: "管理节点权限组和用户分组映射。" },
    "node-route": { title: "路由规则", description: "维护节点路由匹配规则。" },
    "plan-manage": { title: "套餐管理", description: "维护套餐、流量和价格配置。" },
    "order-manage": { title: "订单管理", description: "处理待支付和已支付订单。" },
    "coupon-manage": { title: "优惠券", description: "创建和维护优惠券信息。" },
    "user-manage": { title: "用户管理", description: "查看用户订阅、流量和封禁状态。" },
    "ticket-manage": { title: "工单中心", description: "查看用户工单和处理状态。" },
    realname: { title: "实名认证", description: "审核实名记录和同步状态。" },
    "user-online-devices": { title: "在线设备", description: "查看用户在线 IP 和设备分布。" },
    "user-ipv6-subscription": { title: "IPv6 子账号", description: "管理 IPv6 阴影账号与密码同步。" },
    "system-config": { title: "系统设置", description: "编辑站点、订阅和安全参数。" }
  };

  state.route = normalizeRoute(readRoute());

  boot();

  async function boot() {
    window.addEventListener("hashchange", async function () {
      state.route = normalizeRoute(readRoute());
      state.modal = null;
      await hydrateRoute();
    });

    root.addEventListener("click", onClick);
    root.addEventListener("submit", onSubmit);

    // Initialize shell and modal containers
    root.innerHTML = '<div id="admin-shell-container"></div><div id="admin-modal-container"></div><div id="admin-busy-container"></div>';

    if (state.token) {
      await loadBootstrap();
    } else {
      render();
    }

    if (state.user) {
      await hydrateRoute();
    } else {
      render();
    }
  }

  async function loadBootstrap() {
    try {
      setBusy(true);
      const loginCheck = unwrap(await request("/api/v1/user/checkLogin", { method: "GET" }));
      if (!loginCheck || !loginCheck.is_admin) {
        clearSession();
        return;
      }

      state.user = loginCheck;
      const [config, system] = await Promise.all([
        request(cfg.api.adminConfig, { method: "GET" }),
        request(cfg.api.systemStatus, { method: "GET" })
      ]);
      state.config = unwrap(config) || {};
      state.system = unwrap(system) || {};
    } catch (error) {
      console.error("bootstrap failed", error);
      clearSession();
      show(error.message || "管理端初始化失败", "error");
    } finally {
      setBusy(false);
      render();
    }
  }

  async function hydrateRoute() {
    if (!state.user) {
      render();
      return;
    }

    try {
      setBusy(true);
      const page = getCurrentPage();

      if (state.route === "overview") {
        state.dashboard = unwrap(await request(cfg.api.dashboardSummary));
      } else if (state.route === "dashboard-node") {
        const [dashboard, nodes] = await Promise.all([
          request(cfg.api.dashboardSummary),
          request(cfg.api.serverNodes)
        ]);
        state.dashboard = unwrap(dashboard) || {};
        state.nodes = toArray(unwrap(nodes));
      } else if (state.route === "node-manage") {
        const [nodes, groups] = await Promise.all([
          request(cfg.api.serverNodes),
          request(cfg.api.serverGroups)
        ]);
        state.nodes = toArray(unwrap(nodes));
        state.groups = toArray(unwrap(groups));
      } else if (state.route === "node-group") {
        state.groups = toArray(unwrap(await request(cfg.api.serverGroups)));
      } else if (state.route === "node-route") {
        state.routes = toArray(unwrap(await request(cfg.api.serverRoutes)));
      } else if (state.route === "plan-manage") {
        const [plans, groups] = await Promise.all([
          request(cfg.api.plans),
          request(cfg.api.serverGroups)
        ]);
        state.plans = toArray(unwrap(plans));
        state.groups = toArray(unwrap(groups));
      } else if (state.route === "order-manage") {
        const payload = await request(`${cfg.api.orders}?page=${page}&per_page=20`);
        state.orders = normalizeListPayload(payload);
      } else if (state.route === "coupon-manage") {
        state.coupons = toArray(unwrap(await request(cfg.api.coupons)));
      } else if (state.route === "user-manage") {
        const [users, plans, groups] = await Promise.all([
          request(`${cfg.api.users}?page=${page}&per_page=20`),
          request(cfg.api.plans),
          request(cfg.api.serverGroups)
        ]);
        state.users = normalizeListPayload(users);
        state.plans = toArray(unwrap(plans));
        state.groups = toArray(unwrap(groups));
      } else if (state.route === "ticket-manage") {
        const payload = await request(`${cfg.api.tickets}?page=${page}&per_page=20`);
        state.tickets = normalizeListPayload(payload);
      } else if (state.route === "realname") {
        const payload = await request(`${cfg.api.realnameBase}/records?page=${page}&per_page=20`);
        state.realname = normalizeListPayload(payload, "data");
      } else if (state.route === "user-online-devices") {
        const payload = await request(`${cfg.api.onlineDevices}?page=${page}&per_page=20`);
        state.devices = normalizeListPayload(payload);
      } else if (state.route === "user-ipv6-subscription") {
        const [payload, plans] = await Promise.all([
          request(`${cfg.api.ipv6Base}/users?page=${page}&per_page=20`),
          request(cfg.api.plans)
        ]);
        state.ipv6 = normalizeListPayload(payload);
        state.plans = toArray(unwrap(plans));
      } else if (state.route === "system-config") {
        state.config = unwrap(await request(cfg.api.adminConfig));
      }
    } catch (error) {
      console.error("route hydrate failed", error);
      show(error.message || "页面数据加载失败", "error");
    } finally {
      setBusy(false);
      render();
    }
  }

  async function onClick(event) {
    const actionEl = event.target.closest("[data-action]");
    if (!actionEl || state.busy) {
      return;
    }

    const action = actionEl.getAttribute("data-action");

    if (action === "nav") {
      window.location.hash = actionEl.getAttribute("data-route") || "overview";
      return;
    }

    if (action === "logout") {
      clearSession();
      render();
      return;
    }

    if (action === "refresh") {
      await loadBootstrap();
      await hydrateRoute();
      return;
    }

    if (action === "modal-close") {
      state.modal = null;
      render();
      return;
    }

    if (action === "sidebar-toggle") {
      const group = actionEl.getAttribute("data-id");
      state.sidebarGroups[group] = state.sidebarGroups[group] === false;
      render();
      return;
    }

    if (action === "config-tab") {
      state.configTab = actionEl.getAttribute("data-tab") || "site";
      render();
      return;
    }

    if (action === "page") {
      setCurrentPage(Number(actionEl.getAttribute("data-page")) || 1);
      await hydrateRoute();
      return;
    }

    if (action === "node-expand") {
      const id = String(actionEl.getAttribute("data-id"));
      if (state.expandedNodes.has(id)) {
        state.expandedNodes.delete(id);
      } else {
        state.expandedNodes.add(id);
      }
      render();
      return;
    }

    if (action === "plan-add") {
      state.modal = { type: "plan", data: {} };
      render();
      return;
    }

    if (action === "plan-edit") {
      const item = state.plans.find((row) => String(row.id) === actionEl.getAttribute("data-id"));
      state.modal = { type: "plan", data: item || {} };
      render();
      return;
    }

    if (action === "plan-delete") {
      event.preventDefault();
      event.stopPropagation();
      if (confirm("确认删除该套餐吗？")) {
        await adminPost(`${cfg.api.adminBase}/plan/drop`, { id: Number(actionEl.getAttribute("data-id")) });
        await hydrateRoute();
      }
      return;
    }

    if (action === "coupon-add") {
      state.modal = { type: "coupon", data: {} };
      render();
      return;
    }

    if (action === "coupon-delete") {
      event.preventDefault();
      event.stopPropagation();
      if (confirm("确认删除该优惠券吗？")) {
        await adminPost(`${cfg.api.adminBase}/coupon/drop`, { id: Number(actionEl.getAttribute("data-id")) });
        await hydrateRoute();
      }
      return;
    }

    if (action === "user-edit") {
      const item = state.users.list.find((row) => String(row.id) === actionEl.getAttribute("data-id"));
      state.modal = { type: "user", data: item || {} };
      render();
      return;
    }

    if (action === "user-ban" || action === "user-unban") {
      await adminPost(`${cfg.api.adminBase}/user/ban`, {
        id: Number(actionEl.getAttribute("data-id")),
        banned: action === "user-ban"
      });
      await hydrateRoute();
      return;
    }

    if (action === "user-reset-traffic") {
      await adminPost(`${cfg.api.adminBase}/user/resetTraffic`, {
        id: Number(actionEl.getAttribute("data-id"))
      });
      await hydrateRoute();
      return;
    }

    if (action === "order-paid") {
      event.preventDefault();
      event.stopPropagation();
      await adminPost(`${cfg.api.adminBase}/order/paid`, {
        trade_no: actionEl.getAttribute("data-trade")
      });
      await hydrateRoute();
      return;
    }

    if (action === "order-cancel") {
      event.preventDefault();
      event.stopPropagation();
      await adminPost(`${cfg.api.adminBase}/order/cancel`, {
        trade_no: actionEl.getAttribute("data-trade")
      });
      await hydrateRoute();
      return;
    }

    if (action === "node-add") {
      state.modal = { type: "node", data: {} };
      render();
      return;
    }

    if (action === "node-edit") {
      event.preventDefault();
      event.stopPropagation();
      const nodeId = String(actionEl.getAttribute("data-id"));
      const item = state.nodes.find((row) => String(row.id) === nodeId);
      state.modal = { type: "node", data: item || {} };
      render();
      return;
    }

    if (action === "node-copy") {
      event.preventDefault();
      event.stopPropagation();
      const nodeId = Number(actionEl.getAttribute("data-id"));
      try {
        await adminPost(`${cfg.api.adminBase}/server/manage/copy`, { id: nodeId });
      } catch (e) { /* adminPost already shows error */ }
      await hydrateRoute();
      return;
    }

    if (action === "node-delete") {
      event.preventDefault();
      event.stopPropagation();
      if (confirm("确认删除该节点吗？")) {
        const nodeId = Number(actionEl.getAttribute("data-id"));
        try {
          await adminPost(`${cfg.api.adminBase}/server/manage/drop`, { id: nodeId });
        } catch (e) { /* adminPost already shows error */ }
        await hydrateRoute();
      }
      return;
    }

    if (action === "node-toggle-visible") {
      event.preventDefault();
      event.stopPropagation();
      const nodeId = Number(actionEl.getAttribute("data-id"));
      const input = actionEl.querySelector("input");
      if (!input) {
        return;
      }
      const newShow = !input.checked;
      input.checked = newShow;
      try {
        await adminPost(`${cfg.api.adminBase}/server/manage/update`, {
          id: nodeId,
          show: newShow ? 1 : 0
        });
      } catch (e) { /* adminPost already shows error */ }
      await hydrateRoute();
      return;
    }

    if (action === "group-add") {
      state.modal = { type: "group", data: {} };
      render();
      return;
    }

    if (action === "group-edit") {
      const item = state.groups.find((row) => String(row.id) === actionEl.getAttribute("data-id"));
      state.modal = { type: "group", data: item || {} };
      render();
      return;
    }

    if (action === "group-delete") {
      if (confirm("确认删除该权限组吗？")) {
        await adminPost(`${cfg.api.adminBase}/server/group/drop`, {
          id: Number(actionEl.getAttribute("data-id"))
        });
        await hydrateRoute();
      }
      return;
    }

    if (action === "route-add") {
      state.modal = { type: "route", data: {} };
      render();
      return;
    }

    if (action === "route-edit") {
      const item = state.routes.find((row) => String(row.id) === actionEl.getAttribute("data-id"));
      state.modal = { type: "route", data: item || {} };
      render();
      return;
    }

    if (action === "route-delete") {
      if (confirm("确认删除该路由规则吗？")) {
        await adminPost(`${cfg.api.adminBase}/server/route/drop`, {
          id: Number(actionEl.getAttribute("data-id"))
        });
        await hydrateRoute();
      }
      return;
    }

    if (action === "realname-review") {
      const userId = actionEl.getAttribute("data-user-id");
      const status = actionEl.getAttribute("data-status");
      const reason = status === "rejected" ? prompt("请输入驳回原因，可留空：", "") || "" : "";
      await adminPost(`${cfg.api.realnameBase}/review/${userId}`, { status, reason });
      await hydrateRoute();
      return;
    }

    if (action === "approve-all") {
      await adminPost(`${cfg.api.realnameBase}/approve-all`, {});
      await hydrateRoute();
      return;
    }

    if (action === "sync-all") {
      await adminPost(`${cfg.api.realnameBase}/sync-all`, {});
      await hydrateRoute();
      return;
    }

    if (action === "ipv6-enable-modal") {
      const userId = actionEl.getAttribute("data-user-id");
      const userEmail = actionEl.getAttribute("data-email") || "";
      state.modal = { type: "ipv6-enable", data: { userId, email: userEmail } };
      render();
      return;
    }

    if (action === "ipv6-disable") {
      const userId = actionEl.getAttribute("data-user-id");
      if (confirm("确认关闭该用户的 IPv6 子账号？（软禁用，可恢复）")) {
        await adminPost(`${cfg.api.ipv6Base}/disable/${userId}`, {});
        await hydrateRoute();
      }
      return;
    }

    if (action === "ipv6-sync-password") {
      const userId = actionEl.getAttribute("data-user-id");
      await adminPost(`${cfg.api.ipv6Base}/sync-password/${userId}`, {});
      await hydrateRoute();
      return;
    }
  }

  async function onSubmit(event) {
    const form = event.target;
    const action = form.getAttribute("data-form");
    if (!action) {
      return;
    }

    event.preventDefault();

    if (action === "login") {
      try {
        setBusy(true);
        const payload = unwrap(await request("/api/v2/passport/auth/login", {
          method: "POST",
          auth: false,
          body: serializeForm(form)
        }));
        if (!payload || !payload.auth_data || !payload.is_admin) {
          throw new Error("当前账号没有管理员权限");
        }
        saveToken(payload.auth_data);
        state.token = readToken();
        await loadBootstrap();
        await hydrateRoute();
        show("登录成功", "success");
      } catch (error) {
        show(error.message || "登录失败", "error");
        render();
      } finally {
        setBusy(false);
      }
      return;
    }

    const body = serializeForm(form);
    let target = "";

    if (action === "plan-save") {
      target = `${cfg.api.adminBase}/plan/save`;
    } else if (action === "coupon-save") {
      target = `${cfg.api.adminBase}/coupon/save`;
    } else if (action === "user-save") {
      target = `${cfg.api.adminBase}/user/update`;
    } else if (action === "node-save") {
      target = `${cfg.api.adminBase}/server/manage/save`;
    } else if (action === "group-save") {
      target = `${cfg.api.adminBase}/server/group/save`;
    } else if (action === "route-save") {
      target = `${cfg.api.adminBase}/server/route/save`;
    } else if (action === "config-save") {
      target = `${cfg.api.adminBase}/config/save`;
    }

    if (!target) {
      if (action === "ipv6-enable-save") {
        const userId = body.user_id;
        const planId = Number(body.plan_id) || 0;
        await adminPost(`${cfg.api.ipv6Base}/enable/${userId}`, { plan_id: planId });
        state.modal = null;
        await hydrateRoute();
        return;
      }
      return;
    }

    await adminPost(target, body);
    if (action !== "config-save") {
      state.modal = null;
    }
    await hydrateRoute();
  }

  function render(force) {
    const shellContainer = document.getElementById("admin-shell-container");
    const modalContainer = document.getElementById("admin-modal-container");
    const busyContainer = document.getElementById("admin-busy-container");

    if (!shellContainer || !modalContainer || !busyContainer) return;

    // Re-render the shell if user or route changed, or if forced (e.g., data updated)
    if (force || state.user !== state.prevUser || state.route !== state.prevRoute) {
      shellContainer.innerHTML = state.user ? renderDashboard() : renderLogin();
      state.prevUser = state.user;
      state.prevRoute = state.route;
    }

    // Handle Modal independently
    if (state.modal) {
      modalContainer.innerHTML = `<div class="modal-overlay">${renderModalContent()}</div>`;
    } else {
      modalContainer.innerHTML = "";
    }

    // Handle Busy overlay independently
    if (state.busy) {
      busyContainer.innerHTML = '<div class="busy-overlay"><div class="busy-spinner">正在处理...</div></div>';
    } else {
      busyContainer.innerHTML = "";
    }
  }

  function renderLogin() {
    return [
      '<div class="login-container">',
      '<div class="login-card">',
      '<div class="login-header">',
      `<h1>${escapeHtml(cfg.title || "SingBox 管理后台")}</h1>`,
      '<p>使用管理员账号登录 Go 重构后的控制台</p>',
      "</div>",
      state.message ? renderNotice() : "",
      '<form data-form="login" class="login-form">',
      '<div class="login-field"><label>邮箱</label><div class="input-wrapper"><input type="email" name="email" placeholder="admin@example.com" required autocomplete="email" /></div></div>',
      '<div class="login-field"><label>密码</label><div class="input-wrapper"><input type="password" name="password" placeholder="请输入密码" required autocomplete="current-password" /></div></div>',
      '<button type="submit" class="btn btn-primary btn-login">登录管理后台</button>',
      "</form>",
      "</div>",
      "</div>"
    ].join("");
  }

  function renderDashboard() {
    return [
      '<div class="admin-shell">',
      renderSidebar(),
      '<main class="admin-main">',
      renderTopbar(),
      '<div class="page-shell">',
      state.message ? renderNotice() : "",
      renderMainContent(),
      "</div>",
      "</main>",
      "</div>"
    ].join("");
  }

  function renderSidebar() {
    return [
      '<aside class="admin-sidebar">',
      '<div class="sidebar-header">',
      '<div class="sidebar-brand">',
      `<strong>${escapeHtml(cfg.title || "Admin")}</strong>`,
      `<span>Go Control Plane v${escapeHtml(cfg.version || "1.0.0")}</span>`,
      "</div>",
      "</div>",
      '<div class="sidebar-nav">',
      renderSidebarGroup("dashboard", "概览", [
        navItem("overview", "总览", "收入、用户、流量"),
        navItem("dashboard-node", "节点状态", "实时在线与负载")
      ]),
      renderSidebarGroup("infrastructure", "基础设施", [
        navItem("node-manage", "节点管理", "服务节点与层级"),
        navItem("node-group", "权限组", "套餐与节点分组"),
        navItem("node-route", "路由规则", "流量匹配动作")
      ]),
      renderSidebarGroup("business", "运营", [
        navItem("plan-manage", "套餐管理", "流量与价格"),
        navItem("order-manage", "订单管理", "支付与开通"),
        navItem("coupon-manage", "优惠券", "营销优惠")
      ]),
      renderSidebarGroup("operations", "用户", [
        navItem("user-manage", "用户管理", "账号、订阅、流量"),
        navItem("realname", "实名认证", "实名审核"),
        navItem("user-online-devices", "在线设备", "在线 IP 与会话"),
        navItem("user-ipv6-subscription", "IPv6 子账号", "开通与密码同步"),
        navItem("ticket-manage", "工单中心", "用户支持")
      ]),
      renderSidebarGroup("system", "系统", [
        navItem("system-config", "系统设置", "站点与安全参数")
      ]),
      "</div>",
      '<div class="sidebar-footer">',
      '<button class="btn btn-secondary sidebar-footer-btn" data-action="logout">退出登录</button>',
      "</div>",
      "</aside>"
    ].join("");
  }

  function renderSidebarGroup(id, label, items) {
    const expanded = state.sidebarGroups[id] !== false;
    return [
      '<div class="sidebar-nav-group">',
      `<button class="sidebar-nav-item-header" data-action="sidebar-toggle" data-id="${escapeHtml(id)}">`,
      `<span>${escapeHtml(label)}</span>`,
      `<span class="sidebar-arrow ${expanded ? "expanded" : ""}">›</span>`,
      "</button>",
      `<div class="sidebar-submenu ${expanded ? "" : "collapsed"}">`,
      items.join(""),
      "</div>",
      "</div>"
    ].join("");
  }

  function navItem(route, title, desc) {
    const active = state.route === route ? "active" : "";
    return [
      `<a class="sidebar-item ${active}" data-action="nav" data-route="${escapeHtml(route)}" href="#${escapeHtml(route)}">`,
      `<strong>${escapeHtml(title)}</strong>`,
      `<span>${escapeHtml(desc)}</span>`,
      "</a>"
    ].join("");
  }

  function renderTopbar() {
    const meta = ROUTE_META[state.route] || {
      title: getRouteTitle(state.route),
      description: "管理后台页面"
    };
    return [
      '<header class="topbar card">',
      '<div class="topbar-copy">',
      `<h1>${escapeHtml(meta.title)}</h1>`,
      `<p>${escapeHtml(meta.description)}</p>`,
      '<div class="topbar-meta">',
      `<span class="topbar-chip">路径 /${escapeHtml(getSecurePath())}</span>`,
      `<span class="topbar-chip">${escapeHtml(state.user.email || "")}</span>`,
      `<span class="topbar-chip">${escapeHtml(formatDate(state.system && state.system.server_time))}</span>`,
      "</div>",
      "</div>",
      '<div class="toolbar"><button class="btn btn-secondary" data-action="refresh">刷新数据</button></div>',
      "</header>"
    ].join("");
  }

  function renderMainContent() {
    if (state.route === "overview") return renderOverview();
    if (state.route === "dashboard-node") return renderDashboardNodes();
    if (state.route === "node-manage") return renderNodeManage();
    if (state.route === "node-group") return renderNodeGroup();
    if (state.route === "node-route") return renderNodeRoute();
    if (state.route === "plan-manage") return renderPlanManage();
    if (state.route === "order-manage") return renderOrderManage();
    if (state.route === "coupon-manage") return renderCouponManage();
    if (state.route === "user-manage") return renderUserManage();
    if (state.route === "ticket-manage") return renderTicketManage();
    if (state.route === "realname") return renderRealnameManage();
    if (state.route === "user-online-devices") return renderOnlineDevices();
    if (state.route === "user-ipv6-subscription") return renderIPv6Manage();
    if (state.route === "system-config") return renderSystemConfig();
    return renderOverview();
  }

  function renderOverview() {
    const dash = state.dashboard || {};
    return [
      '<div class="grid grid-3">',
      statCard("今日收入", formatMoney(dash.todayIncome), `${formatSignedPercent(dash.dayIncomeGrowth)} 较昨日`),
      statCard("本月收入", formatMoney(dash.currentMonthIncome), `${formatSignedPercent(dash.monthIncomeGrowth)} 较上月`),
      statCard("总用户", String(dash.totalUsers || 0), `本月新增 ${dash.currentMonthNewUsers || 0}`),
      statCard("在线用户", String(dash.onlineUsers || 0), `在线设备 ${dash.onlineDevices || 0}`),
      statCard("待处理工单", String(dash.ticketPendingTotal || 0), `在线节点 ${dash.onlineNodes || 0}`),
      statCard("总流量", formatTraffic(dash.totalTraffic && dash.totalTraffic.total), `今日 ${formatTraffic(dash.todayTraffic && dash.todayTraffic.total)}`),
      "</div>",
      '<section class="card">',
      "<h2>运行概况</h2>",
      '<div class="grid grid-3 compact-grid">',
      summaryItem("应用名称", dash.app_name || cfg.title || "XBoard"),
      summaryItem("管理路径", dash.secure_path || getSecurePath()),
      summaryItem("服务器时间", formatDate(dash.server_time)),
      summaryItem("活跃用户", String(dash.activeUsers || 0)),
      summaryItem("月流量", formatTraffic(dash.monthTraffic && dash.monthTraffic.total)),
      summaryItem("用户增长", formatSignedPercent(dash.userGrowth)),
      "</div>",
      "</section>"
    ].join("");
  }

  function renderDashboardNodes() {
    const rows = (state.nodes || []).map((node) => [
      `<code>${node.id}</code>`,
      escapeHtml(node.name || "-"),
      escapeHtml(node.type || "-"),
      renderStatus(node.available_status || "offline"),
      escapeHtml(`${formatTraffic(node.u)} / ${formatTraffic(node.d)}`),
      escapeHtml(formatDate(node.last_push_at || node.last_check_at))
    ]);
    return wrapTable(
      ["ID", "节点", "类型", "状态", "上下行", "最后心跳"],
      rows
    );
  }

  function renderNodeManage() {
    const isRoot = (node) => !node.parent_id || String(node.parent_id) === "0";
    const roots = state.nodes.filter(isRoot);
    const childrenByParent = {};
    state.nodes.forEach((node) => {
      if (node.parent_id) {
        childrenByParent[node.parent_id] = childrenByParent[node.parent_id] || [];
        childrenByParent[node.parent_id].push(node);
      }
    });

    const rows = [];
    roots.forEach((node) => {
      const children = childrenByParent[node.id] || [];
      const expanded = state.expandedNodes.has(String(node.id));
      rows.push(renderNodeRow(node, false, children.length > 0, expanded));
      if (expanded) {
        children.forEach((child) => rows.push(renderNodeRow(child, true, false, false)));
      }
    });

    return [
      '<div class="toolbar toolbar-spaced">',
      '<button class="btn btn-primary" data-action="node-add">新增节点</button>',
      "</div>",
      wrapTable(["ID", "名称 / 主机", "类型", "倍率", "显示", "操作"], rows)
    ].join("");
  }

  function renderNodeRow(node, isChild, hasChildren, expanded) {
    const toggle = hasChildren
      ? `<button class="node-toggle" data-action="node-expand" data-id="${node.id}">${expanded ? "−" : "+"}</button>`
      : '<span class="node-toggle node-toggle-placeholder"></span>';
    const relationCell = isChild && node.parent_id
      ? `<span class="relation-chip"><code>${escapeHtml(node.id)}</code><span class="relation-arrow">&rarr;</span><code>${escapeHtml(node.parent_id)}</code></span>`
      : `<code>${node.id}</code>`;
    return {
      className: isChild ? "node-child" : "",
      cells: [
        relationCell,
        [
          '<div class="node-name-block">',
          toggle,
          `<div><strong>${escapeHtml(node.name || "-")}</strong><div class="subtle-text">${escapeHtml(node.host || "-")}</div></div>`,
          "</div>"
        ].join(""),
        escapeHtml(node.type || "-"),
        escapeHtml(`${node.rate || 1}x`),
        [
          '<div class="switch-row">',
          renderStatus(node.show ? "visible" : "hidden"),
          `<label class="switch" data-action="node-toggle-visible" data-id="${node.id}"><input type="checkbox" ${node.show ? "checked" : ""}><span class="slider"></span></label>`,
          "</div>"
        ].join(""),
        renderActionRow([
          buttonAction("编辑", "node-edit", node.id),
          buttonAction("复制", "node-copy", node.id),
          buttonAction("删除", "node-delete", node.id)
        ])
      ]
    };
  }

  function renderNodeGroup() {
    const rows = state.groups.map((group) => [
      `<code>${group.id}</code>`,
      escapeHtml(group.name || "-"),
      `<code>${group.server_count || 0}</code>`,
      `<code>${group.user_count || 0}</code>`,
      renderActionRow([
        buttonAction("编辑", "group-edit", group.id),
        buttonAction("删除", "group-delete", group.id)
      ])
    ]);

    return [
      '<div class="toolbar toolbar-spaced"><button class="btn btn-primary" data-action="group-add">新增权限组</button></div>',
      wrapTable(["ID", "名称", "节点数", "用户数", "操作"], rows)
    ].join("");
  }

  function renderNodeRoute() {
    const rows = state.routes.map((route) => [
      `<code>${route.id}</code>`,
      escapeHtml(route.remarks || "-"),
      escapeHtml((route.match || []).join(", ")),
      escapeHtml(route.action || "-"),
      renderActionRow([
        buttonAction("编辑", "route-edit", route.id),
        buttonAction("删除", "route-delete", route.id)
      ])
    ]);

    return [
      '<div class="toolbar toolbar-spaced"><button class="btn btn-primary" data-action="route-add">新增路由</button></div>',
      wrapTable(["ID", "备注", "匹配规则", "动作", "操作"], rows)
    ].join("");
  }

  function renderPlanManage() {
    const rows = state.plans.map((plan) => [
      `<code>${plan.id}</code>`,
      escapeHtml(plan.name || "-"),
      escapeHtml(plan.group_name || "-"),
      escapeHtml(formatTraffic(plan.transfer_enable)),
      `<code>${escapeHtml(plan.prices || "{}")}</code>`,
      renderStatus(plan.show ? "visible" : "hidden"),
      renderActionRow([
        buttonAction("编辑", "plan-edit", plan.id),
        buttonAction("删除", "plan-delete", plan.id)
      ])
    ]);

    return [
      '<div class="toolbar toolbar-spaced"><button class="btn btn-primary" data-action="plan-add">新增套餐</button></div>',
      wrapTable(["ID", "套餐名称", "权限组", "流量", "价格", "状态", "操作"], rows)
    ].join("");
  }

  function renderOrderManage() {
    const rows = state.orders.list.map((order) => [
      `<code>${escapeHtml(order.trade_no)}</code>`,
      escapeHtml(order.user_email || `#${order.user_id}`),
      escapeHtml((order.plan && order.plan.name) || "-"),
      formatMoney(order.total_amount),
      renderStatus(orderStatusText(order.status)),
      renderActionRow(
        order.status === 0
          ? [
              buttonAction("标记已支付", "order-paid", null, `data-trade="${escapeHtml(order.trade_no)}"`),
              buttonAction("取消", "order-cancel", null, `data-trade="${escapeHtml(order.trade_no)}"`)
            ]
          : ["-"]
      )
    ]);

    return [
      wrapTable(["订单号", "用户", "套餐", "金额", "状态", "操作"], rows),
      renderPagination(state.orders.pagination)
    ].join("");
  }

  function renderCouponManage() {
    const rows = state.coupons.map((coupon) => [
      `<code>${coupon.id}</code>`,
      escapeHtml(coupon.name || "-"),
      `<strong>${escapeHtml(coupon.code || "-")}</strong>`,
      escapeHtml(coupon.type === 1 ? "固定金额" : "比例折扣"),
      escapeHtml(coupon.type === 1 ? formatMoney(coupon.value) : `${coupon.value || 0}%`),
      renderActionRow([buttonAction("删除", "coupon-delete", coupon.id)])
    ]);

    return [
      '<div class="toolbar toolbar-spaced"><button class="btn btn-primary" data-action="coupon-add">新增优惠券</button></div>',
      wrapTable(["ID", "名称", "编码", "类型", "面额", "操作"], rows)
    ].join("");
  }

  function renderUserManage() {
    const rows = state.users.list.map((user) => [
      user.parent_id ? renderRelationChip(user.parent_id, user.id) : `<code>${user.id}</code>`,
      [
        `<strong>${escapeHtml(user.email || "-")}</strong>`,
        user.parent_id ? `<div class="subtle-text">${renderRelationChip(user.parent_id, user.id)}</div>` : "",
        user.online_ip ? `<div class="subtle-text">在线 IP: ${escapeHtml(user.online_ip)}</div>` : "",
        `<div class="subtle-text">实名: ${escapeHtml(user.realname_label || user.realname_status || "-")}</div>`,
        user.ipv6_enabled ? `<div class="subtle-text">IPv6: ${renderRelationChip(user.id, user.ipv6_shadow_id)}</div>` : ""
      ].join(""),
      renderStatus(user.banned ? "banned" : "active"),
      escapeHtml(`${formatTraffic((user.u || 0) + (user.d || 0))} / ${formatTraffic(user.transfer_enable)}`),
      escapeHtml(formatDate(user.expired_at)),
      renderActionRow([
        buttonAction("编辑", "user-edit", user.id),
        buttonAction("重置流量", "user-reset-traffic", user.id),
        buttonAction(user.banned ? "解封" : "封禁", user.banned ? "user-unban" : "user-ban", user.id)
      ])
    ]);

    return [
      wrapTable(["ID", "邮箱", "状态", "流量", "到期时间", "操作"], rows),
      renderPagination(state.users.pagination)
    ].join("");
  }

  function renderTicketManage() {
    const rows = state.tickets.list.map((ticket) => [
      `<code>${ticket.id}</code>`,
      escapeHtml(ticket.user_email || `#${ticket.user_id}`),
      escapeHtml(ticket.subject || "-"),
      renderStatus(ticketStatusText(ticket.status)),
      escapeHtml(formatDate(ticket.updated_at || ticket.created_at)),
      `<code>${ticket.message_count || 0}</code>`
    ]);

    return [
      wrapTable(["ID", "用户", "主题", "状态", "更新时间", "消息数"], rows),
      renderPagination(state.tickets.pagination)
    ].join("");
  }

  function renderRealnameManage() {
    const rows = state.realname.list.map((record) => [
      `<code>${record.id}</code>`,
      escapeHtml(record.email || "-"),
      escapeHtml(record.real_name || "-"),
      `<code>${escapeHtml(record.identity_no_masked || "-")}</code>`,
      renderStatus(record.status_label || record.status || "unverified"),
      escapeHtml(formatDate(record.submitted_at)),
      renderActionRow([
        buttonAction("通过", "realname-review", null, `data-user-id="${record.id}" data-status="approved"`),
        buttonAction("驳回", "realname-review", null, `data-user-id="${record.id}" data-status="rejected"`)
      ])
    ]);

    return [
      '<div class="toolbar toolbar-spaced">',
      '<div class="toolbar-group">',
      '<button class="btn btn-primary" data-action="approve-all">全部通过待审</button>',
      '<button class="btn btn-secondary" data-action="sync-all">同步全部状态</button>',
      "</div>",
      "</div>",
      wrapTable(["用户ID", "邮箱", "姓名", "证件号", "状态", "提交时间", "操作"], rows),
      renderPagination(state.realname.pagination)
    ].join("");
  }

  function renderOnlineDevices() {
    const rows = state.devices.list.map((item) => [
      `<code>${item.id}</code>`,
      escapeHtml(item.email || "-"),
      escapeHtml(item.subscription_name || "-"),
      escapeHtml((item.online_devices || []).join(", ") || "-"),
      `<code>${item.online_count || 0}</code>`,
      escapeHtml(item.last_online_text || "-")
    ]);

    return [
      wrapTable(["用户ID", "邮箱", "套餐", "在线 IP", "设备数", "最后在线"], rows),
      renderPagination(state.devices.pagination)
    ].join("");
  }

  function renderIPv6Manage() {
    const rows = state.ipv6.list.map((item) => {
      const isActive = item.is_active || item.status === "active";
      const isDisabled = item.status === "disabled";
      const actions = [];
      if (isActive) {
        actions.push(buttonAction("关闭", "ipv6-disable", null, `data-user-id="${item.id}"`));
        actions.push(buttonAction("同步密码", "ipv6-sync-password", null, `data-user-id="${item.id}"`));
      } else {
        actions.push(buttonAction("开通", "ipv6-enable-modal", null, `data-user-id="${item.id}" data-email="${escapeHtml(item.email || "")}"`));
      }
      if (isDisabled) {
        actions.unshift(buttonAction("重新开通", "ipv6-enable-modal", null, `data-user-id="${item.id}" data-email="${escapeHtml(item.email || "")}"`));
      }
      return [
        `<code>${item.id}</code>`,
        [
          `<strong>${escapeHtml(item.email || "-")}</strong>`,
          `<div class="subtle-text">${escapeHtml(item.ipv6_email || "-")}</div>`
        ].join(""),
        escapeHtml(item.plan_name || "-"),
        renderStatus(item.status_label || item.status || "-"),
        escapeHtml(formatDate(item.updated_at)),
        renderActionRow(actions)
      ];
    });

    return [
      wrapTable(["用户ID", "账号", "IPv6 套餐", "状态", "更新时间", "操作"], rows),
      renderPagination(state.ipv6.pagination)
    ].join("");
  }

  function renderSystemConfig() {
    const sections = ["site", "subscribe", "server", "safe", "invite", "frontend"];
    const activeTab = sections.includes(state.configTab) ? state.configTab : "site";
    const values = (state.config && state.config[activeTab]) || {};

    return [
      '<div class="tabs-nav card">',
      sections
        .map((section) => {
          const active = section === activeTab ? "btn-primary" : "btn-ghost";
          return `<button class="btn ${active}" data-action="config-tab" data-tab="${section}">${section.toUpperCase()}</button>`;
        })
        .join(""),
      "</div>",
      '<form data-form="config-save" class="card">',
      `<input type="hidden" name="__section" value="${activeTab}" />`,
      '<div class="grid grid-2">',
      Object.keys(values)
        .map((key) => renderConfigField(key, values[key]))
        .join(""),
      "</div>",
      '<div class="toolbar toolbar-spaced"><button class="btn btn-primary" type="submit">保存配置</button></div>',
      "</form>"
    ].join("");
  }

  function renderConfigField(key, value) {
    const label = key.replace(/_/g, " ");
    if (typeof value === "boolean") {
      return [
        '<div class="field">',
        `<label>${escapeHtml(label)}</label>`,
        `<select name="${escapeHtml(key)}"><option value="1" ${value ? "selected" : ""}>开启</option><option value="0" ${value ? "" : "selected"}>关闭</option></select>`,
        "</div>"
      ].join("");
    }

    return [
      '<div class="field">',
      `<label>${escapeHtml(label)}</label>`,
      `<input name="${escapeHtml(key)}" value="${escapeHtml(value == null ? "" : String(value))}" />`,
      "</div>"
    ].join("");
  }

  function renderModalContent() {
    const modal = state.modal;
    const body =
      modal.type === "plan"
        ? renderPlanForm(modal.data)
        : modal.type === "coupon"
          ? renderCouponForm(modal.data)
          : modal.type === "user"
            ? renderUserForm(modal.data)
            : modal.type === "node"
              ? renderNodeForm(modal.data)
              : modal.type === "group"
                ? renderGroupForm(modal.data)
                : modal.type === "route"
                  ? renderRouteForm(modal.data)
                  : modal.type === "ipv6-enable"
                    ? renderIPv6EnableForm(modal.data)
                    : "";

    return [
      '<div class="modal-card">',
      '<div class="card modal-card-inner">',
      '<button class="btn btn-close" data-action="modal-close">×</button>',
      body,
      "</div>",
      "</div>"
    ].join("");
  }

  function renderPlanForm(plan) {
    return [
      `<h2>${plan.id ? "编辑套餐" : "新建套餐"}</h2>`,
      '<form data-form="plan-save">',
      hiddenField("id", plan.id || ""),
      inputField("套餐名称", "name", plan.name || "", "text", true),
      selectField("权限组", "group_id", state.groups, plan.group_id, false),
      inputField("流量额度", "transfer_enable", plan.transfer_enable || 0, "number", false),
      inputField("速度限制 Mbps", "speed_limit", plan.speed_limit || 0, "number", false),
      textareaField("价格 JSON", "prices", plan.prices || "{}"),
      booleanField("是否展示", "show", plan.show !== false),
      submitRow(plan.id ? "保存套餐" : "创建套餐"),
      "</form>"
    ].join("");
  }

  function renderCouponForm(coupon) {
    return [
      `<h2>${coupon.id ? "编辑优惠券" : "新建优惠券"}</h2>`,
      '<form data-form="coupon-save">',
      hiddenField("id", coupon.id || ""),
      inputField("名称", "name", coupon.name || "", "text", true),
      inputField("编码", "code", coupon.code || "", "text", true),
      selectSimpleField("类型", "type", [
        { value: 1, label: "固定金额" },
        { value: 2, label: "比例折扣" }
      ], coupon.type || 1),
      inputField("数值", "value", coupon.value || 0, "number", true),
      booleanField("是否展示", "show", coupon.show !== false),
      submitRow(coupon.id ? "保存优惠券" : "创建优惠券"),
      "</form>"
    ].join("");
  }

  function renderUserForm(user) {
    return [
      `<h2>编辑用户 #${escapeHtml(user.id || "")}</h2>`,
      '<form data-form="user-save">',
      hiddenField("id", user.id || ""),
      inputField("邮箱", "email", user.email || "", "email", true),
      inputField("新密码", "password", "", "password", false),
      inputField("余额", "balance", user.balance || 0, "number", false),
      selectField("套餐", "plan_id", state.plans, user.plan_id, true),
      inputField("设备限制", "device_limit", user.device_limit || 0, "number", false),
      inputField("速度限制 Mbps", "speed_limit", user.speed_limit || 0, "number", false),
      textareaField("备注", "remarks", user.remarks || ""),
      datetimeField("到期时间", "expired_at", user.expired_at),
      submitRow("保存用户"),
      "</form>"
    ].join("");
  }

  function renderNodeForm(node) {
    return [
      `<h2>${node.id ? "编辑节点" : "新增节点"}</h2>`,
      '<form data-form="node-save">',
      hiddenField("id", node.id || ""),
      inputField("节点名称", "name", node.name || "", "text", true),
      inputField("节点类型", "type", node.type || "shadowsocks", "text", true),
      inputField("主机地址", "host", node.host || "", "text", true),
      inputField("对外端口", "port", node.port || "", "text", true),
      inputField("服务端口", "server_port", node.server_port || 443, "number", true),
      inputField("倍率", "rate", node.rate || 1, "number", true, 'step="0.1"'),
      booleanField("是否展示", "show", node.show !== false),
      submitRow(node.id ? "保存节点" : "创建节点"),
      "</form>"
    ].join("");
  }

  function renderGroupForm(group) {
    return [
      `<h2>${group.id ? "编辑权限组" : "新增权限组"}</h2>`,
      '<form data-form="group-save">',
      hiddenField("id", group.id || ""),
      inputField("权限组名称", "name", group.name || "", "text", true),
      submitRow(group.id ? "保存权限组" : "创建权限组"),
      "</form>"
    ].join("");
  }

  function renderRouteForm(route) {
    return [
      `<h2>${route.id ? "编辑路由规则" : "新增路由规则"}</h2>`,
      '<form data-form="route-save">',
      hiddenField("id", route.id || ""),
      inputField("备注", "remarks", route.remarks || "", "text", true),
      textareaField("匹配规则", "match", Array.isArray(route.match) ? route.match.join("\n") : ""),
      selectSimpleField("动作", "action", [
        { value: "direct", label: "direct" },
        { value: "proxy", label: "proxy" },
        { value: "block", label: "block" },
        { value: "dns", label: "dns" }
      ], route.action || "direct"),
      inputField("动作值", "action_value", route.action_value || "", "text", false),
      submitRow(route.id ? "保存规则" : "创建规则"),
      "</form>"
    ].join("");
  }

  function renderNotice() {
    return `<div class="notice notice-${escapeHtml(state.messageType)}">${escapeHtml(state.message)}</div>`;
  }

  function wrapTable(headers, rows) {
    return `<div class="table-wrap">${renderTable(headers, rows)}</div>`;
  }

  function renderTable(headers, rows) {
    if (!rows || !rows.length) {
      return '<div class="empty-state">暂无数据</div>';
    }

    return [
      "<table>",
      "<thead><tr>",
      headers.map((header) => `<th>${escapeHtml(header)}</th>`).join(""),
      "</tr></thead>",
      "<tbody>",
      rows
        .map((row) => {
          const isObjectRow = !Array.isArray(row);
          const cells = isObjectRow ? row.cells : row;
          const className = isObjectRow ? row.className || "" : "";
          return `<tr class="${className}">${cells.map((cell) => `<td>${cell}</td>`).join("")}</tr>`;
        })
        .join(""),
      "</tbody>",
      "</table>"
    ].join("");
  }

  function renderPagination(pagination) {
    if (!pagination || pagination.last_page <= 1) {
      return "";
    }

    const buttons = [];
    for (let page = 1; page <= pagination.last_page; page += 1) {
      buttons.push(
        `<button class="page-btn ${pagination.current === page ? "active" : ""}" data-action="page" data-page="${page}">${page}</button>`
      );
    }

    return `<div class="pagination-shell">${buttons.join("")}</div>`;
  }

  function statCard(title, value, hint) {
    return [
      '<article class="card stat-card">',
      `<span>${escapeHtml(title)}</span>`,
      `<strong>${escapeHtml(value)}</strong>`,
      `<p>${escapeHtml(hint || "")}</p>`,
      "</article>"
    ].join("");
  }

  function summaryItem(label, value) {
    return `<div class="summary-item"><span>${escapeHtml(label)}</span><strong>${escapeHtml(value)}</strong></div>`;
  }

  function buttonAction(label, action, id, extraAttrs) {
    const idAttr = id == null ? "" : `data-id="${id}"`;
    return `<button class="btn btn-ghost" data-action="${action}" ${idAttr} ${extraAttrs || ""}>${escapeHtml(label)}</button>`;
  }

  function renderActionRow(items) {
    return `<div class="row-actions">${items.join("")}</div>`;
  }

  function renderRelationChip(fromId, toId) {
    return `<span class="relation-chip"><code>${escapeHtml(fromId)}</code><span class="relation-arrow">&rarr;</span><code>${escapeHtml(toId)}</code></span>`;
  }

  function hiddenField(name, value) {
    return `<input type="hidden" name="${escapeHtml(name)}" value="${escapeHtml(String(value))}" />`;
  }

  function inputField(label, name, value, type, required, extraAttrs) {
    return [
      '<div class="field">',
      `<label>${escapeHtml(label)}</label>`,
      `<input type="${type}" name="${escapeHtml(name)}" value="${escapeHtml(String(value == null ? "" : value))}" ${required ? "required" : ""} ${extraAttrs || ""} />`,
      "</div>"
    ].join("");
  }

  function textareaField(label, name, value) {
    return [
      '<div class="field">',
      `<label>${escapeHtml(label)}</label>`,
      `<textarea name="${escapeHtml(name)}">${escapeHtml(String(value == null ? "" : value))}</textarea>`,
      "</div>"
    ].join("");
  }

  function booleanField(label, name, value) {
    return selectSimpleField(label, name, [
      { value: 1, label: "开启" },
      { value: 0, label: "关闭" }
    ], value ? 1 : 0);
  }

  function datetimeField(label, name, value) {
    const formatted = value ? new Date(value * 1000).toISOString().slice(0, 16) : "";
    return inputField(label, name, formatted, "datetime-local", false);
  }

  function selectField(label, name, items, currentValue, allowEmpty) {
    const options = [];
    if (allowEmpty) {
      options.push('<option value="0">无</option>');
    }
    items.forEach((item) => {
      options.push(
        `<option value="${item.id}" ${Number(currentValue) === Number(item.id) ? "selected" : ""}>${escapeHtml(item.name)}</option>`
      );
    });
    return `<div class="field"><label>${escapeHtml(label)}</label><select name="${escapeHtml(name)}">${options.join("")}</select></div>`;
  }

  function selectSimpleField(label, name, items, currentValue) {
    return `<div class="field"><label>${escapeHtml(label)}</label><select name="${escapeHtml(name)}">${items
      .map((item) => `<option value="${escapeHtml(String(item.value))}" ${String(item.value) === String(currentValue) ? "selected" : ""}>${escapeHtml(item.label)}</option>`)
      .join("")}</select></div>`;
  }

  function submitRow(label) {
    return `<div class="toolbar toolbar-spaced"><button class="btn btn-primary" type="submit">${escapeHtml(label)}</button></div>`;
  }

  function renderIPv6EnableForm(data) {
    return [
      `<h2>开通 IPv6 子账号</h2>`,
      `<p>用户: <strong>${escapeHtml(data.email || data.userId)}</strong></p>`,
      '<form data-form="ipv6-enable-save">',
      hiddenField("user_id", data.userId),
      selectField("IPv6 套餐", "plan_id", state.plans, 0, true),
      submitRow("确认开通"),
      "</form>"
    ].join("");
  }

  function setBusy(value) {
    state.busy = value;
    render(true);
  }

  function show(message, type) {
    state.message = message;
    state.messageType = type || "info";
    render(true);
    window.clearTimeout(show._timer);
    show._timer = window.setTimeout(function () {
      state.message = "";
      render(true);
    }, 3000);
  }

  async function adminPost(url, body) {
    try {
      const response = await request(url, { method: "POST", body });
      show("操作成功", "success");
      return response;
    } catch (error) {
      show(error.message || "操作失败", "error");
      throw error;
    }
  }

  async function request(url, options) {
    const opt = options || {};
    const headers = { "Content-Type": "application/json" };
    if (opt.auth !== false && state.token) {
      headers.Authorization = state.token;
    }

    const response = await fetch(url, {
      method: opt.method || "GET",
      headers,
      body: opt.body ? JSON.stringify(opt.body) : undefined
    });
    const payload = await response.json().catch(() => null);

    if (!response.ok) {
      if (response.status === 401) {
        clearSession();
        render();
      }
      throw new Error((payload && (payload.message || payload.msg)) || "请求失败");
    }

    return payload;
  }

  function normalizeListPayload(payload, listKey) {
    const key = listKey || "list";
    return {
      list: toArray(payload, key),
      pagination: payload && payload.pagination ? payload.pagination : null
    };
  }

  function unwrap(payload) {
    return payload && typeof payload.data !== "undefined" ? payload.data : payload;
  }

  function toArray(value, key) {
    if (Array.isArray(value)) {
      return value;
    }
    if (!value || typeof value !== "object") {
      return [];
    }
    if (Array.isArray(value[key || "data"])) {
      return value[key || "data"];
    }
    if (Array.isArray(value.list)) {
      return value.list;
    }
    if (Array.isArray(value.data)) {
      return value.data;
    }
    return [];
  }

  function serializeForm(form) {
    const values = {};
    const section = form.querySelector('input[name="__section"]');
    const formData = new window.FormData(form);

    formData.forEach((rawValue, key) => {
      if (key === "__section") {
        return;
      }

      if (key === "show" || key === "renew" || key === "sell") {
        values[key] = String(rawValue) === "1";
        return;
      }

      if (key === "expired_at") {
        values[key] = rawValue ? Math.floor(new Date(rawValue).getTime() / 1000) : null;
        return;
      }

      if (key === "match") {
        values[key] = String(rawValue)
          .split(/\r?\n/)
          .map((item) => item.trim())
          .filter(Boolean);
        return;
      }

      if (["id", "group_id", "transfer_enable", "speed_limit", "balance", "plan_id", "device_limit", "server_port", "value", "user_id"].includes(key)) {
        values[key] = rawValue === "" ? null : Number(rawValue);
        return;
      }

      values[key] = rawValue;
    });

    if (section) {
      return values;
    }

    return values;
  }

  function getCurrentPage() {
    return state.pagination[state.route] || 1;
  }

  function setCurrentPage(page) {
    state.pagination[state.route] = page > 0 ? page : 1;
  }

  function readToken() {
    return window.localStorage.getItem("__gopanel_admin_auth__") || "";
  }

  function saveToken(token) {
    window.localStorage.setItem("__gopanel_admin_auth__", /^Bearer /.test(token) ? token : `Bearer ${token}`);
  }

  function clearSession() {
    state.token = "";
    state.user = null;
    state.modal = null;
    window.localStorage.removeItem("__gopanel_admin_auth__");
  }

  function readRoute() {
    return (window.location.hash || "#overview").slice(1);
  }

  function normalizeRoute(route) {
    return ROUTE_META[route] ? route : "overview";
  }

  function getSecurePath() {
    if (state.config && state.config.safe && state.config.safe.secure_path) {
      return String(state.config.safe.secure_path).replace(/^\//, "");
    }
    return String(cfg.securePath || "admin").replace(/^\//, "");
  }

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

  function formatMoney(amount) {
    return `¥${((Number(amount) || 0) / 100).toFixed(2)}`;
  }

  function formatDate(value) {
    if (!value) {
      return "-";
    }
    const date = new Date(typeof value === "number" ? value * 1000 : value);
    if (Number.isNaN(date.getTime())) {
      return String(value);
    }
    return date.toLocaleString();
  }

  function formatSignedPercent(value) {
    const num = Number(value || 0);
    return `${num >= 0 ? "+" : ""}${num.toFixed(2)}%`;
  }

  function orderStatusText(status) {
    if (status === 0) return "pending";
    if (status === 3) return "paid";
    if (status === 2) return "cancelled";
    return String(status);
  }

  function ticketStatusText(status) {
    if (status === 0) return "pending";
    if (status === 1) return "answered";
    if (status === 2) return "closed";
    return String(status);
  }

  function renderStatus(status) {
    const text = String(status || "-");
    const normalized = text.toLowerCase();
    let type = "danger";
    if (/(ok|active|visible|approved|paid|answered|online|enabled)/.test(normalized)) {
      type = "ok";
    } else if (/(pending|warn|unverified|eligible|ready)/.test(normalized)) {
      type = "warn";
    } else if (/(disabled)/.test(normalized)) {
      type = "warn";
    }
    return `<span class="status-pill status-${type}">${escapeHtml(text)}</span>`;
  }

  function escapeHtml(value) {
    return String(value == null ? "" : value)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
  }

  function getRouteTitle(route) {
    return route.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
  }
})();
