/* global React */
/* ============================================================
   KEYWORDS — taxonomia central de termos do jogo
   ============================================================

   Esta é a única fonte de verdade para classificar termos do
   sistema. Toda nova aba (Classes, Raças, Itens, Bestiário)
   apenas adiciona entradas aqui — sem refatorar nada mais.

   Como funciona:
   1) KEYWORDS é um dicionário { termo: { kind, tooltip? } }
   2) <Kw kind="..."> renderiza um span colorido (via --kw-{kind})
   3) parseText(str) varre a string e marca automaticamente todo
      termo conhecido, devolvendo um array de React nodes
   4) Adicione termos novos a KEYWORDS e tudo já fica colorido
   ============================================================ */

// Tipos semânticos (cada um tem cor própria em styles.css)
const KW_KINDS = {
  school:     { label: "Escola de magia",  color: "var(--kw-school)" },
  circle:     { label: "Círculo de magia", color: "var(--kw-circle)" },
  "power-type":{ label: "Tipo de poder",   color: "var(--kw-power-type)" },
  condition:  { label: "Condição",          color: "var(--kw-condition)" },
  damage:     { label: "Tipo de dano",     color: "var(--kw-damage)" },
  attribute:  { label: "Atributo",          color: "var(--kw-attribute)" },
  class:      { label: "Classe",            color: "var(--kw-class)" },
  race:       { label: "Raça",              color: "var(--kw-race)" },
  action:     { label: "Ação",              color: "var(--kw-action)" },
  area:       { label: "Área/Alcance",     color: "var(--kw-area)" },
  item:       { label: "Item/Equipamento", color: "var(--kw-item)" },
  dice:       { label: "Dado",              color: "var(--kw-dice)" },
};

// dicionário canônico. Match case-insensitive, whole-word.
// "alias" permite que vários textos resolvam para o mesmo termo.
const KEYWORDS = {
  // — escolas —
  "Abjuração":     { kind: "school" },
  "Adivinhação":   { kind: "school" },
  "Convocação":    { kind: "school" },
  "Encantamento":  { kind: "school" },
  "Evocação":      { kind: "school" },
  "Ilusão":        { kind: "school" },
  "Necromancia":   { kind: "school" },
  "Transmutação":  { kind: "school" },

  // — tipos de poder —
  "Combate":       { kind: "power-type" },
  "Concedido":     { kind: "power-type" },
  "Destino":       { kind: "power-type" },
  "Mágico":        { kind: "power-type" },
  "Tormenta":      { kind: "power-type" },

  // — condições —
  "Atordoado":     { kind: "condition" },
  "Caído":         { kind: "condition" },
  "Enfraquecido":  { kind: "condition" },
  "Esmorecido":    { kind: "condition" },
  "Frustrado":     { kind: "condition" },
  "Imóvel":        { kind: "condition" },
  "Paralisado":    { kind: "condition" },
  "Pasmo":         { kind: "condition" },
  "Surpreendido":  { kind: "condition" },
  "Vulnerável":    { kind: "condition" },
  "Indefeso":      { kind: "condition" },

  // — danos —
  "fogo":          { kind: "damage" },
  "frio":          { kind: "damage" },
  "elétrico":      { kind: "damage" },
  "ácido":         { kind: "damage" },
  "trovão":        { kind: "damage" },
  "necrótico":     { kind: "damage" },
  "psíquico":      { kind: "damage" },
  "radiante":      { kind: "damage" },
  "perfurante":    { kind: "damage" },
  "cortante":      { kind: "damage" },
  "contundente":   { kind: "damage" },

  // — atributos —
  "Força":         { kind: "attribute" },
  "Destreza":      { kind: "attribute" },
  "Constituição":  { kind: "attribute" },
  "Inteligência":  { kind: "attribute" },
  "Sabedoria":     { kind: "attribute" },
  "Carisma":       { kind: "attribute" },
  "For":           { kind: "attribute" },
  "Des":           { kind: "attribute" },
  "Con":           { kind: "attribute" },
  "Int":           { kind: "attribute" },
  "Sab":           { kind: "attribute" },
  "Car":           { kind: "attribute" },

  // — classes (preparadas para futuro) —
  "Bárbaro":       { kind: "class" },
  "Bardo":         { kind: "class" },
  "Bucaneiro":     { kind: "class" },
  "Cavaleiro":     { kind: "class" },
  "Caçador":       { kind: "class" },
  "Clérigo":       { kind: "class" },
  "Druida":        { kind: "class" },
  "Guerreiro":     { kind: "class" },
  "Inventor":      { kind: "class" },
  "Ladino":        { kind: "class" },
  "Lutador":       { kind: "class" },
  "Mago":          { kind: "class" },
  "Nobre":         { kind: "class" },
  "Paladino":      { kind: "class" },

  // — raças —
  "Humano":        { kind: "race" },
  "Anão":          { kind: "race" },
  "Elfo":          { kind: "race" },
  "Goblin":        { kind: "race" },
  "Hynne":         { kind: "race" },
  "Lefou":         { kind: "race" },
  "Minotauro":     { kind: "race" },
  "Qareen":        { kind: "race" },
  "Golem":         { kind: "race" },
  "Osteon":        { kind: "race" },
  "Sereia":        { kind: "race" },
  "Silfide":       { kind: "race" },
  "Trog":          { kind: "race" },

  // — ações —
  "ação padrão":   { kind: "action" },
  "ação completa": { kind: "action" },
  "ação livre":    { kind: "action" },
  "ação de movimento": { kind: "action" },
  "reação":        { kind: "action" },
  "1 PM":          { kind: "action", tooltip: "Custa 1 ponto de mana" },
  "2 PM":          { kind: "action", tooltip: "Custa 2 pontos de mana" },
  "3 PM":          { kind: "action", tooltip: "Custa 3 pontos de mana" },
  "4 PM":          { kind: "action", tooltip: "Custa 4 pontos de mana" },
  "5 PM":          { kind: "action", tooltip: "Custa 5 pontos de mana" },

  // — itens —
  "componente material": { kind: "item" },
  "foco arcano":   { kind: "item" },
  "símbolo sagrado": { kind: "item" },
};

