// Standalone BOT ATTACKS board. It intentionally uses its own deterministic
// image-slot ids and does not read or write battle cards/weeks.
const { useState: useSbf, useEffect: useEffBf } = React;

const BOT_FIGHT_SECTIONS = [
  { id: "citadel", labelKey: "botFightCitadel", kind: "heroes", count: 7, layout: "wide" },
  { id: "ice-bastion", labelKey: "botFightIceBastion", kind: "titans", count: 4 },
  { id: "nature-gate", labelKey: "botFightNatureGate", kind: "titans", count: 4 },
  { id: "fire-bastion", labelKey: "botFightFireBastion", kind: "titans", count: 4 },
  { id: "bridge", labelKey: "botFightBridge", kind: "titans", count: 4, layout: "wide" },
  { id: "elements-source", labelKey: "botFightElementsSource", kind: "titans", count: 4 },
  { id: "lighthouse", labelKey: "botFightLighthouse", kind: "heroes", count: 3 },
  { id: "foundry", labelKey: "botFightFoundry", kind: "heroes", count: 4 },
  { id: "mage-academy", labelKey: "botFightMageAcademy", kind: "heroes", count: 3 },
  { id: "barracks", labelKey: "botFightBarracks", kind: "heroes", count: 3 },
];

function botFightSlotId(guildId, sectionId, index) {
  return `botfight-${guildId}-${sectionId}-${index}`;
}

function botFightMetaId(guildId, sectionId, index) {
  return `botfight-meta-${guildId}-${sectionId}-${index}`;
}

function loadBotFightGuildSlots(guildId, summary = false) {
  return fetch("/api/botfight-slots?guild=" + encodeURIComponent(guildId) + (summary ? "&summary=1" : "") + "&t=" + Date.now(), { cache: "no-store" })
    .then((r) => {
      if (!r.ok) throw new Error("botfight slots " + r.status);
      return r.json();
    });
}

function BotFightSlotButton({ guildId, section, index, onOpen, filled, nickname, loading }) {
  const slotId = botFightSlotId(guildId, section.id, index);
  return (
    <button
      className={`g2-botfight-slot is-${section.kind}${filled ? " is-filled" : ""}${loading ? " is-loading" : ""}`}
      onClick={() => onOpen({ section, index, slotId, nickname, guildId })}
      disabled={loading}
      aria-busy={loading || undefined}
      title={hwT("botFightOpenSlot", { n: index + 1 })}
      aria-label={hwT("botFightOpenSlot", { n: index + 1 })}
    >
      <span>{index + 1}</span>
    </button>
  );
}

