/**
 * STONK IM Stats reader (ISOLATED) — trang Hộp thư TikTok Affiliate (/seller/im).
 * Đọc số cuộc hội thoại "Chưa đọc" / "Chưa trả lời" / "Tất cả" mà TikTok đã render (Phase-1 DOM,
 * an toàn, không giải mã protobuf), theo dõi bằng MutationObserver, lưu theo shop_id + gửi server.
 * KHÔNG polling liên tục; chỉ đọc khi DOM đổi + vài mốc đầu. Số là CUỘC HỘI THOẠI (không phải message lẻ).
 */
(function () {
  if (window.__STONK_IM_STATS__) return;
  window.__STONK_IM_STATS__ = true;

  // v3.8.8 — TikTok có 2 hộp thư: /seller/im VÀ "Cooperation Chat" (mở từ nút "Tin nhắn từ nhà sáng tạo",
  // URL kiểu /connection/... hoặc /message/chat). Nhận diện RỘNG theo URL; nếu URL không rõ vẫn thử đọc
  // theo DẤU HIỆU DOM (có nhãn "Chưa trả lời/Chưa đọc (N)") — readAndReport tự siết để tránh nhầm trang khác.
  function onImPage() {
    // KHÔNG khớp bare "connection" (đó là trang danh sách KOC có overlay — nặng DOM). Chỉ khớp trang CHAT/hộp thư.
    return /(seller\/)?\/im(\/|\?|$)|\bim_v2\b|cooperation|message|\bchat\b|inbox/i
      .test(location.pathname + location.search);
  }
  function parseCount(text) {
    const m = String(text || "").replace(/[., ]/g, "").match(/\((\d+)\)/);
    return m ? Number(m[1]) : null;
  }
  function currentShopId() { try { return new URL(location.href).searchParams.get("shop_id") || ""; } catch { return ""; } }
  const PAT = {
    // Hỗ trợ đa ngôn ngữ; "unreplied" phải kiểm TRƯỚC "unread" vì "chưa trả lời" ≠ "chưa đọc".
    unreplied: /(chưa trả lời|chưa phản hồi|not\s*replied|un[_\s-]?repl)/i,
    unread: /(chưa đọc|unread)/i,
    total: /(tất cả|^all\b|\ball\b)/i,
  };
  let last = "";

  function readAndReport() {
    if (!onImPage()) return;
    let unread = null, unreplied = null, total = null;
    const nodes = document.querySelectorAll("a,button,li,span,div");
    for (const n of nodes) {
      const t = (n.textContent || "").trim();
      if (t.length > 42 || !/\(\d[\d., ]*\)/.test(t)) continue;   // chỉ nhãn menu ngắn "... (N)"
      const c = parseCount(t);
      if (c == null) continue;
      if (unreplied == null && PAT.unreplied.test(t)) { unreplied = c; continue; }
      if (unread == null && PAT.unread.test(t)) { unread = c; continue; }
      if (total == null && PAT.total.test(t)) { total = c; continue; }
    }
    // Siết: chỉ báo khi thấy tín hiệu ĐẶC TRƯNG hộp thư (chưa đọc / chưa trả lời) — "Tất cả (N)" đơn lẻ dễ nhầm trang khác.
    // Nhãn "chưa đọc"/"chưa trả lời" có mặt nhưng KHÔNG kèm badge số → TikTok ẩn vì = 0 → báo 0
    // (trước đây để null → dashboard hiện "—" mãi dù hộp thư đã render). Quét nhẹ lần 2, chỉ khi còn null.
    if (unread == null || unreplied == null) {
      for (const n of document.querySelectorAll("a,button,li,span,div")) {
        const t = (n.textContent || "").trim();
        if (t.length > 42) continue;
        if (unread == null && PAT.unread.test(t)) unread = 0;
        if (unreplied == null && PAT.unreplied.test(t)) unreplied = 0;
      }
    }
    if (unread == null && unreplied == null) return;
    const shopId = currentShopId();
    // null = chưa lấy được; KHÔNG tự gán 0.
    const payload = { shopId, unread, unreplied, total, updatedAt: new Date().toISOString(), source: "tiktok_dom" };
    const sig = JSON.stringify({ shopId, unread, unreplied, total });
    if (sig === last) return;
    last = sig;
    try {
      chrome.storage.local.get(["stonk_im_stats_by_shop"], v => {
        const all = (v && v.stonk_im_stats_by_shop) || {};
        all[shopId || "_"] = payload;
        chrome.storage.local.set({ stonk_im_stats_by_shop: all });
      });
    } catch {}
    try { chrome.runtime.sendMessage({ type: "STONK_IM_STATS", stats: payload }); } catch {}
  }

  let _t = null;
  const debounced = () => { clearTimeout(_t); _t = setTimeout(readAndReport, 600); };
  let mo = null;
  function start() {
    // v5.8.53 — KHÔNG dựng MutationObserver khi không ở trang hộp thư. Tệp này chạy với
    // all_frames:true nên nó nạp vào MỌI khung của trang affiliate (Garfish micro-frontend có
    // nhiều khung con); trước đây mỗi khung đều tạo sẵn một MutationObserver dù không dùng.
    if (!onImPage()) return;
    mo = new MutationObserver(debounced);
    try { mo.observe(document.documentElement, { childList: true, subtree: true, characterData: true }); } catch {}
    [800, 2500, 6000].forEach(ms => setTimeout(readAndReport, ms));
    // Đọc lại định kỳ khi vẫn ở trang hộp thư (số đổi theo thời gian thực), bỏ chặn debounce.
    setInterval(() => { if (onImPage()) readAndReport(); }, 15000);
    // v5.8.53 — CHỈ báo khi THẬT SỰ gắn. Trước đây dòng log này nằm ngoài start() nên trang chủ
    // (/platform/homepage) cũng in "IM stats reader gắn (trang hộp thư)" dù không gắn gì cả —
    // đọc log tưởng đang có bộ theo dõi DOM chạy nền trên trang chủ, chẩn đoán sai hoàn toàn.
    console.log("[STONK] IM stats reader gắn (trang hộp thư).");
  }
  if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", start);
  else start();
})();
