(() => {
  if (typeof window !== "undefined" && window.MMWQianchuanWorkflowTemplate) return;

  const SCHEMA_VERSION = 8;
  const MAX_SELECTED_PLANS = 20;
  const SPEND_WINDOW_MS = 60 * 60 * 1000;
  const PLAN_ID_PATTERN = /^\d{10,24}$/;
  const DEFAULT_CONFIG = Object.freeze({
    schemaVersion: SCHEMA_VERSION,
    enabled: false,
    executionMode: "confirm",
    intervalMinutes: 5,
    targetMode: "all",
    planId: "",
    planIds: Object.freeze([]),
    hourlySpendTarget: 100,
    spendOverPercent: 20,
    roiIncrease: 0.1,
    coldStartEnabled: false,
    coldStartMaxDecrease: 0.5,
    coldStartHourlySpendBelow: 10,
    coldStartRoiDecrease: 0.1,
    pauseBelowNetRoi: 1.5,
    lowRoiCycles: 2,
    minimumSpend: 100,
    maxActionsPerDay: 8,
    notifications: Object.freeze({
      balanceEnabled: false,
      balanceBelow: 500,
      revenueRiseEnabled: false,
      revenueRisePercent: 20,
      netRoiEnabled: false,
      netRoiBelow: 1.5
    }),
    dataReport: Object.freeze({
      enabled: false,
      intervalMinutes: 30,
      includeDashboard: true,
      includePlans: true,
      deliveryMode: "aggregate"
    })
  });

  function numberIn(value, fallback, min, max, digits = 2) {
    const parsed = Number(value);
    if (!Number.isFinite(parsed)) return fallback;
    const clamped = Math.min(max, Math.max(min, parsed));
    return Number(clamped.toFixed(digits));
  }

  function integerIn(value, fallback, min, max) {
    const parsed = Number(value);
    return Number.isInteger(parsed) && parsed >= min && parsed <= max ? parsed : fallback;
  }

  function rawPlanIds(value = {}) {
    const source = value && typeof value === "object" ? value : {};
    const listed = Array.isArray(source.planIds) ? source.planIds : [];
    const values = listed.some((item) => String(item || "").trim()) ? listed : [source.planId];
    return values.map((item) => String(item || "").trim()).filter(Boolean);
  }

  function normalizePlanIds(value = {}) {
    const seen = new Set();
    return rawPlanIds(value)
      .filter((planId) => PLAN_ID_PATTERN.test(planId) && !seen.has(planId) && seen.add(planId))
      .slice(0, MAX_SELECTED_PLANS);
  }

  function normalizeConfig(value = {}) {
    const source = value && typeof value === "object" ? value : {};
    const notifications = source.notifications && typeof source.notifications === "object" ? source.notifications : {};
    const dataReport = source.dataReport && typeof source.dataReport === "object" ? source.dataReport : {};
    const planIds = normalizePlanIds(source);
    const hasHourlySpendTarget = Object.prototype.hasOwnProperty.call(source, "hourlySpendTarget");
    const legacyPacing = !hasHourlySpendTarget && (Object.prototype.hasOwnProperty.call(source, "risePercent")
      || (Number(source.schemaVersion) > 0 && Number(source.schemaVersion) < SCHEMA_VERSION));
    const targetMode = source.targetMode === "all"
      ? "all"
      : source.targetMode === "selected" || planIds.length ? "selected" : "all";
    return {
      schemaVersion: SCHEMA_VERSION,
      enabled: source.enabled === true,
      executionMode: source.executionMode === "managed" ? "managed" : "confirm",
      intervalMinutes: integerIn(source.intervalMinutes, DEFAULT_CONFIG.intervalMinutes, 1, 1440),
      targetMode,
      planId: planIds[0] || "",
      planIds,
      hourlySpendTarget: numberIn(source.hourlySpendTarget, legacyPacing ? 0 : DEFAULT_CONFIG.hourlySpendTarget, 0, 100000000),
      spendOverPercent: numberIn(source.spendOverPercent ?? source.risePercent, DEFAULT_CONFIG.spendOverPercent, 0, 10000),
      roiIncrease: numberIn(source.roiIncrease, DEFAULT_CONFIG.roiIncrease, 0.1, 99),
      coldStartEnabled: source.coldStartEnabled === true,
      coldStartMaxDecrease: numberIn(source.coldStartMaxDecrease, DEFAULT_CONFIG.coldStartMaxDecrease, 0.01, 99),
      coldStartHourlySpendBelow: numberIn(source.coldStartHourlySpendBelow, DEFAULT_CONFIG.coldStartHourlySpendBelow, 0, 100000000),
      coldStartRoiDecrease: numberIn(source.coldStartRoiDecrease, DEFAULT_CONFIG.coldStartRoiDecrease, 0.01, 99),
      pauseBelowNetRoi: numberIn(source.pauseBelowNetRoi, DEFAULT_CONFIG.pauseBelowNetRoi, 0.01, 100),
      lowRoiCycles: integerIn(source.lowRoiCycles, DEFAULT_CONFIG.lowRoiCycles, 1, 12),
      minimumSpend: numberIn(source.minimumSpend, DEFAULT_CONFIG.minimumSpend, 0, 100000000),
      maxActionsPerDay: integerIn(source.maxActionsPerDay, DEFAULT_CONFIG.maxActionsPerDay, 1, 30),
      notifications: {
        balanceEnabled: notifications.balanceEnabled === true,
        balanceBelow: numberIn(notifications.balanceBelow, DEFAULT_CONFIG.notifications.balanceBelow, 0, 100000000),
        revenueRiseEnabled: notifications.revenueRiseEnabled === true,
        revenueRisePercent: numberIn(notifications.revenueRisePercent, DEFAULT_CONFIG.notifications.revenueRisePercent, 0.1, 10000),
        netRoiEnabled: notifications.netRoiEnabled === true,
        netRoiBelow: numberIn(notifications.netRoiBelow, DEFAULT_CONFIG.notifications.netRoiBelow, 0.01, 100)
      },
      dataReport: {
        enabled: dataReport.enabled === true,
        intervalMinutes: integerIn(dataReport.intervalMinutes, DEFAULT_CONFIG.dataReport.intervalMinutes, 1, 1440),
        includeDashboard: dataReport.includeDashboard !== false,
        includePlans: dataReport.includePlans !== false,
        deliveryMode: dataReport.deliveryMode === "per_account" ? "per_account" : "aggregate"
      }
    };
  }

  function validateConfig(value) {
    const config = normalizeConfig(value);
    const sourceIds = rawPlanIds(value);
    const planScopeRequired = config.enabled || config.dataReport.enabled;
    if (planScopeRequired && config.targetMode === "selected" && !sourceIds.length) {
      return { ok: false, code: "PLAN_ID_REQUIRED", message: "选择“指定计划”后，请至少填写一条完整计划 ID。", value: config };
    }
    if (planScopeRequired && config.targetMode === "selected" && sourceIds.length > MAX_SELECTED_PLANS) {
      return { ok: false, code: "PLAN_ID_LIMIT", message: `指定计划最多添加 ${MAX_SELECTED_PLANS} 条。`, value: config };
    }
    if (planScopeRequired && config.targetMode === "selected" && sourceIds.some((planId) => !PLAN_ID_PATTERN.test(planId))) {
      return { ok: false, code: "PLAN_ID_INVALID", message: "指定计划 ID 应为 10 至 24 位数字，请检查后重试。", value: config };
    }
    if (planScopeRequired && config.targetMode === "selected" && new Set(sourceIds).size !== sourceIds.length) {
      return { ok: false, code: "PLAN_ID_DUPLICATE", message: "指定计划 ID 不能重复，请删除重复项。", value: config };
    }
    if (config.dataReport.enabled && !config.dataReport.includeDashboard && !config.dataReport.includePlans) {
      return { ok: false, code: "REPORT_TYPE_REQUIRED", message: "定时数据通知至少要选择“表盘总数据”或“计划数据”。", value: config };
    }
    if (config.coldStartEnabled && config.coldStartRoiDecrease > config.coldStartMaxDecrease) {
      return { ok: false, code: "COLD_START_STEP_EXCEEDS_LIMIT", message: "计划冷启动的“每次下调”不能大于“累计最多下调”。", value: config };
    }
    return { ok: true, code: "OK", message: "", value: config };
  }

  function normalizeRuntime(value = {}) {
    const source = value && typeof value === "object" ? value : {};
    const previous = source.previous && typeof source.previous === "object" ? source.previous : {};
    const pendingAction = source.pendingAction && typeof source.pendingAction === "object" ? source.pendingAction : null;
    const planStates = {};
    Object.entries(source.planStates && typeof source.planStates === "object" ? source.planStates : {})
      .slice(0, 40)
      .forEach(([planId, item]) => {
        if (!PLAN_ID_PATTERN.test(planId) || !item || typeof item !== "object") return;
        planStates[planId] = {
          lowRoiCount: integerIn(item.lowRoiCount, 0, 0, 12),
          spendWindowStartedAt: Math.max(0, Number(item.spendWindowStartedAt) || 0),
          spendWindowStartValue: finiteOrNull(item.spendWindowStartValue),
          spendWindowLastValue: finiteOrNull(item.spendWindowLastValue),
          coldStartBaseRoi: finiteOrNull(item.coldStartBaseRoi),
          coldStartActive: item.coldStartActive === true
        };
      });
    return {
      lastRunAt: Math.max(0, Number(source.lastRunAt) || 0),
      lastDataReportAt: Math.max(0, Number(source.lastDataReportAt) || 0),
      dataReportRetryAt: Math.max(0, Number(source.dataReportRetryAt) || 0),
      lowRoiCount: integerIn(source.lowRoiCount, 0, 0, 12),
      previous: {
        accountNetRevenue: finiteOrNull(previous.accountNetRevenue),
        accountNetRoi: finiteOrNull(previous.accountNetRoi),
        balance: finiteOrNull(previous.balance)
      },
      activeAlerts: {
        balance: source.activeAlerts?.balance === true,
        netRoi: source.activeAlerts?.netRoi === true
      },
      planStates,
      pendingAction: pendingAction ? {
        action: String(pendingAction.action || ""),
        rule: String(pendingAction.rule || ""),
        planId: String(pendingAction.planId || ""),
        expectedBefore: finiteOrNull(pendingAction.expectedBefore),
        expectedStatus: String(pendingAction.expectedStatus || ""),
        targetValue: finiteOrNull(pendingAction.targetValue),
        attempts: integerIn(pendingAction.attempts, 0, 0, 3),
        createdAt: Math.max(0, Number(pendingAction.createdAt) || 0)
      } : null
    };
  }

  function finiteOrNull(value) {
    if (value == null || value === "") return null;
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
  }

  function isDue(lastRunAt, intervalMinutes, now = Date.now()) {
    return !lastRunAt || now - Number(lastRunAt) >= integerIn(intervalMinutes, 5, 1, 1440) * 60000;
  }

  function evaluate(configValue, runtimeValue, snapshot = {}, now = Date.now()) {
    const validation = validateConfig(configValue);
    const config = validation.value;
    const runtime = normalizeRuntime(runtimeValue);
    if (!config.enabled) return result("disabled", "规则任务未启用", runtime);
    if (!validation.ok) return result("blocked", validation.message, runtime, validation.code);
    if (!isDue(runtime.lastRunAt, config.intervalMinutes, now)) return result("not_due", "尚未到巡检时间", runtime);

    const next = { ...runtime, lastRunAt: now, activeAlerts: { ...runtime.activeAlerts }, planStates: { ...runtime.planStates } };
    const selection = selectTargetRows(config, snapshot.rows);
    if (!selection.ok) return result("blocked", selection.message, next, selection.code);

    const account = readAccountMetrics(snapshot);
    const notifications = evaluateNotifications(config, runtime, next, account);
    const observed = selection.rows.map((row) => {
      const planId = String(row.id);
      const plan = readPlanMetrics(row);
      const legacy = config.targetMode === "selected" && planId === config.planId
        ? { lowRoiCount: runtime.lowRoiCount }
        : {};
      const previous = runtime.planStates[planId] || legacy;
      const lowRoiEvaluable = plan.netRoi != null && plan.spend != null;
      const lowRoiCount = lowRoiEvaluable && plan.spend >= config.minimumSpend && plan.netRoi < config.pauseBelowNetRoi
        ? Math.min(12, Number(previous.lowRoiCount || 0) + 1)
        : 0;
      const spendWindow = config.coldStartEnabled || config.hourlySpendTarget > 0
        ? advanceSpendWindow(previous, plan.spend, now)
        : { startedAt: 0, startValue: null, lastValue: null, completedSpend: null };
      let coldStartBaseRoi = config.coldStartEnabled ? finiteOrNull(previous.coldStartBaseRoi) : null;
      if (config.coldStartEnabled && plan.targetRoi != null
        && (coldStartBaseRoi == null || plan.targetRoi > coldStartBaseRoi)) {
        coldStartBaseRoi = plan.targetRoi;
      }
      const coldStartActive = config.coldStartEnabled
        && (spendWindow.completedSpend == null
          ? previous.coldStartActive === true
          : spendWindow.completedSpend < config.coldStartHourlySpendBelow);
      next.planStates[planId] = {
        lowRoiCount,
        spendWindowStartedAt: spendWindow.startedAt,
        spendWindowStartValue: spendWindow.startValue,
        spendWindowLastValue: spendWindow.lastValue,
        coldStartBaseRoi,
        coldStartActive
      };
      return {
        row,
        plan,
        planId,
        lowRoiCount,
        hourlySpend: spendWindow.completedSpend,
        coldStartBaseRoi,
        coldStartActive
      };
    });
    const selected = observed[0];
    next.previous = {
      accountNetRevenue: account.netRevenue,
      accountNetRoi: account.netRoi,
      balance: account.balance
    };
    next.lowRoiCount = config.targetMode === "selected" ? selected.lowRoiCount : 0;

    const pendingTarget = runtime.pendingAction
      ? observed.find((item) => item.planId === runtime.pendingAction.planId)
      : null;
    if (runtime.pendingAction && !pendingTarget) {
      return result("blocked", "待验证计划已不在当前列表，本轮停止并等待页面恢复。", next, "CONTROL_NOT_FOUND", notifications);
    }
    const pending = resumePendingAction(runtime.pendingAction, pendingTarget?.plan, pendingTarget?.planId);
    if (pending.status === "ready") {
      next.pendingAction = runtime.pendingAction;
      return result("action", workflowFeedback(config, observed, account, `重试固定目标：${describeAction(pending.action)}`), next, "OK", notifications, pending.action);
    }
    if (pending.status === "completed") next.pendingAction = null;
    if (pending.status === "exhausted") {
      return result("blocked", "同一固定目标已尝试 3 次，任务已停机并等待用户检查。", next, "RETRY_EXHAUSTED", notifications);
    }
    if (pending.status === "mismatch") {
      next.pendingAction = null;
      return result("blocked", "计划当前值已变化，旧调整目标已作废，等待下轮重新观察。", next, "PAGE_CHANGED", notifications);
    }

    let action = null;
    const pauseTarget = observed.find((item) => item.lowRoiCount >= config.lowRoiCycles && item.row.status !== "paused");
    if (pauseTarget) {
      action = {
        action: "pause",
        target_id: pauseTarget.planId,
        target_name: String(pauseTarget.row.name || pauseTarget.planId).slice(0, 160),
        expected_current: { status: pauseTarget.row.status || "active" },
        safety_context: {
          current_net_roi: pauseTarget.plan.netRoi,
          target_roi: pauseTarget.plan.targetRoi
        },
        reason: `净 ROI ${formatNumber(pauseTarget.plan.netRoi)} 连续 ${pauseTarget.lowRoiCount} 轮低于 ${formatNumber(config.pauseBelowNetRoi)}，且计划当前消耗达到 ${formatMoney(config.minimumSpend)}。`
      };
      next.pendingAction = {
        action: "pause",
        planId: pauseTarget.planId,
        expectedBefore: null,
        expectedStatus: pauseTarget.row.status || "active",
        targetValue: null,
        attempts: 0,
        createdAt: now
      };
    }

    const coldStartTarget = !action && config.coldStartEnabled
      ? observed.find((item) => item.row.status !== "paused" && item.hourlySpend != null
        && item.hourlySpend < config.coldStartHourlySpendBelow
        && item.plan.targetRoi != null && item.coldStartBaseRoi != null
        && item.plan.targetRoi > Math.max(0.01, item.coldStartBaseRoi - config.coldStartMaxDecrease) + 0.0001)
      : null;
    if (coldStartTarget) {
      const floor = Number(Math.max(0.01, coldStartTarget.coldStartBaseRoi - config.coldStartMaxDecrease).toFixed(2));
      const target = Number(Math.max(floor, coldStartTarget.plan.targetRoi - config.coldStartRoiDecrease).toFixed(2));
      action = {
        action: "set_roi",
        workflow_rule: "cold_start",
        target_id: coldStartTarget.planId,
        target_name: String(coldStartTarget.row.name || coldStartTarget.planId).slice(0, 160),
        new_roi: target,
        expected_current: { roi: coldStartTarget.plan.targetRoi, status: coldStartTarget.row.status || "active" },
        safety_context: {
          current_net_roi: coldStartTarget.plan.netRoi,
          target_roi: coldStartTarget.plan.targetRoi,
          hourly_spend: coldStartTarget.hourlySpend,
          hourly_spend_threshold: config.coldStartHourlySpendBelow,
          cold_start_base_roi: coldStartTarget.coldStartBaseRoi,
          cold_start_floor_roi: floor
        },
        reason: `计划近一小时消耗 ${formatMoney(coldStartTarget.hourlySpend)}，低于冷启动目标 ${formatMoney(config.coldStartHourlySpendBelow)}；目标 ROI 下调至 ${formatNumber(target)}，累计下限为 ${formatNumber(floor)}。`
      };
      next.pendingAction = createPendingAction(action, now);
    }

    if (!action && config.hourlySpendTarget > 0) {
      const spendLimit = config.hourlySpendTarget * (1 + config.spendOverPercent / 100);
      const riseTarget = observed.find((item) => !item.coldStartActive && item.row.status !== "paused"
        && item.hourlySpend != null && item.plan.targetRoi != null
        && item.hourlySpend >= spendLimit);
      if (riseTarget) {
        const pacingPercent = riseTarget.hourlySpend / config.hourlySpendTarget * 100;
        const target = Number((riseTarget.plan.targetRoi + config.roiIncrease).toFixed(2));
        action = {
          action: "set_roi",
          workflow_rule: "spend_pacing",
          target_id: riseTarget.planId,
          target_name: String(riseTarget.row.name || riseTarget.planId).slice(0, 160),
          new_roi: target,
          expected_current: { roi: riseTarget.plan.targetRoi, status: riseTarget.row.status || "active" },
          safety_context: {
            current_net_roi: riseTarget.plan.netRoi,
            target_roi: riseTarget.plan.targetRoi,
            hourly_spend: riseTarget.hourlySpend,
            hourly_spend_target: config.hourlySpendTarget,
            spend_over_percent: config.spendOverPercent,
            spend_pacing_percent: Number(pacingPercent.toFixed(2))
          },
          reason: `计划近一小时消耗 ${formatMoney(riseTarget.hourlySpend)}，达到目标 ${formatMoney(config.hourlySpendTarget)} 的 ${pacingPercent.toFixed(1)}%，超过允许流速 ${formatNumber(100 + config.spendOverPercent)}%；目标 ROI 提高至 ${formatNumber(target)}。`
        };
        next.pendingAction = createPendingAction(action, now);
      }
    }

    const missing = observed.filter((item) => item.plan.netRevenue == null || item.plan.netRoi == null || item.plan.spend == null).length;
    const note = action
      ? `触发：${describeAction(action)}`
      : missing ? `仅监控：${missing} 个计划指标不完整，本轮只记录可读数据` : "未触发调控";
    return result(action ? "action" : "observed", workflowFeedback(config, observed, account, note), next, "OK", notifications, action);
  }

  function advanceSpendWindow(previous = {}, currentSpend, now) {
    const spend = finiteOrNull(currentSpend);
    const startedAt = Math.max(0, Number(previous.spendWindowStartedAt) || 0);
    const startValue = finiteOrNull(previous.spendWindowStartValue);
    const lastValue = finiteOrNull(previous.spendWindowLastValue);
    if (spend == null) return { startedAt, startValue, lastValue, completedSpend: null };
    if (!startedAt || startValue == null || spend < startValue || (lastValue != null && spend < lastValue)) {
      return { startedAt: now, startValue: spend, lastValue: spend, completedSpend: null };
    }
    const elapsed = now - startedAt;
    if (elapsed < SPEND_WINDOW_MS) {
      return { startedAt, startValue, lastValue: spend, completedSpend: null };
    }
    const hourlySpend = Math.max(0, spend - startValue) * SPEND_WINDOW_MS / elapsed;
    return { startedAt: now, startValue: spend, lastValue: spend, completedSpend: Number(hourlySpend.toFixed(2)) };
  }

  function createPendingAction(action, now) {
    return {
      action: action.action,
      rule: String(action.workflow_rule || ""),
      planId: action.target_id,
      expectedBefore: finiteOrNull(action.expected_current?.roi),
      expectedStatus: String(action.expected_current?.status || ""),
      targetValue: finiteOrNull(action.new_roi),
      attempts: 0,
      createdAt: now
    };
  }

  function selectTargetRows(config, rowsValue) {
    const rows = (Array.isArray(rowsValue) ? rowsValue : [])
      .filter((row) => PLAN_ID_PATTERN.test(String(row?.id || "")))
      .slice(0, 40);
    if (config.targetMode === "selected") {
      const selected = [];
      for (const planId of config.planIds) {
        const matches = rows.filter((row) => String(row.id) === planId);
        if (matches.length !== 1) {
          return {
            ok: false,
            rows: [],
            code: matches.length ? "TARGET_NOT_UNIQUE" : "CONTROL_NOT_FOUND",
            message: matches.length
              ? `指定计划 ${planId} 在当前页面不唯一，本轮已停止。`
              : `当前列表未找到指定计划 ${planId}，本轮未操作。`
          };
        }
        selected.push(matches[0]);
      }
      return { ok: true, rows: selected, code: "OK", message: "" };
    }
    if (!rows.length) return { ok: false, rows: [], code: "CONTROL_NOT_FOUND", message: "当前列表未识别到带完整 ID 的计划，本轮未操作。" };
    const seen = new Set();
    const duplicate = rows.find((row) => seen.has(String(row.id)) || !seen.add(String(row.id)));
    if (duplicate) return { ok: false, rows: [], code: "TARGET_NOT_UNIQUE", message: `计划 ${duplicate.id} 在当前列表重复，本轮已停止。` };
    return { ok: true, rows, code: "OK", message: "" };
  }

  function resumePendingAction(pending, plan, planId) {
    if (!pending || pending.planId !== planId) return { status: "none", action: null };
    if (pending.attempts >= 3) return { status: "exhausted", action: null };
    if (pending.action === "pause") {
      if (plan.status === "paused") return { status: "completed", action: null };
      if (plan.status && pending.expectedStatus && plan.status !== pending.expectedStatus) return { status: "mismatch", action: null };
      return {
        status: "ready",
        action: {
          action: "pause",
          target_id: planId,
          expected_current: { status: pending.expectedStatus || "active" },
          reason: "沿用首次观察生成的暂停意图；执行前仍会重新定位并验证计划状态。"
        }
      };
    }
    if (pending.action !== "set_roi") return { status: "mismatch", action: null };
    if (plan.targetRoi == null || pending.expectedBefore == null || pending.targetValue == null) return { status: "mismatch", action: null };
    if (nearlyEqual(plan.targetRoi, pending.targetValue)) return { status: "completed", action: null };
    if (!nearlyEqual(plan.targetRoi, pending.expectedBefore)) return { status: "mismatch", action: null };
    return {
      status: "ready",
      action: {
        action: "set_roi",
        workflow_rule: String(pending.rule || ""),
        target_id: planId,
        new_roi: pending.targetValue,
        expected_current: { roi: pending.expectedBefore },
        reason: `沿用首次观察固定的 ROI 目标 ${formatNumber(pending.targetValue)}，不重复累加。`
      }
    };
  }

  function evaluateNotifications(config, runtime, next, account) {
    const items = [];
    const balanceActive = config.notifications.balanceEnabled && account.balance != null
      && account.balance < config.notifications.balanceBelow;
    if (balanceActive && !runtime.activeAlerts.balance) {
      items.push({ code: "BALANCE_LOW", message: `账户余额 ${formatMoney(account.balance)}，低于提醒值 ${formatMoney(config.notifications.balanceBelow)}。` });
    }
    next.activeAlerts.balance = balanceActive;

    const roiActive = config.notifications.netRoiEnabled && account.netRoi != null
      && account.netRoi < config.notifications.netRoiBelow;
    if (roiActive && !runtime.activeAlerts.netRoi) {
      items.push({ code: "NET_ROI_LOW", message: `账户净 ROI ${formatNumber(account.netRoi)}，低于提醒值 ${formatNumber(config.notifications.netRoiBelow)}。` });
    }
    next.activeAlerts.netRoi = roiActive;

    if (config.notifications.revenueRiseEnabled && runtime.previous.accountNetRevenue != null
      && runtime.previous.accountNetRevenue > 0 && account.netRevenue != null) {
      const rise = (account.netRevenue - runtime.previous.accountNetRevenue) / runtime.previous.accountNetRevenue * 100;
      if (rise >= config.notifications.revenueRisePercent) {
        items.push({ code: "NET_REVENUE_RISE", message: `账户净成交金额较上一轮上涨 ${rise.toFixed(1)}%。` });
      }
    }
    return items;
  }

  function readPlanMetrics(row = {}) {
    const text = String(row.text || "");
    return {
      netRevenue: metricFrom(text, ["用户实际支付净成交金额", "净成交金额"]),
      netRoi: metricFrom(text, ["净成交ROI", "净ROI"]),
      spend: metricFrom(text, ["整体消耗", "消耗"]),
      targetRoi: metricFrom(text, ["综合营销ROI目标", "目标ROI", "ROI目标"]),
      status: String(row.status || "")
    };
  }

  function readAccountMetrics(snapshot = {}) {
    const metrics = [...(Array.isArray(snapshot.summaryMetrics) ? snapshot.summaryMetrics : []),
      ...(Array.isArray(snapshot.planTotals) ? snapshot.planTotals : [])];
    const find = (labels) => {
      const item = metrics.find((metric) => labels.includes(String(metric?.label || "").replace(/\(元\)$/g, "")));
      return finiteOrNull(item?.numericValue);
    };
    return {
      balance: finiteOrNull(snapshot.accountBalance),
      netRevenue: find(["用户实际支付净成交金额", "净成交金额"]),
      netRoi: find(["净成交ROI"])
    };
  }

  function extractAccountBalance(text) {
    const match = String(text || "").match(/千川(?:可用)?余额(?:\(元\))?\s*[:：]?\s*[¥￥]?\s*(-?(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?)/);
    return match ? finiteOrNull(match[1].replace(/,/g, "")) : null;
  }

  function metricFrom(text, labels) {
    for (const label of labels) {
      const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
      const match = text.match(new RegExp(`${escaped}\\s*[:：]?\\s*[¥￥]?\\s*(-?(?:\\d{1,3}(?:,\\d{3})+|\\d+)(?:\\.\\d+)?)`, "i"));
      if (match) return finiteOrNull(match[1].replace(/,/g, ""));
    }
    return null;
  }

  function compactFeedback(plan, account, note) {
    const parts = [
      `巡检完成`,
      plan.netRevenue == null ? "计划净成交 --" : `计划净成交 ${formatMoney(plan.netRevenue)}`,
      plan.netRoi == null ? "净ROI --" : `净ROI ${formatNumber(plan.netRoi)}`,
      plan.targetRoi == null ? "目标ROI --" : `目标ROI ${formatNumber(plan.targetRoi)}`,
      account.balance == null ? "" : `余额 ${formatMoney(account.balance)}`,
      note
    ].filter(Boolean);
    return parts.join(" · ").slice(0, 360);
  }

  function workflowFeedback(config, observed, account, note) {
    if (config.targetMode === "selected" && observed.length === 1) return compactFeedback(observed[0].plan, account, note);
    const readable = observed.filter((item) => item.plan.netRevenue != null || item.plan.netRoi != null || item.plan.spend != null).length;
    return [
      `巡检 ${observed.length} 个计划`,
      `可读 ${readable} 个`,
      account.balance == null ? "" : `余额 ${formatMoney(account.balance)}`,
      note,
      actionQueueHint(observed)
    ].filter(Boolean).join(" · ").slice(0, 360);
  }

  function actionQueueHint(observed) {
    return observed.length > 1 ? "每轮最多处理 1 个明确计划" : "";
  }

  function describeAction(action) {
    if (!action) return "未触发调控";
    if (action.action === "pause") return `暂停计划 ${action.target_id}`;
    if (action.action === "set_roi") return `计划 ${action.target_id} 的目标 ROI 调至 ${formatNumber(action.new_roi)}`;
    return String(action.action || "待处理操作");
  }

  function result(status, feedback, runtime, code = "OK", notifications = [], action = null) {
    return { status, code, feedback: String(feedback || "").slice(0, 360), runtime: normalizeRuntime(runtime), notifications, action };
  }

  function nearlyEqual(left, right) {
    return Math.abs(Number(left) - Number(right)) < 0.0001;
  }

  function formatNumber(value) {
    return Number(value).toFixed(2).replace(/\.00$/, "").replace(/(\.\d)0$/, "$1");
  }

  function formatMoney(value) {
    return `¥${Number(value).toLocaleString("zh-CN", { maximumFractionDigits: 2 })}`;
  }

  function markActionSettled(runtimeValue, succeeded) {
    const runtime = normalizeRuntime(runtimeValue);
    if (succeeded) runtime.pendingAction = null;
    else if (runtime.pendingAction) runtime.pendingAction.attempts = Math.min(3, runtime.pendingAction.attempts + 1);
    return runtime;
  }

  const api = Object.freeze({
    SCHEMA_VERSION,
    DEFAULT_CONFIG,
    normalizeConfig,
    validateConfig,
    normalizeRuntime,
    isDue,
    evaluate,
    extractAccountBalance,
    markActionSettled
  });
  if (typeof window !== "undefined") window.MMWQianchuanWorkflowTemplate = api;
  if (typeof module !== "undefined" && module.exports) module.exports = api;
})();