function BotFightBoard2({ guild, onOpen }) {
  if (!guild) return null;
  const slotIds = BOT_FIGHT_SECTIONS.flatMap((section) => (
    Array.from({ length: section.count }, (_, index) => botFightSlotId(guild.id, section.id, index))
  ));
  const [filledIds, setFilledIds] = useSbf(new Set());
  const [nicknames, setNicknames] = useSbf({});
  const [statusReady, setStatusReady] = useSbf(false);
  useEffBf(() => {
    let alive = true;
    let refreshBusy = false;
    let localChangeSeq = 0;
    setStatusReady(false);
    const metaIds = BOT_FIGHT_SECTIONS.flatMap((section) => (
      Array.from({ length: section.count }, (_, index) => botFightMetaId(guild.id, section.id, index))
    ));
    const refresh = () => {
      if (refreshBusy) return;
      refreshBusy = true;
      const seq = localChangeSeq;
      loadBotFightGuildSlots(guild.id, true).then((slots) => {
      if (!alive || !slots || seq !== localChangeSeq) return;
      setFilledIds(new Set(Object.entries(slots || {}).filter(([, value]) => (
        window.HW_slotIsFilled ? window.HW_slotIsFilled(value) : !!(value && value.filled)
      )).map(([id]) => id)));
      const nextNicknames = {};
      metaIds.forEach((id) => {
        const value = slots && slots[id];
        if (value && typeof value === "object" && value.nickname) nextNicknames[id] = String(value.nickname);
      });
      setNicknames(nextNicknames);
      setStatusReady(true);
      }).catch(() => {}).finally(() => { refreshBusy = false; });
    };
    const onChange = (e) => {
      const detail = e.detail || {};
      if (!slotIds.includes(detail.id)) return;
      localChangeSeq += 1;
      setFilledIds((current) => {
        const next = new Set(current);
        if (detail.filled) next.add(detail.id); else next.delete(detail.id);
        return next;
      });
    };
    refresh();
    const timer = setInterval(refresh, 5000);
    window.addEventListener("hw-image-slot-change", onChange);
    return () => { alive = false; clearInterval(timer); window.removeEventListener("hw-image-slot-change", onChange); };
  }, [guild.id]);
  return (
    <section className="g2-botfight">
      <div className="g2-botfight-heading">
        <div>
          <div className="g2-botfight-kicker">{guild.name}</div>
          <h2>{hwT("botAttacks")}</h2>
        </div>
        <div className="g2-botfight-legend">
          <span><i className="g2-botfight-mini is-heroes"></i>{hwT("heroes")}</span>
          <span><i className="g2-botfight-mini is-titans"></i>{hwT("titans")}</span>
        </div>
      </div>
      <div className="g2-botfight-grid">
        {BOT_FIGHT_SECTIONS.map((section) => (
          <article key={section.id} className={`g2-botfight-card${section.layout === "wide" ? " is-wide" : ""}`}>
            <h3>{hwT(section.labelKey)}</h3>
            <div className="g2-botfight-slots">
              {Array.from({ length: section.count }, (_, index) => (
                <BotFightSlotButton key={index} guildId={guild.id} section={section} index={index}
                  filled={filledIds.has(botFightSlotId(guild.id, section.id, index))}
                  loading={!statusReady} nickname={nicknames[botFightMetaId(guild.id, section.id, index)] || ""} onOpen={onOpen} />
              ))}
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

function BotFightPopup2({ ctx, onClose }) {
  useEffBf(() => {
    const h = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", h);
    return () => document.removeEventListener("keydown", h);
  }, []);
  if (!ctx) return null;
  const color = ctx.section.kind === "heroes" ? "var(--hero)" : "var(--titan)";
  return (
    <div onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }} style={{
      position: "fixed", inset: 0, zIndex: 100, display: "grid", placeItems: "center",
      background: "rgba(5,10,20,.7)", backdropFilter: "blur(4px)", padding: 16, overflow: "auto",
    }}>
      <div style={{
        width: "min(780px, 96vw)", background: "var(--surface)", border: "1px solid var(--card-border)",
        borderRadius: 18, overflow: "hidden", boxShadow: "0 40px 90px -24px rgba(0,0,0,.85)",
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "16px 18px", borderBottom: "1px solid var(--card-border)" }}>
          <div style={{
            fontFamily: "var(--font-mono)", fontSize: 11, fontWeight: 800, letterSpacing: ".08em", textTransform: "uppercase",
            padding: "6px 12px", borderRadius: 999, color, whiteSpace: "nowrap",
            background: `color-mix(in oklab, ${color} 18%, transparent)`, border: `1px solid color-mix(in oklab, ${color} 48%, transparent)`,
          }}>{ctx.section.kind === "heroes" ? hwT("heroes") : hwT("titans")}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 16, fontWeight: 800, color: "var(--text)" }}>{hwT(ctx.section.labelKey)}</div>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-faint)", marginTop: 3 }}>
              {hwT("botFightPosition", { n: ctx.index + 1 })}{ctx.nickname ? ` · ${ctx.nickname}` : ""}
            </div>
          </div>
          <button onClick={onClose} className="g2-x" style={{ width: 32, height: 32, borderRadius: 10, cursor: "pointer", flexShrink: 0, background: "var(--surface-2)", border: "1px solid var(--card-border)", color: "var(--text-dim)", fontSize: 15 }}>×</button>
        </div>
        <div style={{ padding: 18 }}>
          <BotScreenshots2 slotIds={[ctx.slotId]} loader={() => loadBotFightGuildSlots(ctx.guildId)} />
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { BOT_FIGHT_SECTIONS, botFightSlotId, botFightMetaId, BotFightBoard2, BotFightPopup2 });
