/* global React, window, Kw, Parsed */
/* ============================================================
   DEITY CREATOR — aba "Divindade" do livro.
   Lista agrupada por panteão à esquerda.
   Detalhes completos (com poderes concedidos) à direita.
   Seleção persiste em localStorage.

   Regra de poderes concedidos:
     - Paladino e Clérigo → 2 poderes
     - demais classes      → 1 poder
   ============================================================ */

const { useState, useEffect, useMemo } = React;

const LS_DEITY = "arton_char_deity";
const LS_CLASS = "arton_char_class";

function dcLsGet(key) { try { return JSON.parse(localStorage.getItem(key)); } catch { return null; } }
function dcLsSet(key, val) { try { localStorage.setItem(key, JSON.stringify(val)); } catch {} }

/** Lê as classes salvas do personagem (multiclasse). */
function getSavedClassNames() {
  try {
    const data = JSON.parse(localStorage.getItem(LS_CLASS));
    if (data && Array.isArray(data.classes)) {
      return data.classes.map((c) => c.className).filter(Boolean);
    }
  } catch {}
  return [];
}

/** Quais das classes salvas têm is_devoted=true no backend. */
function getDevotedSavedClass(classNames) {
  const allClasses = window.CLASSES || [];
  for (const n of classNames || []) {
    const cls = allClasses.find((c) => c.name === n);
    if (cls?.is_devoted) return n;
  }
  return null;
}

/** Quantos poderes concedidos o personagem pode escolher.
   Se ele tem ALGUMA classe devota, ganha o bônus. */
function getMaxPowers(classNames) {
  return getDevotedSavedClass(classNames) ? 2 : 1;
}

/** Intersecta allowed_deities de TODAS as classes que têm restrição.
   Classes sem restrição não contribuem. Retorna null = sem restrição. */
function getAllowedDeities(classNames) {
  const allClasses = window.CLASSES || [];
  let allowed = null;
  for (const n of classNames || []) {
    const cls = allClasses.find((c) => c.name === n);
    const list = cls?.allowed_deities;
    if (!Array.isArray(list) || list.length === 0) continue;
    if (allowed === null) {
      allowed = new Set(list);
    } else {
      allowed = new Set([...allowed].filter((d) => list.includes(d)));
    }
  }
  return allowed ? [...allowed] : null;
}

const CHANNEL_COLORS = {
  "Positiva": "var(--gilt-0)",
  "Negativa": "var(--kw-school)",
  "Ambas":    "var(--kw-damage)",
};

function DCCorners() {
  return <>
    <span className="frame-corner tl"/>
    <span className="frame-corner tr"/>
    <span className="frame-corner bl"/>
    <span className="frame-corner br"/>
  </>;
}

function ChannelDot({ energy }) {
  return (
    <span style={{
      display: "inline-block",
      width: 7, height: 7,
      borderRadius: "50%",
      background: CHANNEL_COLORS[energy] || "var(--ink-2)",
      flexShrink: 0,
      marginTop: 2,
    }}/>
  );
}

/* ============================================================
   DEITY LIST  (página esquerda)
   ============================================================ */
