// Accent-insensitive phrase matcher for the hover-to-learn feature. Builds a
// single RegExp that finds known orchestra/singer names in arbitrary page text
// (any accent/case, with word boundaries) without mutating the page's own text.
const ACCENT = {
  a: "aáàâä", e: "eéèêë", i: "iíìîï", o: "oóòôö", u: "uúùûü", n: "nñ", c: "cç",
};
const PARTICLES = new Set(["di", "de", "del", "la", "las", "los", "da", "do", "van", "von", "y"]);

export function deacc(s) {
  return (s || "").normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase();
}

export function norm(s) {
  return deacc(s).replace(/\s+/g, " ").trim();
}

// "Carlos Di Sarli" -> "Di Sarli", "Juan D'Arienzo" -> "D'Arienzo",
// "Alfredo De Angelis" -> "De Angelis", "Aníbal Troilo" -> "Troilo".
export function surname(full) {
  const toks = (full || "").trim().split(/\s+/);
  if (toks.length < 2) return "";
  let i = toks.length - 1;
  const parts = [toks[i]];
  while (i - 1 >= 1 && PARTICLES.has(deacc(toks[i - 1]))) {
    parts.unshift(toks[i - 1]);
    i--;
  }
  return parts.join(" ");
}

function charSrc(ch) {
  if (ch === " ") return "\\s+";
  if (ch === "'" || ch === "’") return "['’]";   // straight or curly apostrophe
  const cls = ACCENT[ch];
  if (cls) return "[" + cls + "]";
  if (/[a-z0-9]/.test(ch)) return ch;
  // In u-mode only true metacharacters may be escaped; others (", comma…) are literal.
  return /[\\^$.*+?()[\]{}|/]/.test(ch) ? "\\" + ch : ch;
}

export function phraseRegexSource(phrase) {
  return [...deacc(phrase)].map(charSrc).join("");
}

// phrases: array of display strings. Returns a global, case/accent-insensitive
// RegExp whose group 1 is the matched text; longer phrases take precedence.
export function buildMatcher(phrases) {
  const sorted = [...new Set(phrases)].filter(p => norm(p).replace(/[^a-z0-9]/g, "").length >= 4)
    .sort((a, b) => b.length - a.length);
  if (!sorted.length) return null;
  const alt = sorted.map(phraseRegexSource).join("|");
  return new RegExp("(?<![\\p{L}\\p{N}])(" + alt + ")(?![\\p{L}\\p{N}])", "giu");
}
