(() => {
  const METRICS = [
    { id: "account_balance", label: "千川可用余额", unit: "元", aliases: ["千川可用余额", "账户可用余额", "账号可用余额", "当前账户余额", "当前账号余额", "账户余额", "账号余额"] },
    { id: "account_daily_budget", label: "千川日预算", unit: "元", aliases: ["千川日预算", "账户日预算", "账号日预算", "日预算"], allowUnlimited: true },
    { id: "page_update_time", label: "页面更新时间", unit: "", aliases: ["页面更新时间", "数据更新时间", "更新时间"], kind: "time" },
    { id: "comprehensive_roi", label: "综合营销ROI", unit: "", aliases: ["综合营销ROI", "净成交ROI"] },
    { id: "net_transaction_amount", label: "净成交金额", unit: "元", aliases: ["净成交金额"] },
    { id: "net_order_count", label: "净成交订单数", unit: "单", aliases: ["净成交订单数"] },
    { id: "paid_net_amount", label: "用户实际支付净成交金额", unit: "元", aliases: ["用户实际支付净成交金额"] },
    { id: "total_transaction_amount", label: "整体成交金额", unit: "元", aliases: ["整体成交金额"] },
    { id: "total_spend", label: "整体消耗", unit: "元", aliases: ["整体消耗", "当前消耗", "账户消耗"] },
    { id: "comprehensive_cost", label: "综合成本", unit: "元", aliases: ["综合成本"] },
    { id: "order_cost", label: "综合订单成本", unit: "元", aliases: ["综合订单成本", "整体成交订单成本"] },
    { id: "hourly_refund_rate", label: "1小时内退款率", unit: "%", aliases: ["1小时内退款率", "退款率"] }
  ];
  const METRIC_BY_ID = new Map(METRICS.map((metric) => [metric.id, metric]));
  const READ_INTENT = /获取|查询|查看|读取|告诉|反馈|汇报|发送|发到|发给|多少|余额|数据/i;
  const WRITE_INTENT = /调整|修改|设置|提高|提升|降低|增加|减少|暂停|恢复|开启|关闭|删除|创建|充值|支付/i;
  const REASONING_INTENT = /分析|诊断|原因|建议|是否|够不够|充足|异常|为什么|趋势|对比|优化/i;

  function compactText(value) {
    return String(value || "").replace(/\s+/g, " ").trim();
  }

  function parseRequest(message) {
    const text = compactText(message);
    const metricIds = METRICS
      .filter((metric) => metric.aliases.some((alias) => text.toLowerCase().includes(alias.toLowerCase())))
      .map((metric) => metric.id);
    const recognized = metricIds.length > 0 && READ_INTENT.test(text) && !WRITE_INTENT.test(text);
    return {
      recognized,
      metricIds: recognized ? metricIds : [],
      directReply: recognized && !REASONING_INTENT.test(text),
      deliverToWeixin: /微信|weixin|wechat/i.test(text) && /发送|发到|发给|同步|推送|回复/i.test(text)
    };
  }

  function observe(doc = document, message = "", structured = {}) {
    const request = parseRequest(message);
    if (!request.recognized) return { request, facts: [], missingMetricIds: [], evidenceText: "" };
    const pageText = documentText(doc);
    const facts = mergeFacts(
      extractFactsFromText(pageText, request.metricIds),
      factsFromStructured(structured, request.metricIds)
    );
    const pageUpdate = extractFactsFromText(pageText, ["page_update_time"])[0]
      || factsFromStructured(structured, ["page_update_time"])[0]
      || null;
    return {
      request,
      facts,
      pageUpdate,
      missingMetricIds: request.metricIds.filter((id) => !facts.some((fact) => fact.id === id)),
      evidenceText: targetedEvidence(pageText, request.metricIds)
    };
  }

  function documentText(doc) {
    let text = String(doc?.body?.innerText || doc?.body?.textContent || "");
    const agentText = String(doc?.querySelector?.("#mmw-qianchuan-agent-root")?.innerText || "").trim();
    if (agentText) text = text.replace(agentText, "");
    return text.slice(0, 80000);
  }

  function extractFactsFromText(text, metricIds = []) {
    const lines = String(text || "").split(/\r?\n/).map(compactText).filter(Boolean);
    const facts = [];
    for (const id of metricIds) {
      const metric = METRIC_BY_ID.get(id);
      if (!metric) continue;
      const fact = metric.kind === "time" ? extractTimeFact(lines, metric) : extractValueFact(lines, metric);
      if (fact) facts.push(fact);
    }
    return facts;
  }

  function extractValueFact(lines, metric) {
    for (let index = 0; index < lines.length; index += 1) {
      const line = lines[index];
      const alias = metric.aliases.find((item) => startsWithLabel(line, item));
      if (!alias) continue;
      const offset = alias.length;
      const candidates = [line.slice(offset), ...lines.slice(index + 1, index + 5)];
      const value = candidates.map((candidate) => readMetricValue(candidate, metric)).find(Boolean);
      if (!value) continue;
      const numericValue = Number(value.replace(/[%￥¥,]/g, ""));
      return {
        id: metric.id,
        label: metric.label,
        value,
        unit: metric.unit,
        ...(Number.isFinite(numericValue) ? { numericValue } : {}),
        confidence: 1,
        source: "page_text",
        evidence: `${alias} ${value}`.trim().slice(0, 160)
      };
    }
    return null;
  }

  function extractTimeFact(lines, metric) {
    const joined = lines.join("\n");
    const value = joined.match(/\b\d{2}-\d{2}\s+\d{2}:\d{2}\s*更新/)?.[0]
      || joined.match(/\b\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?/)?.[0]
      || "";
    return value ? {
      id: metric.id,
      label: metric.label,
      value: compactText(value),
      unit: "",
      confidence: 1,
      source: "page_text",
      evidence: compactText(value).slice(0, 160)
    } : null;
  }

  function readMetricValue(value, metric) {
    const text = compactText(value).replace(/^[()（）\[\]【】元：:>｜|·-]+/, "");
    if (metric.allowUnlimited && /^(?:不限|无限制|无上限)(?:\s|$|[>｜|])/.test(text)) return text.match(/不限|无限制|无上限/)?.[0] || "";
    return text.match(/(?:[¥￥]\s*)?(-?(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?%?)/)?.[1] || "";
  }

  function factsFromStructured(structured = {}, metricIds = []) {
    const records = [...(structured.summaryMetrics || []), ...(structured.planTotals || [])];
    if (structured.pageUpdatedText) records.push({ label: "页面更新时间", value: structured.pageUpdatedText });
    const facts = [];
    for (const id of metricIds) {
      const metric = METRIC_BY_ID.get(id);
      const record = records.find((item) => metric?.aliases.some((alias) => startsWithLabel(compactText(item?.label), alias)));
      const value = compactText(record?.value);
      if (!metric || !value) continue;
      facts.push({
        id,
        label: metric.label,
        value,
        unit: metric.unit,
        ...(Number.isFinite(Number(record.numericValue)) ? { numericValue: Number(record.numericValue) } : {}),
        confidence: 1,
        source: "structured_page_context",
        evidence: `${compactText(record.label)} ${value}`.slice(0, 160)
      });
    }
    return facts;
  }

  function mergeFacts(...groups) {
    const result = [];
    const seen = new Set();
    for (const fact of groups.flat()) {
      if (!fact?.id || seen.has(fact.id)) continue;
      seen.add(fact.id);
      result.push(fact);
    }
    return result;
  }

  function targetedEvidence(text, metricIds) {
    const aliases = metricIds.flatMap((id) => METRIC_BY_ID.get(id)?.aliases || []);
    const lines = String(text || "").split(/\r?\n/).map(compactText).filter(Boolean);
    const picked = [];
    for (let index = 0; index < lines.length; index += 1) {
      if (!aliases.some((alias) => lines[index].toLowerCase().includes(alias.toLowerCase()))) continue;
      picked.push(...lines.slice(Math.max(0, index - 1), index + 5));
    }
    return [...new Set(picked)].join("\n").slice(0, 2400);
  }

  function startsWithLabel(value, label) {
    const text = compactText(value).toLowerCase();
    const wanted = compactText(label).toLowerCase();
    if (!text.startsWith(wanted)) return false;
    const next = text.slice(wanted.length, wanted.length + 1);
    return !next || /[\s(（:：]/.test(next);
  }

  function formatResult(observation, meta = {}) {
    const facts = observation?.facts || [];
    const missing = observation?.missingMetricIds || [];
    const lines = ["【千川 Agent 数据回传】", `范围：${compactText(meta.sceneLabel) || "当前千川页面"}`];
    for (const fact of facts) {
      const suffix = fact.unit && !String(fact.value).endsWith(fact.unit) && !String(fact.value).endsWith("%") ? ` ${fact.unit}` : "";
      lines.push(`${fact.label}：${fact.value}${suffix}`);
    }
    if (observation?.pageUpdate && !facts.some((fact) => fact.id === "page_update_time")) {
      lines.push(`页面更新时间：${observation.pageUpdate.value}`);
    }
    if (missing.length) lines.push(`未确认：${missing.map((id) => METRIC_BY_ID.get(id)?.label || id).join("、")}`);
    lines.push(`数据来源：${facts.some((fact) => fact.source === "page_visual") ? "当前千川页面画面识别" : "当前千川页面只读观测"}`);
    lines.push("本次未执行任何投放操作。");
    return lines.join("\n");
  }

  const api = { METRICS, parseRequest, observe, extractFactsFromText, mergeFacts, formatResult };
  if (typeof window !== "undefined") window.MMWQianchuanReadonlyObserver = api;
  if (typeof module !== "undefined" && module.exports) module.exports = api;
})();