function DeityList({
  deities, total, selected, saved, onSelect,
  query, setQuery,
  groups, activeGroup, onGroupToggle,
  activeChannel, onChannelToggle,
  restrictionHint,
}) {
  const folioLabel = deities.length < total
    ? `${deities.length} de ${total}`
    : String(total);

  const grouped = useMemo(() => {
    const map = new Map();
    for (const d of deities) {
      if (!map.has(d.deity_group)) map.set(d.deity_group, []);
      map.get(d.deity_group).push(d);
    }
    return map;
  }, [deities]);

  return (
    <div className="page-content rc-list-page">
      <header className="page-header">
        <span className="page-eyebrow">Divindades · Arton</span>
        <span className="page-folio">{folioLabel} divindades</span>
      </header>
      <h1 className="page-title">Panteão de Arton</h1>
      <p className="page-subtitle">
        Escolha uma divindade patrona. Ela concede poderes e obrigações ao devoto.
      </p>
      {restrictionHint && (
        <div className="dc-restriction-hint">{restrictionHint}</div>
      )}

      <div className="rc-search-wrap">
        <input
          className="rc-search"
          placeholder="Buscar divindade…"
          value={query}
          onChange={e => setQuery(e.target.value)}
        />
      </div>

      {groups.length > 1 && (
        <div className="rc-source-chips">
          {groups.map(g => {
            const short = g
              .replace(/^Panteão\s+(d[oa]s?|d[ae])\s+/i, "")
              .replace(/^Panteão\s+/i, "")
              .trim();
            return (
              <button
                key={g}
                className={"rc-source-chip" + (activeGroup === g ? " active" : "")}
                onClick={() => onGroupToggle(g)}
              >
                {short}
              </button>
            );
          })}
        </div>
      )}

      <div className="rc-source-chips" style={{ marginBottom: 8 }}>
        {["Positiva", "Negativa"].map(ch => (
          <button
            key={ch}
            className={"rc-source-chip dc-channel-chip" + (activeChannel === ch ? " active" : "")}
            style={activeChannel === ch ? {} : { color: CHANNEL_COLORS[ch], borderColor: CHANNEL_COLORS[ch] }}
            onClick={() => onChannelToggle(ch)}
          >
            {ch}
          </button>
        ))}
      </div>

      <div className="rc-entity-list">
        {[...grouped.entries()].map(([groupName, members]) => (
          <div key={groupName}>
            <div className="dc-group-header">{groupName}</div>
            {members.map(d => {
              const isSaved    = saved?.id === d.id;
              const isSelected = selected?.id === d.id;
              return (
                <button
                  key={d.id}
                  className={
                    "rc-entity-row" +
                    (isSelected ? " rc-selected" : "") +
                    (isSaved ? " rc-saved" : "")
                  }
                  onClick={() => onSelect(d)}
                >
                  <div className="rc-entity-main">
                    <ChannelDot energy={d.channel_energy}/>
                    <span className="rc-entity-name">{d.name}</span>
                  </div>
                  <div className="rc-entity-sub">
                    <span className="rc-attr-preview">{d.areas_of_influence}</span>
                    {isSaved && <span className="rc-saved-badge">✦ Devoto</span>}
                  </div>
                </button>
              );
            })}
          </div>
        ))}
        {deities.length === 0 && (
          <div className="rc-empty">Nenhuma divindade encontrada.</div>
        )}
      </div>
    </div>
  );
}

/* ============================================================
   POWER ROW  (expansível + seletor checkbox/rádio)
   ============================================================ */
function GrantedPowerRow({ power, selected, onSelect, disabled }) {
  const [open, setOpen] = useState(false);
  return (
    <div className={
      "dc-power-row" +
      (selected ? " dc-power-selected" : "") +
      (disabled ? " dc-power-disabled" : "")
    }>
      <div className="dc-power-head">
        <button
          type="button"
          className={"dc-power-radio" + (selected ? " is-selected" : "")}
          onClick={(e) => { e.stopPropagation(); onSelect(); }}
          disabled={disabled}
          title={selected ? "Remover poder" : disabled ? "Limite de poderes atingido" : "Escolher este poder"}
          aria-pressed={selected}
        >
          <span className="dc-power-radio-dot"/>
        </button>
        <span className="dc-power-name" onClick={() => setOpen(o => !o)}>
          {power.name}
        </span>
        <span className="dc-power-meta" onClick={() => setOpen(o => !o)}>
          <Kw kind="power-type">{power.power_type}</Kw>
          {power.power_category ? <> · {power.power_category}</> : null}
        </span>
        <span
          className="dc-power-chevron"
          onClick={() => setOpen(o => !o)}
          aria-label={open ? "Recolher" : "Expandir"}
        >{open ? "−" : "+"}</span>
      </div>
      {open && power.description && (
        <div className="dc-power-desc">
          {power.prerequisites && (
            <p style={{
              fontFamily: "var(--font-display)",
              fontSize: 10,
              letterSpacing: "0.16em",
              textTransform: "uppercase",
              color: "var(--ink-2)",
              margin: "0 0 6px",
            }}>
              Pré-requisito:{" "}
              <span style={{ fontFamily: "var(--font-body)", textTransform: "none", letterSpacing: 0 }}>
                {power.prerequisites}
              </span>
            </p>
          )}
          <Parsed>{power.description}</Parsed>
        </div>
      )}
    </div>
  );
}