// regex de dados (1d6, 2d8+3, etc) — captura inline, sem precisar listar
const DICE_RE = /\b(\d+d\d+(?:\s*[+-]\s*\d+)?|\d+d\d+)\b/g;

// base da wiki para links internos [[Página|Texto]]
const WIKI_BASE = "https://tormenta-collab.fandom.com/pt-br/wiki/";

// hiperlink externo: [https://url.com Texto do link]
const LINK_RE = /\[(https?:\/\/\S+)\s+([^\]]+)\]/g;

// link interno wiki: [[Página|Texto]] ou [[Página]]
const WIKI_LINK_RE = /\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g;

// monta regex único para todas as chaves (ordenado por tamanho desc
// pra "ação completa" ganhar de "ação")
const ALL_TERMS = Object.keys(KEYWORDS).sort((a, b) => b.length - a.length);
const escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const KW_RE = new RegExp(
  "\\b(" + ALL_TERMS.map(escape).join("|") + ")\\b",
  "gi"
);

// — Kw: renderiza um termo —
function Kw({ kind, children, title }) {
  const meta = KW_KINDS[kind] || {};
  return (
    <span
      className="kw"
      data-kind={kind}
      title={title || meta.label}
      style={{ "--kw-color": meta.color }}
    >
      {children}
    </span>
  );
}

// — parseText: string → array de nodes com Kw onde necessário —
function parseText(str) {
  if (!str) return [];
  const out = [];
  let cursor = 0;
  // 1) achar todos os matches de termos + dados, ordenar por índice
  const matches = [];
  for (const m of str.matchAll(KW_RE)) {
    const original = m[0];
    // achar a entrada canônica (case-insensitive)
    const canonical = ALL_TERMS.find((t) => t.toLowerCase() === original.toLowerCase());
    if (canonical) {
      matches.push({
        idx: m.index,
        len: original.length,
        text: original,
        kind: KEYWORDS[canonical].kind,
        tooltip: KEYWORDS[canonical].tooltip,
      });
    }
  }
  for (const m of str.matchAll(DICE_RE)) {
    matches.push({
      idx: m.index,
      len: m[0].length,
      text: m[0],
      kind: "dice",
    });
  }
  for (const m of str.matchAll(LINK_RE)) {
    matches.push({
      idx: m.index,
      len: m[0].length,
      text: m[2],
      href: m[1],
      kind: "link",
    });
  }
  for (const m of str.matchAll(WIKI_LINK_RE)) {
    const page = m[1].trim();
    matches.push({
      idx: m.index,
      len: m[0].length,
      text: (m[2] || page).trim(),
      href: WIKI_BASE + encodeURIComponent(page),
      kind: "link",
    });
  }
  // ordenar e remover overlap
  matches.sort((a, b) => a.idx - b.idx);
  const clean = [];
  let lastEnd = -1;
  for (const m of matches) {
    if (m.idx >= lastEnd) {
      clean.push(m);
      lastEnd = m.idx + m.len;
    }
  }
  // 2) montar nodes
  for (const m of clean) {
    if (cursor < m.idx) out.push(str.slice(cursor, m.idx));
    if (m.kind === "link") {
      out.push(
        <a
          key={m.idx + "-link"}
          className="kw-link"
          href={m.href}
          target="_blank"
          rel="noopener noreferrer"
        >
          {m.text}
        </a>
      );
    } else {
      out.push(
        <Kw key={m.idx + "-" + m.text} kind={m.kind} title={m.tooltip}>
          {m.text}
        </Kw>
      );
    }
    cursor = m.idx + m.len;
  }
  if (cursor < str.length) out.push(str.slice(cursor));
  return out;
}

// componente conveniente: parsea uma string solta
function Parsed({ children }) {
  if (typeof children !== "string") return children;
  return <>{parseText(children).map((n, i) => (
    typeof n === "string" ? <React.Fragment key={i}>{n}</React.Fragment> : n
  ))}</>;
}

// expõe globais
Object.assign(window, { KEYWORDS, KW_KINDS, Kw, parseText, Parsed });
