// /AIWK_COMMON/core/aiwk_title.js
// 용도: AIWK/Heart 공존용 browser title prefix 파서/포맷터 공통 모듈.
// AIWK EXT4 v157-heart-title-sticky-common
(function () {
  "use strict";
  const root = window.AIWK || (window.AIWK = {});
  const HEART_TOKEN_RE = /^(?:❤\ufe0f?|♥\ufe0f?|♡\ufe0f?|❣\ufe0f?|💛|💚|💙|💜|🧡|🖤|🤍|🤎|💖|💗|💓|💞|💕|💘|💝|💟)/u;
  const STATUS_TOKEN_GROUP = "(?:🟢|🟡|🔴|⚫|♻\ufe0f?|⚠\ufe0f?|⏹\ufe0f?)";
  const STATUS_PREFIX_PATTERN = "(?:" + STATUS_TOKEN_GROUP + "\\s*){1,8}";
  const META_RE = new RegExp("^\\s*" + STATUS_PREFIX_PATTERN + "([A-Za-z][A-Za-z0-9_-]{0,31})\\s+R:([0-9]{1,8})\\s+T:([0-9]{1,8})\\s*[-–]\\s*(.*)$", "iu");
  const PREFIX_WITH_COUNTERS_RE = new RegExp("^\\s*" + STATUS_PREFIX_PATTERN + "[A-Za-z][A-Za-z0-9_-]{0,31}\\s+R:\\d{1,8}\\s+T:\\d{1,8}\\s*[-–]\\s*", "iu");
  const PREFIX_SIMPLE_RE = new RegExp("^\\s*" + STATUS_PREFIX_PATTERN + "[A-Za-z][A-Za-z0-9_-]{0,31}\\s*[-–]\\s*", "iu");
  const TAIL_WITH_COUNTERS_RE = new RegExp("\\s*[-–]\\s*" + STATUS_PREFIX_PATTERN + "[A-Za-z][A-Za-z0-9_-]{0,31}\\s+R:\\d{1,8}\\s+T:\\d{1,8}.*$", "iu");

  function pad4(n) { return String(Math.max(0, parseInt(n || 0, 10) || 0)).padStart(4, "0"); }

  function readLeadingHeartTriple(title) {
    const src = String(title || "");
    const leading = (src.match(/^\s*/) || [""])[0];
    let idx = leading.length;
    let prefix = leading;
    for (let i = 0; i < 3; i++) {
      const m = src.slice(idx).match(HEART_TOKEN_RE);
      if (!m) return { prefix: "", rest: src };
      prefix += m[0];
      idx += m[0].length;
    }
    return { prefix: prefix.trim(), rest: src.slice(idx).replace(/^\s+/, "") };
  }

  function joinHeartPrefix(prefix, title) {
    const body = String(title || "").trim();
    const head = String(prefix || "").trim();
    if (!head) return body;
    return body ? head + " " + body : head;
  }

  function stripBody(title, hasPreservedHeart) {
    let out = String(title || "").trim();
    for (let i = 0; i < 20; i++) {
      const before = out;
      out = out
        .replace(PREFIX_WITH_COUNTERS_RE, "")
        .replace(PREFIX_SIMPLE_RE, "")
        .replace(TAIL_WITH_COUNTERS_RE, "")
        .trim();

      const nestedHeart = readLeadingHeartTriple(out);
      if (nestedHeart.prefix) {
        const rest = String(nestedHeart.rest || "").trim();
        if (hasPreservedHeart || META_RE.test(rest) || PREFIX_WITH_COUNTERS_RE.test(rest) || PREFIX_SIMPLE_RE.test(rest)) {
          out = rest;
        }
      }
      if (out === before) break;
    }
    return out.trim();
  }

  function parse(title) {
    const heart = readLeadingHeartTriple(title);
    let raw = heart.prefix ? heart.rest : String(title || "");
    let clientId = "";
    let counters = null;
    for (let i = 0; i < 20; i++) {
      const before = raw;
      const m = raw.match(META_RE);
      if (m) {
        clientId = String(m[1] || clientId || "").toUpperCase();
        counters = { rx: parseInt(m[2] || "0", 10) || 0, tx: parseInt(m[3] || "0", 10) || 0 };
        raw = String(m[4] || "").trim();
      } else {
        raw = raw
          .replace(PREFIX_WITH_COUNTERS_RE, "")
          .replace(PREFIX_SIMPLE_RE, "")
          .replace(TAIL_WITH_COUNTERS_RE, "")
          .trim();
      }

      const nestedHeart = readLeadingHeartTriple(raw);
      if (nestedHeart.prefix) {
        const rest = String(nestedHeart.rest || "").trim();
        if (heart.prefix || META_RE.test(rest) || PREFIX_WITH_COUNTERS_RE.test(rest) || PREFIX_SIMPLE_RE.test(rest)) raw = rest;
      }
      if (raw === before) break;
    }
    return {
      heartPrefix: heart.prefix,
      cleanTitle: raw.trim(),
      clientId: clientId,
      counters: counters,
      title: joinHeartPrefix(heart.prefix, raw)
    };
  }

  function strip(title) {
    const p = parse(title);
    return joinHeartPrefix(p.heartPrefix, stripBody(p.cleanTitle, !!p.heartPrefix));
  }

  function format(opts) {
    opts = opts || {};
    const parsed = parse(opts.baseTitle || "AIWK");
    const heartPrefix = String(opts.heartPrefix || parsed.heartPrefix || "").trim();
    const cleanBase = String(parsed.cleanTitle || "AIWK").trim() || "AIWK";
    const statusTriple = String(opts.statusTriple || "🔴🔴🔴").trim() || "🔴🔴🔴";
    const clientId = String(opts.clientId || parsed.clientId || "AIWK").trim() || "AIWK";
    const rx = opts.rx !== undefined ? opts.rx : (parsed.counters && parsed.counters.rx);
    const tx = opts.tx !== undefined ? opts.tx : (parsed.counters && parsed.counters.tx);
    return joinHeartPrefix(heartPrefix, statusTriple + " " + clientId + " R:" + pad4(rx) + " T:" + pad4(tx) + " - " + cleanBase);
  }

  const api = {
    version: "v157-heart-title-sticky-common",
    readLeadingHeartTriple: readLeadingHeartTriple,
    joinHeartPrefix: joinHeartPrefix,
    stripBody: stripBody,
    strip: strip,
    parse: parse,
    format: format,
    pad4: pad4,
    _regex: {
      heartToken: HEART_TOKEN_RE,
      meta: META_RE,
      prefixWithCounters: PREFIX_WITH_COUNTERS_RE,
      prefixSimple: PREFIX_SIMPLE_RE,
      tailWithCounters: TAIL_WITH_COUNTERS_RE
    }
  };
  root.title = api;
  window.AIWK_TITLE = api;
})();