/* ============================================================
   DEITY DETAIL  (página direita)
   ============================================================ */
function DeityDetail({
  deity, fullDeity, detailLoading,
  saved, onSave,
  chosenIds, togglePower, maxPowers, devotedClassName,
}) {
  if (!deity) {
    return (
      <div className="page-content">
        <header className="page-header">
          <span className="page-eyebrow">Detalhes</span>
          <span className="page-folio">—</span>
        </header>
        <div className="empty-state">
          <div className="ornament">✦ ✦ ✦</div>
          <div>Selecione uma divindade à esquerda.</div>
        </div>
      </div>
    );
  }

  const display = fullDeity || deity;
  const powers  = display.granted_powers || [];

  /* objetos dos poderes escolhidos (precisam estar carregados) */
  const chosenPowers = powers.filter(p => chosenIds.has(p.id));

  /* está salvo exatamente este combo? */
  const isSavedDeity = saved?.id === deity.id;
  const savedIds     = new Set((saved?.chosen_powers || []).map(p => p.id));
  const isExactSave  = isSavedDeity &&
    savedIds.size === chosenIds.size &&
    [...chosenIds].every(id => savedIds.has(id));

  const canSave = chosenIds.size === maxPowers && !isExactSave;

  /* label do botão */
  let saveLabel;
  if (isExactSave) {
    saveLabel = `✦ Devotado a ${deity.name}`;
  } else if (chosenIds.size === 0) {
    saveLabel = maxPowers === 1
      ? "Escolha um poder concedido"
      : `Escolha ${maxPowers} poderes concedidos`;
  } else if (chosenIds.size < maxPowers) {
    const faltam = maxPowers - chosenIds.size;
    saveLabel = `Escolha mais ${faltam} poder${faltam > 1 ? "es" : ""}`;
  } else if (isSavedDeity) {
    saveLabel = "Atualizar poderes";
  } else {
    saveLabel = `Devotar-se a ${deity.name}`;
  }

  /* hint da seção de poderes */
  let powerHint;
  if (chosenIds.size === maxPowers) {
    const names = chosenPowers.map(p => p.name).join(" · ");
    powerHint   = names
      ? { text: names, color: "var(--gilt-1)" }
      : { text: "restaurando escolha…", color: "var(--ink-2)" };
  } else {
    const faltam = maxPowers - chosenIds.size;
    powerHint = {
      text: `escolha ${faltam} poder${faltam > 1 ? "es" : ""}`,
      color: "var(--kw-condition)",
    };
  }

  /* badge de classe devota */
  const isDevotedClass = !!devotedClassName;

  return (
    <div className="page-content rc-detail-page">
      <header className="page-header">
        <span className="page-eyebrow">{deity.deity_group}</span>
        <span className="page-folio dc-channel-label" style={{ color: CHANNEL_COLORS[deity.channel_energy] }}>
          <ChannelDot energy={deity.channel_energy}/>
          {" "}{deity.channel_energy}
        </span>
      </header>

      <h1 className="page-title">{deity.name}</h1>

      {deity.motto && (
        <p className="page-subtitle" style={{ fontStyle: "italic" }}>
          "{deity.motto}"
        </p>
      )}

      {deity.other_names && (
        <p style={{ fontSize: 12, color: "var(--ink-2)", margin: "0 0 10px", fontStyle: "italic" }}>
          Também conhecida como: {deity.other_names}
        </p>
      )}

      <div className="rc-detail-body">
        <dl className="statblock">
          <div>
            <dt>Símbolo sagrado</dt>
            <dd>{deity.sacred_symbol || "—"}</dd>
          </div>
          <div>
            <dt>Arma preferida</dt>
            <dd>{deity.preferred_weapon || "—"}</dd>
          </div>
          <div>
            <dt>Plano divino</dt>
            <dd>{deity.divine_world || "—"}</dd>
          </div>
          <div>
            <dt>Energia canalizada</dt>
            <dd style={{ color: CHANNEL_COLORS[deity.channel_energy], fontWeight: 600 }}>
              {deity.channel_energy}
            </dd>
          </div>
          {deity.significant_colors && (
            <div style={{ gridColumn: "1 / -1" }}>
              <dt>Cores significativas</dt>
              <dd>{deity.significant_colors}</dd>
            </div>
          )}
        </dl>

        <div className="divider">❦</div>

        {deity.description && (
          <div style={{ marginBottom: 14 }}>
            {deity.description.split("\n\n").map((p, i) => (
              <p key={i} style={{
                fontSize: 13.5,
                lineHeight: 1.65,
                margin: "0 0 0.65em",
                color: "var(--ink-0)",
                textWrap: "pretty",
              }}>
                <Parsed>{p}</Parsed>
              </p>
            ))}
          </div>
        )}

        {deity.areas_of_influence && (
          <div style={{ marginBottom: 12 }}>
            <div className="rc-section-label">Áreas de Influência</div>
            <div className="dc-chip-row">
              {deity.areas_of_influence
                .split(",")
                .map(a => a.trim())
                .filter(Boolean)
                .map((area, i) => (
                  <span key={i} className="dc-area-chip">{area}</span>
                ))}
            </div>
          </div>
        )}

        {deity.beliefs_and_goals && (
          <div style={{ marginBottom: 12 }}>
            <div className="rc-section-label">Crenças e Objetivos</div>
            <p style={{
              fontSize: 13.5,
              fontStyle: "italic",
              color: "var(--ink-1)",
              margin: "4px 0 0",
              lineHeight: 1.6,
              textWrap: "pretty",
            }}>
              {deity.beliefs_and_goals}
            </p>
          </div>
        )}

        {deity.obligations && (
          <div style={{ marginBottom: 12 }}>
            <div className="rc-section-label">Obrigações dos Devotos</div>
            <p style={{
              fontSize: 13.5,
              color: "var(--ink-1)",
              margin: "4px 0 0",
              lineHeight: 1.6,
              textWrap: "pretty",
            }}>
              {deity.obligations}
            </p>
          </div>
        )}

        {((deity.devoted_races && deity.devoted_races.length > 0) ||
          (deity.devoted_classes && deity.devoted_classes.length > 0)) && (
          <div style={{ marginBottom: 14 }}>
            <div className="rc-section-label">Devotos Típicos</div>
            <div className="dc-chip-row" style={{ marginTop: 6 }}>
              {(deity.devoted_races || []).map((r, i) => (
                <span key={"r" + i} className="dc-devotee-chip dc-devotee-race">
                  <Kw kind="race">{r}</Kw>
                </span>
              ))}
              {(deity.devoted_classes || []).map((c, i) => (
                <span key={"c" + i} className="dc-devotee-chip dc-devotee-class">
                  <Kw kind="class">{c}</Kw>
                </span>
              ))}
            </div>
          </div>
        )}

        {/* poderes concedidos */}
        {(deity.granted_power_names && deity.granted_power_names.length > 0) && (
          <div style={{ marginBottom: 14 }}>
            <div className="rc-section-label" style={{ marginBottom: 6, display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
              <span>
                {maxPowers === 1 ? "Poder Concedido" : "Poderes Concedidos"}
              </span>

              {/* badge de classe devota */}
              {isDevotedClass && (
                <span className="dc-devoted-badge">
                  <Kw kind="class">{devotedClassName}</Kw>
                  {" · "}+1 poder
                </span>
              )}

              <span style={{
                fontFamily: "var(--font-body)",
                fontStyle: "italic",
                fontSize: 11,
                color: powerHint.color,
                textTransform: "none",
                letterSpacing: 0,
                fontWeight: 400,
              }}>
                {powerHint.text}
              </span>

              {!detailLoading && powers.length > 0 && (
                <span style={{
                  fontFamily: "var(--font-mono)",
                  fontSize: 10,
                  marginLeft: "auto",
                  color: "var(--ink-2)",
                }}>
                  {powers.length} disponíve{powers.length === 1 ? "l" : "is"}
                </span>
              )}
            </div>

            {/* slots visuais quando maxPowers > 1 */}
            {maxPowers > 1 && (
              <div className="dc-slots-row">
                {Array.from({ length: maxPowers }).map((_, i) => {
                  const p = chosenPowers[i];
                  return (
                    <div key={i} className={"dc-slot" + (p ? " dc-slot-filled" : "")}>
                      {p ? p.name : <span className="dc-slot-empty">vazio</span>}
                    </div>
                  );
                })}
              </div>
            )}

            {detailLoading ? (
              <div className="dc-powers-loading">
                {deity.granted_power_names.map((name, i) => (
                  <div key={i} className="dc-power-skeleton">{name}</div>
                ))}
              </div>
            ) : powers.length > 0 ? (
              <div className="dc-powers-list">
                {powers.map(p => {
                  const isSelected = chosenIds.has(p.id);
                  const isDisabled = !isSelected && chosenIds.size >= maxPowers;
                  return (
                    <GrantedPowerRow
                      key={p.id}
                      power={p}
                      selected={isSelected}
                      disabled={isDisabled}
                      onSelect={() => togglePower(p.id)}
                    />
                  );
                })}
              </div>
            ) : (
              <div style={{ fontStyle: "italic", color: "var(--ink-2)", fontSize: 13 }}>
                {deity.granted_power_names.join(" · ")}
              </div>
            )}
          </div>
        )}
      </div>

      <div className="rc-save-wrap">
        <button
          className={"rc-save-btn" + (isExactSave ? " is-saved" : "")}
          disabled={!canSave && !isExactSave}
          style={!canSave && !isExactSave ? { opacity: 0.5, cursor: "not-allowed" } : null}
          onClick={() => canSave && onSave(deity, chosenPowers)}
        >
          {saveLabel}
        </button>
      </div>
    </div>
  );
}

/* ============================================================
   DEITY CREATOR  (raiz da aba "divindade")
   ============================================================ */
function DeityCreator() {
  const [allDeities, setAllDeities]       = useState([]);
  const [loading, setLoading]             = useState(true);
  const [query, setQuery]                 = useState("");
  const [activeGroup, setActiveGroup]     = useState(null);
  const [activeChannel, setActiveChannel] = useState(null);
  const [selected, setSelected]           = useState(null);
  const [fullDeity, setFullDeity]         = useState(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [saved, setSaved]                 = useState(() => dcLsGet(LS_DEITY));
  /* conjunto de IDs de poderes selecionados */
  const [chosenIds, setChosenIds]         = useState(() => new Set());
  /* classes do personagem (multiclasse) — lidas no mount e sincronizadas em foco */
  const [savedClassNames, setSavedClassNames] = useState(() => getSavedClassNames());
  const devotedClass = getDevotedSavedClass(savedClassNames);
  const maxPowers    = getMaxPowers(savedClassNames);
  const allowedNames = useMemo(
    () => getAllowedDeities(savedClassNames),
    [savedClassNames]
  );

  /* atualiza classes se o jogador as trocou em outra aba */
  useEffect(() => {
    const sync = () => setSavedClassNames(getSavedClassNames());
    window.addEventListener("focus", sync);
    return () => window.removeEventListener("focus", sync);
  }, []);

  /* quando maxPowers diminui (ex: Paladino → Guerreiro), descarta excedentes */
  useEffect(() => {
    setChosenIds(prev => {
      if (prev.size <= maxPowers) return prev;
      return new Set([...prev].slice(0, maxPowers));
    });
  }, [maxPowers]);

  /* carga inicial: busca todas as divindades e restaura seleção */
  useEffect(() => {
    window.fetchDeities().then(data => {
      setAllDeities(data);
      setLoading(false);
      const s = dcLsGet(LS_DEITY);
      if (s) setSelected(data.find(d => d.id === s.id) || null);
    });
  }, []);

  /* carrega detalhe ao selecionar divindade; restaura poderes se for a salva */
  useEffect(() => {
    if (!selected) { setFullDeity(null); setChosenIds(new Set()); return; }
    setDetailLoading(true);
    setFullDeity(null);

    /* restaura IDs salvos respeitando o maxPowers atual.
       Suporta formato antigo (chosen_power) e novo (chosen_powers). */
    const s = dcLsGet(LS_DEITY);
    if (s?.id === selected.id) {
      const ids = s.chosen_powers
        ? s.chosen_powers.map(p => p.id)
        : s.chosen_power?.id
          ? [s.chosen_power.id]
          : [];
      setChosenIds(new Set(ids.slice(0, maxPowers)));
    } else {
      setChosenIds(new Set());
    }

    window.fetchDeity(selected.id).then(data => {
      setFullDeity(data);
      setDetailLoading(false);
    });
  }, [selected && selected.id]);

  /* toggle de um poder: adiciona/remove respeitando maxPowers */
  const togglePower = (powerId) => {
    setChosenIds(prev => {
      const next = new Set(prev);
      if (next.has(powerId)) {
        next.delete(powerId);
      } else if (next.size < maxPowers) {
        next.add(powerId);
      }
      /* se maxPowers === 1 e já há um selecionado, substituir */
      else if (maxPowers === 1) {
        next.clear();
        next.add(powerId);
      }
      return next;
    });
  };

  const groups = useMemo(
    () => [...new Set(allDeities.map(d => d.deity_group))],
    [allDeities]
  );

  const filtered = useMemo(() => {
    let out = allDeities;
    /* restrição por classe (Druida só pode Allihanna, Megalokk, Oceano, Aharadak, Tenebra) */
    if (Array.isArray(allowedNames)) {
      const set = new Set(allowedNames);
      out = out.filter(d => set.has(d.name));
    }
    if (activeGroup)   out = out.filter(d => d.deity_group === activeGroup);
    if (activeChannel) out = out.filter(d => d.channel_energy === activeChannel);
    const q = query.toLowerCase().trim();
    if (q) out = out.filter(d =>
      d.name.toLowerCase().includes(q) ||
      (d.areas_of_influence || "").toLowerCase().includes(q) ||
      (d.other_names || "").toLowerCase().includes(q) ||
      (d.deity_group || "").toLowerCase().includes(q)
    );
    return out;
  }, [allDeities, query, activeGroup, activeChannel, allowedNames]);

  const handleSave = (deity, chosenPowers) => {
    const val = {
      id: deity.id,
      name: deity.name,
      deity_group: deity.deity_group,
      chosen_powers: chosenPowers.map(p => ({ id: p.id, name: p.name })),
    };
    dcLsSet(LS_DEITY, val);
    setSaved(val);
  };

  if (loading) {
    return (
      <div className="cc-root">
        <div className="spread-frame">
          <div className="page left">
            <DCCorners/>
            <div className="page-content">
              <div className="empty-state">
                <div className="ornament">·</div>
                <div>Consultando os panteões…</div>
              </div>
            </div>
          </div>
          <div className="page right">
            <DCCorners/>
            <div className="page-content"/>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="cc-root">
      <div className="spread-frame">
        <div className="page left">
          <DCCorners/>
          <DeityList
            deities={filtered}
            total={allDeities.length}
            selected={selected}
            saved={saved}
            onSelect={setSelected}
            query={query}
            setQuery={setQuery}
            groups={groups}
            activeGroup={activeGroup}
            onGroupToggle={g => setActiveGroup(prev => prev === g ? null : g)}
            activeChannel={activeChannel}
            onChannelToggle={ch => setActiveChannel(prev => prev === ch ? null : ch)}
            restrictionHint={
              allowedNames
                ? `Sua classe permite apenas: ${allowedNames.join(" · ")}`
                : null
            }
          />
        </div>
        <div className="page right">
          <DCCorners/>
          <DeityDetail
            deity={selected}
            fullDeity={fullDeity}
            detailLoading={detailLoading}
            saved={saved}
            onSave={handleSave}
            chosenIds={chosenIds}
            togglePower={togglePower}
            maxPowers={maxPowers}
            devotedClassName={devotedClass}
          />
        </div>
      </div>
    </div>
  );
}

window.DeityCreator = DeityCreator;
