﻿// Admin dashboard — tabs: Verifisering | Turneringer | Brukere
const AdminDashboard = ({ tweaks, role = "admin" }) => {
  const isSuper = role === "superadmin";
  const isAdminPlus = role === "admin" || isSuper;
  const isMod = role === "mod";

  // Default tab: highest-privilege user lands on their primary work surface
  const defaultTab = isAdminPlus ? "verify" : "verify";
  const [tab, setTab] = useState(defaultTab);
  const [wizardOpen, setWizardOpen] = useState(false);
  const [editingTournament, setEditingTournament] = useState(null);
  const [createToast, setCreateToast] = useState(null);

  const tabs = [
    { id: "verify",       label: "VERIFISERING",    code: "01", allowed: true },
    { id: "registrations",label: "LAG-SØKNADER",    code: "02", allowed: isAdminPlus,
      lockNote: "Krever Admin eller Super Admin" },
    { id: "disputes",     label: "PROTESTER",       code: "03", allowed: true },
    { id: "tournaments",  label: "TURNERINGER",     code: "04", allowed: isAdminPlus,
      lockNote: "Krever Admin eller Super Admin" },
    { id: "users",        label: "BRUKERE & ROLLER",code: "05", allowed: isSuper || role === "admin",
      lockNote: isSuper ? null : (role === "admin" ? "Du kan se brukere, men kun Super Admin kan endre roller" : "Krever Super Admin") },
  ];

  return (
    <div className="admin admin-tabbed">
      <div className="admin-banner">
        <div className="ab-left">
          <div className="ab-eyebrow">
            <span className="trn-pip" style={{background: tweaks.accent}}/>
            <span>ADMIN-KONSOLL · SECTOR-NO</span>
            <span className="ab-role" style={{borderColor: tweaks.accent, color: tweaks.accent}}>
              {window.ROLE_LABELS[role]}
            </span>
          </div>
          <h1 className="ab-title">
            {tab === "verify" && "VERIFISERING"}
            {tab === "registrations" && "LAG-SØKNADER"}
            {tab === "tournaments" && "TURNERINGS-ADMINISTRASJON"}
            {tab === "users" && "BRUKERE & ROLLER"}
          </h1>
        </div>
        <div className="ab-right">
          {tab === "verify" && (
            <div className="admin-pulse">
              <span className="pulse-dot" style={{background: tweaks.accent}}/>
              <span>LIVE · WS-FEED TILKOBLET</span>
            </div>
          )}
        </div>
      </div>

      <div className="admin-tabbar">
        {tabs.map(t => (
          <button
            key={t.id}
            className={`adm-tab ${tab === t.id ? "active" : ""} ${!t.allowed ? "locked" : ""}`}
            onClick={() => t.allowed && setTab(t.id)}
            disabled={!t.allowed}
            style={tab === t.id ? {borderColor: tweaks.accent} : null}
            title={t.lockNote || ""}
          >
            <span className="adm-tab-code">{t.code}</span>
            <span className="adm-tab-lab">{t.label}</span>
            {!t.allowed && <span className="adm-tab-lock">🔒</span>}
          </button>
        ))}
      </div>

      {tab === "verify" && <VerifyView tweaks={tweaks} role={role}/>}
      {tab === "registrations" && isAdminPlus && <RegistrationsView tweaks={tweaks}/>}
      {tab === "disputes" && <DisputesView tweaks={tweaks}/>}
      {tab === "tournaments" && isAdminPlus && (
        <AdminTournamentList
          tweaks={tweaks}
          onCreate={() => { setEditingTournament(null); setWizardOpen(true); }}
          onEdit={(t) => { setEditingTournament(t); setWizardOpen(true); }}
        />
      )}
      {tab === "users" && (isSuper || role === "admin") && <RoleManager tweaks={tweaks} currentRole={role}/>}

      {wizardOpen && (
        <TournamentWizard
          tweaks={tweaks}
          editing={!!editingTournament}
          initialForm={editingTournament ? {
            ...(editingTournament.format_raw || {}),
            // Sørg for at name og publishState reflekterer DB-data
            name: editingTournament.name || "",
            description: editingTournament.format_raw?.description || "",
            publishState: editingTournament.status || "draft",
            startsAt: editingTournament.start_date || "",
            type: editingTournament.format_raw?.type || (editingTournament.type === "killrace" ? "killrace" : "2v2"),
            maps: editingTournament.maps || [],
            capacity: editingTournament.max_teams || 16,
            entryFee: editingTournament.entry_fee || 0,
          } : null}
          onClose={() => { setWizardOpen(false); setEditingTournament(null); }}
          onSave={async (form) => {
            const payload = {
              name: form.name || "Uten navn",
              type: form.type === "killrace" ? "killrace"
                  : form.type === "custom" ? "custom"
                  : form.type === "switcharoo" ? "switcharoo"
                  : "bracket",
              status: form.publishState || "draft",
              start_date: form.startsAt || null,
              max_teams: form.capacity || form.bracketCapacity || 16,
              team_size: (form.type === "killrace" || form.type === "custom") ? (form.krTeamSize || "trios") : "duos",
              maps: form.maps || [],
              games: (form.type === "killrace" || form.type === "custom") ? (form.krRounds || 5) : null,
              prize_pool: (() => {
                const totalEntries = (form.capacity || 16) * (form.entryFee || 0);
                return totalEntries + (form.cashInjection || 0);
              })(),
              entry_fee: form.entryFee || 0,
              scoring: form.type === "killrace" ? (form.krCustomScoring || null) : (form.bracketBo || null),
              rules: form.rulesText || null,
              format_raw: form,
            };
            const result = editingTournament
              ? await WZN_Store.updateTournament(editingTournament.id, payload)
              : await WZN_Store.createTournament(payload);
            setWizardOpen(false);
            setEditingTournament(null);
            if (!result.error) {
              setCreateToast({
                name: payload.name,
                state: payload.status,
                time: new Date().toTimeString().slice(0,8),
                editing: !!editingTournament,
              });
              setTimeout(() => setCreateToast(null), 4500);
              if (typeof AdminTournamentList._refresh === "function") AdminTournamentList._refresh();
            } else {
              alert("Feil ved lagring: " + result.error.message);
            }
          }}
        />
      )}

      {createToast && (
        <div className="toast" style={{borderColor: tweaks.accent}}>
          <span className="toast-pulse" style={{background: tweaks.accent}} />
          <div>
            <div className="toast-title">TURNERING OPPRETTET · {createToast.time}</div>
            <div className="toast-body">
              <b>{createToast.name}</b> · status <b style={{color: tweaks.accent}}>{createToast.state.toUpperCase()}</b>
            </div>
          </div>
          <button className="toast-x" onClick={() => setCreateToast(null)}>✕</button>
        </div>
      )}
    </div>
  );
};

const VerifyView = ({ tweaks, role }) => {
  const [pending, setPending] = useState([]);
  const [loadingPending, setLoadingPending] = useState(true);
  const [selected, setSelected] = useState(null);
  const [publishedToast, setPublishedToast] = useState(null);
  const [leaderboard, setLeaderboard] = useState([]);
  const [verifying, setVerifying] = useState(false);
  const [lightbox, setLightbox] = useState(false);
  const [rejectReason, setRejectReason] = useState("");

  // Normaliser Supabase snake_case → camelCase for UI-kompatibilitet
  const normSub = (s) => ({
    ...s,
    submittedAt:    s.submitted_at    || s.submittedAt    || "",
    submittedBy:    s.submitted_by    || s.submittedBy    || "—",
    submittedByTag: s.submitted_by_tag|| s.submittedByTag || "",
    teamId:         s.team_id         || s.teamId         || null,
    screenshotLabel:s.screenshot_label|| s.screenshotLabel|| "",
    flagReason:     s.flag_reason     || s.flagReason     || null,
    players:        s.players         || [],
    screenshots:    s.screenshots     || {},
  });

  useEffect(() => {
    WZN_Store.getSubmissions().then(data => {
      const normed = (data || []).map(normSub);
      setPending(normed);
      if (normed.length > 0) setSelected(normed[0].id);
      setLoadingPending(false);
    });
    const onKey = (e) => { if (e.key === "Escape") setLightbox(false); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const current = pending.find(p => p.id === selected) || pending[0];

  // EWC Liga-multiplier (matche store.jsx calcLigaPoints)
  const ligaMult = (placement) => {
    const p = Math.max(1, parseInt(placement) || 1);
    if (p === 1)       return 1.6;
    if (p <= 5)        return 1.4;
    if (p <= 10)       return 1.2;
    return 1.0;
  };

  const approve = () => {
    if (!current) return;
    setVerifying(true);
    setTimeout(() => {
      const totalKills = current.players
        ? current.players.reduce((a, p) => a + (p.kills || 0), 0)
        : (current.kills || 0);

      // Velg poeng-formel basert på turnerings-type
      const tType = (current.tournament_type || current.type || "bracket").toLowerCase();
      let bonusInt;
      if (tType === "killrace") {
        bonusInt = totalKills;
      } else if (tType === "cmg" || tType === "2v2" || tType === "switcharoo") {
        // CMG er bracket-format — runden vinnes av kills, ingen LP-akkumulering
        bonusInt = 0;
      } else {
        // Liga / bracket: EWC kills × placement-multiplier
        bonusInt = Math.round(totalKills * ligaMult(current.placement) * 10) / 10;
      }

      // Persist to store
      if (current.teamId) {
        window.WZN_Store.approveSubmission(current.id, current.teamId, bonusInt);
      }

      // Find the correct team in leaderboard, fall back to random
      const teamIdx = leaderboard.findIndex(t => t.id === current.teamId);
      const targetIdx = teamIdx >= 0 ? teamIdx : Math.floor(Math.random() * 4) + 1;

      setLeaderboard(prev => {
        const next = prev.map((t, i) => i === targetIdx
          ? { ...t, animating: true, deltaPoints: bonusInt, lp: t.lp + bonusInt }
          : t
        );
        return next.sort((a,b) => b.lp - a.lp).map((t,i) => ({...t, pos: i+1}));
      });
      setPublishedToast({
        team: current.submittedBy,
        points: bonusInt,
        time: new Date().toTimeString().slice(0,8),
      });
      setTimeout(() => {
        setLeaderboard(prev => prev.map(t => ({...t, animating: false, deltaPoints: 0})));
      }, 2200);
      setTimeout(() => setPublishedToast(null), 4500);
      setPending(p => p.filter(x => x.id !== current.id));
      setVerifying(false);
      if (pending.length > 1) {
        setSelected(pending.find(x => x.id !== current.id)?.id);
      }
    }, 900);
  };

  const reject = () => {
    if (current?.teamId) {
      window.WZN_Store.rejectSubmission(current.id, rejectReason.trim() || null);
    }
    setRejectReason("");
    setPending(p => p.filter(x => x.id !== current.id));
    if (pending.length > 1) setSelected(pending.find(x => x.id !== current.id)?.id);
  };

  return (
    <div className="admin-verify-wrap">
      <div className="admin-grid">
        {/* Pending queue */}
        <div className="admin-queue">
          <div className="aq-head">
            <span>KØ · {pending.length}</span>
            <span className="aq-sort">DATO ↓</span>
          </div>
          {loadingPending && (
            <div className="aq-empty"><div>Laster innsendinger…</div></div>
          )}
          {!loadingPending && pending.length === 0 && (
            <div className="aq-empty">
              <div className="aq-empty-icon">✓</div>
              <div>Kø tom. Alt verifisert.</div>
            </div>
          )}
          {pending.map(p => (
            <button
              key={p.id}
              className={`aq-item ${selected === p.id ? "active" : ""} ${p.flagged ? "flagged" : ""}`}
              onClick={() => setSelected(p.id)}
              style={selected === p.id ? {borderColor: tweaks.accent} : null}
            >
              <div className="aq-item-top">
                <span className="aq-tag" style={{color: tweaks.accent, borderColor: tweaks.accent}}>{p.submittedByTag}</span>
                <span className="aq-time">{p.submittedAt.slice(11,16)}</span>
              </div>
              <div className="aq-team">{p.submittedBy.toUpperCase()}</div>
              <div className="aq-sub">{p.tournament} · GAME {p.game} · #{p.placement}</div>
              {p.flagged && <div className="aq-flag">⚠ FLAGGET</div>}
            </button>
          ))}
        </div>

        {/* Verifier */}
        {current ? (
          <div className="admin-verify">
            <div className="av-head">
              <div>
                <div className="av-eyebrow">RAPPORT-ID / {current.id.toUpperCase()}</div>
                <h2 className="av-title">{current.submittedBy.toUpperCase()} <span className="av-tag" style={{color: tweaks.accent}}>· {current.submittedByTag}</span></h2>
                <div className="av-meta">
                  <span><span className="dim">KAPTEIN</span> {current.captain}</span>
                  <span className="sep">·</span>
                  <span><span className="dim">TURN</span> {current.tournament}</span>
                  <span className="sep">·</span>
                  <span><span className="dim">GAME</span> #{current.game}</span>
                  <span className="sep">·</span>
                  <span><span className="dim">INNSENDT</span> {current.submittedAt.slice(11,16)}</span>
                </div>
              </div>
              <div className="av-placement">
                <div className="ap-lab">RAPPORTERT</div>
                <div className="ap-num" style={{color: tweaks.accent}}>#{current.placement}</div>
              </div>
            </div>

            {current.flagged && (
              <div className="av-flag">
                <span className="flag-icon">⚠</span>
                <div>
                  <b>SYSTEM FLAGG:</b> {current.flagReason}
                </div>
              </div>
            )}

            <div className="av-split">
              <div className="av-screenshot">
                <div className="av-screenshot-head">
                  <div className="ass-title">
                    <span className="ass-eye">OPPLASTEDE SCREENSHOTS</span>
                    <span className="ass-sub">{current.screenshotLabel}</span>
                  </div>
                  <button className="ghost-btn small" onClick={() => setLightbox(true)}>UTVID ↗</button>
                </div>
                <div className="av-dual-shots">
                  <div className="av-shot-tile" onClick={() => setLightbox(true)}>
                    <div className="av-shot-label" style={{color: tweaks.accent}}>SCOREBOARD</div>
                    <img src={current.screenshots?.scoreboard || "assets/sample-scoreboard.png"} alt="scoreboard" className="av-shot-img"/>
                  </div>
                  <div className="av-shot-tile" onClick={() => setLightbox(true)}>
                    <div className="av-shot-label" style={{color: tweaks.accent}}>PLACEMENT</div>
                    <PlacementMock accent={tweaks.accent} placement={current.placement}/>
                  </div>
                </div>
                <div className="av-screenshot-meta">
                  <div className="assm-row"><span>SCOREBOARD</span><b>sb_md10_g{current.game}.png · 2.4 MB</b></div>
                  <div className="assm-row"><span>PLACEMENT</span><b>pl_md10_g{current.game}.png · 1.1 MB</b></div>
                  <div className="assm-row"><span>OPPLASTET</span><b>{current.submittedAt.slice(11,16)} av {current.captain}</b></div>
                  <div className="assm-row"><span>HASH</span><b className="mono-tiny">SHA-256 · {current.id.toLowerCase()}9f4a…</b></div>
                </div>

                {current.aiExtraction && (
                  <div className="av-ai-block" style={{borderColor: tweaks.accent}}>
                    <div className="av-ai-head">
                      <span className="ai-badge" style={{background: tweaks.accent}}>AI</span>
                      <span className="av-ai-title">EKSTRAKSJON</span>
                      <span className="ai-conf" style={{color: tweaks.accent}}>{Math.round(current.aiExtraction.confidence*100)}% SIKKERHET</span>
                    </div>
                    <table className="ai-table compact">
                      <thead><tr><th>SPILLER</th><th>K</th><th>D</th><th>DMG</th><th>KONF.</th></tr></thead>
                      <tbody>
                        {current.aiExtraction.players.map((p, i) => {
                          const reported = current.players[i];
                          const mismatch = reported && reported.kills !== p.kills;
                          return (
                            <tr key={i} className={mismatch ? "mismatch" : ""}>
                              <td><b>{p.name}</b></td>
                              <td className="num">{p.kills}{mismatch && <span className="diff">≠{reported.kills}</span>}</td>
                              <td className="num">{p.deaths}</td>
                              <td className="num">{p.damage}</td>
                              <td><span className="conf-pill" style={{borderColor: tweaks.accent, color: tweaks.accent}}>{Math.round(p.confidence*100)}%</span></td>
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                    {current.aiExtraction.flags?.length > 0 && (
                      <div className="ai-flag-list">
                        {current.aiExtraction.flags.map((f, i) => (
                          <div key={i} className="ai-flag-row">⚠ {f}</div>
                        ))}
                      </div>
                    )}
                  </div>
                )}
              </div>

              <div className="av-stats">
                <div className="avs-head">
                  RAPPORTERT STATISTIKK · KAPTEIN
                  {(() => {
                    const tType = (current.tournament_type || current.type || "bracket").toLowerCase();
                    const mult = ligaMult(current.placement);
                    const totalK = current.players ? current.players.reduce((a,p) => a+(p.kills||0), 0) : (current.kills || 0);
                    const totalDmg = current.players ? current.players.reduce((a,p) => a+(p.damage||0), 0) : (current.damage || 0);
                    const isCmg = tType === "cmg" || tType === "2v2" || tType === "switcharoo";
                    const calcPts = tType === "killrace" ? totalK : isCmg ? 0 : Math.round(totalK * mult * 10) / 10;
                    return (
                      <span style={{marginLeft: 16, fontFamily: "var(--font-mono)", fontSize: 11, color: tweaks.accent}}>
                        {tType === "killrace"
                          ? `KILLRACE · ${totalK} kills = ${calcPts} LP`
                          : isCmg
                            ? `CMG 2V2 · ${totalK} kills + ${totalDmg.toLocaleString()} dmg → bracket (ingen LP)`
                            : `EWC · ${totalK}k × ×${mult} (plass ${current.placement || "?"}) = ${calcPts} LP`
                        }
                      </span>
                    );
                  })()}
                </div>
                {(() => {
                    const tType = (current.tournament_type || current.type || "bracket").toLowerCase();
                    const isCmg = tType === "cmg" || tType === "2v2" || tType === "switcharoo";
                    const mult = ligaMult(current.placement);
                    const totalK = current.players ? current.players.reduce((a,p) => a+(p.kills||0), 0) : (current.kills||0);
                    const totalD = current.players ? current.players.reduce((a,p) => a+(p.deaths||0), 0) : 0;
                    const totalDmg = current.players ? current.players.reduce((a,p) => a+(p.damage||0), 0) : (current.damage||0);
                    const totalPts = tType === "killrace" ? totalK : isCmg ? 0 : Math.round(totalK * mult * 10) / 10;
                    return (
                      <table className="avs-table">
                        <thead>
                          <tr>
                            <th>SPILLER</th><th>K</th><th>D</th>
                            {isCmg ? <th>DMG</th> : <th>LP</th>}
                          </tr>
                        </thead>
                        <tbody>
                          {current.players.map((p,i) => {
                            const pts = tType === "killrace" ? (p.kills||0) : isCmg ? null : Math.round((p.kills||0)*mult*10)/10;
                            return (
                              <tr key={i}>
                                <td><b>{p.name}</b></td>
                                <td className="num"><input className="kill-edit" defaultValue={p.kills} /></td>
                                <td className="num"><input className="kill-edit" defaultValue={p.deaths||0} /></td>
                                {isCmg
                                  ? <td className="num" style={{color: tweaks.accent}}>{(p.damage||0).toLocaleString()}</td>
                                  : <td className="num" style={{color: tweaks.accent}}>+{pts}</td>
                                }
                              </tr>
                            );
                          })}
                        </tbody>
                        <tfoot>
                          <tr>
                            <td><b>TOTAL</b></td>
                            <td className="num"><b>{totalK}</b></td>
                            <td className="num"><b>{totalD}</b></td>
                            {isCmg
                              ? <td className="num big" style={{color: tweaks.accent}}>{totalDmg.toLocaleString()}</td>
                              : <td className="num big" style={{color: tweaks.accent}}>+{totalPts}</td>
                            }
                          </tr>
                          {isCmg && (
                            <tr>
                              <td colSpan="4" style={{paddingTop: 8, fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-dim)"}}>
                                VINNER: flest kills → damage som tiebreaker · ingen LP (bracket-avansement)
                              </td>
                            </tr>
                          )}
                        </tfoot>
                      </table>
                    );
                  })()}

                <div className="avs-reject-reason">
                  <label className="avs-reject-label">AVVISNINGSGRUNN <span style={{color:"var(--text-faint)"}}>(valgfritt — sendes til kaptein via Discord DM)</span></label>
                  <input
                    className="avs-reject-input"
                    type="text"
                    value={rejectReason}
                    onChange={e => setRejectReason(e.target.value)}
                    placeholder="F.eks. Screenshot mangler scoreboard, feil turnering, etc."
                    maxLength={200}
                  />
                </div>
                <div className="avs-actions">
                  <button className="action-reject" onClick={reject} disabled={verifying}>
                    ✕ AVVIS
                  </button>
                  <button className="action-edit">
                    ✎ JUSTER MANUELT
                  </button>
                  <button
                    className="action-approve"
                    onClick={approve}
                    disabled={verifying}
                    style={{background: tweaks.accent}}
                  >
                    {verifying ? "PUBLISERER…" : "✓ GODKJENN & PUBLISER"}
                  </button>
                </div>
              </div>
            </div>
          </div>
        ) : (
          <div className="admin-verify empty">
            <div className="empty-stamp">KØ TOM</div>
            <div className="empty-text">Alle innsendelser er behandlet.</div>
          </div>
        )}

        {/* Live leaderboard */}
        <div className="admin-live">
          <div className="al-head">
            <div>
              <div className="al-eye">LIVE LEDERTAVLE · DIV.1</div>
              <div className="al-sub">Oppdateres ved publisering</div>
            </div>
            <div className="al-pulse" style={{color: tweaks.accent}}>
              <span className="pulse-dot" style={{background: tweaks.accent}} /> WS
            </div>
          </div>
          <div className="al-list">
            {leaderboard.map((t, i) => (
              <div key={t.id} className={`al-row ${t.animating ? "animating" : ""}`}
                   style={t.animating ? {borderColor: tweaks.accent, background: `${tweaks.accent}14`} : null}>
                <span className="al-pos">{String(t.pos || i+1).padStart(2,"0")}</span>
                <div className="al-team">
                  <span className="al-tag" style={{borderColor: tweaks.accent, color: tweaks.accent}}>{t.tag}</span>
                  <span className="al-name">{t.name.toUpperCase()}</span>
                </div>
                <div className="al-points">
                  <span className="al-LP">{t.lp.toLocaleString()}</span>
                  {t.animating && t.deltaPoints > 0 && (
                    <span className="al-bump" style={{color: tweaks.accent}}>+{t.deltaPoints}</span>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {lightbox && current && (
        <div className="lightbox" onClick={() => setLightbox(false)}>
          <div className="lightbox-bar">
            <div className="lb-title">
              <span style={{color: tweaks.accent}}>● VERIFISERING</span>
              <span className="lb-sep">/</span>
              <span>{current.submittedBy.toUpperCase()} — {current.tournament} — GAME #{current.game}</span>
            </div>
            <button className="lb-close" onClick={() => setLightbox(false)}>✕ LUKK (ESC)</button>
          </div>
          <div className="lightbox-stage" onClick={e => e.stopPropagation()}>
            <div className="lightbox-img">
              <img src={current.screenshots?.scoreboard || "assets/sample-scoreboard.png"} alt="scoreboard" style={{width:"100%", height:"auto", display:"block"}}/>
              <div className="lb-placement-strip">
                <PlacementMock accent={tweaks.accent} placement={current.placement}/>
              </div>
            </div>
            <div className="lightbox-side">
              <div className="lbs-block">
                <div className="lbs-eye">RAPPORTERT</div>
                <div className="lbs-big" style={{color: tweaks.accent}}>#{current.placement}</div>
                <div className="lbs-cap">PLACEMENT</div>
              </div>
              <div className="lbs-block">
                <div className="lbs-eye">AI-EKSTRAKSJON · {current.aiExtraction ? Math.round(current.aiExtraction.confidence*100) : 0}%</div>
                {current.aiExtraction?.players.map((p,i) => (
                  <div key={i} className="lbs-row">
                    <span>{p.name}</span>
                    <b>{p.kills}K / {p.deaths}D</b>
                  </div>
                ))}
              </div>
              <div className="lbs-block">
                <div className="lbs-eye">KILLS · RAPPORTERT</div>
                {current.players.map((p,i) => (
                  <div key={i} className="lbs-row">
                    <span>{p.name}</span>
                    <b>{p.kills}K / {p.deaths || 0}D</b>
                  </div>
                ))}
                <div className="lbs-row total"><span>TOTAL</span><b>{current.players.reduce((a,p)=>a+p.kills,0)}</b></div>
              </div>
              <div className="lbs-foot">
                Sammenlign rapportert data med leaderboard-screenshot.
                Plassering for laget skal være markert. Kills per spiller skal stemme overens.
              </div>
            </div>
          </div>
        </div>
      )}

      {publishedToast && (
        <div className="toast" style={{borderColor: tweaks.accent}}>
          <span className="toast-pulse" style={{background: tweaks.accent}} />
          <div>
            <div className="toast-title">PUBLISERT · {publishedToast.time}</div>
            <div className="toast-body">
              <b>{publishedToast.team}</b> +{publishedToast.points} lp · sendt til 150 spillere
            </div>
          </div>
          <button className="toast-x" onClick={() => setPublishedToast(null)}>✕</button>
        </div>
      )}
    </div>
  );
};

// =========================================================
// LAG-SØKNADER
// =========================================================
const RegistrationsView = ({ tweaks }) => {
  const [regs, setRegs] = useState([]);
  const [tournaments, setTournaments] = useState([]);
  const [loading, setLoading] = useState(true);
  const [selectedTournament, setSelectedTournament] = useState({});
  const [toast, setToast] = useState(null);

  const refresh = () => {
    setLoading(true);
    Promise.all([
      WZN_Store.getPendingRegistrations(),
      WZN_Store.getTournaments(),
    ]).then(([r, t]) => {
      setRegs(r || []);
      setTournaments((t || []).filter(x => x.status === "open" || x.status === "draft" || x.status === "locked"));
      setLoading(false);
    });
  };
  useEffect(() => { refresh(); }, []);

  const approve = async (reg) => {
    const tid = selectedTournament[reg.id];
    if (!tid) { alert("Velg en turnering for dette laget først"); return; }
    const { error } = await WZN_Store.approveTeamRegistration(reg.id, tid);
    if (!error) {
      // Tildel Discord-rolle
      if (reg.discord_id || reg.captain_discord_id) {
        window.db.auth.getSession().then(({ data: { session } }) => {
          fetch("/api/assign-role", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              ...(session?.access_token ? { "Authorization": `Bearer ${session.access_token}` } : {}),
            },
            body: JSON.stringify({
              discordId: reg.discord_id || reg.captain_discord_id,
              role: "LIGA-DELTAKER",
            }),
          }).catch(e => console.warn("Discord-rolle feil:", e));
        });
      }
      setToast({ msg: `${reg.name} godkjent og lagt til turnering!`, type: "ok" });
      setTimeout(() => setToast(null), 3500);
      refresh();
    } else {
      alert("Feil: " + error.message);
    }
  };

  const reject = async (reg) => {
    if (!confirm(`Avvis søknad fra ${reg.name}?`)) return;
    await WZN_Store.rejectTeamRegistration(reg.id);
    setToast({ msg: `${reg.name} avvist`, type: "warn" });
    setTimeout(() => setToast(null), 3000);
    refresh();
  };

  return (
    <div className="admin-regs" style={{padding: "1.5rem 2rem"}}>
      {loading && <div style={{color:"var(--text-faint)", padding:"2rem"}}>Laster lag-søknader…</div>}
      {!loading && regs.length === 0 && (
        <div style={{color:"var(--text-faint)", padding:"3rem", textAlign:"center", border:"1px solid var(--line)"}}>
          <div style={{fontSize:"2rem", marginBottom:".5rem"}}>📋</div>
          <div>Ingen ventende lag-søknader</div>
        </div>
      )}
      {regs.map(reg => (
        <div key={reg.id} className="reg-card" style={{
          border:"1px solid var(--line)", marginBottom:"1rem", padding:"1.25rem 1.5rem",
          display:"grid", gridTemplateColumns:"1fr auto", gap:"1rem", alignItems:"start"
        }}>
          <div>
            <div style={{display:"flex", alignItems:"center", gap:".75rem", marginBottom:".5rem"}}>
              <span style={{fontSize:"1.25rem", fontFamily:"var(--font-stencil)", color:tweaks.accent}}>{reg.tag}</span>
              <span style={{fontFamily:"var(--font-stencil)", fontSize:"1rem"}}>{reg.name?.toUpperCase()}</span>
              <span style={{color:"var(--text-faint)", fontSize:".75rem", fontFamily:"var(--font-mono)"}}>
                {reg.registered_at?.slice(0,10)} · DIV {reg.division || "?"}
              </span>
            </div>
            <div style={{color:"var(--text-dim)", fontSize:".8rem", marginBottom:".75rem"}}>
              <span style={{marginRight:"1rem"}}>KAPTEIN: {reg.captain || "—"}</span>
              <span>ROSTER: {Array.isArray(reg.roster) ? reg.roster.map(p => p.activisionId || p.displayName || p).join(" · ") : "—"}</span>
            </div>
            <div style={{display:"flex", alignItems:"center", gap:".75rem"}}>
              <span style={{color:"var(--text-faint)", fontSize:".75rem", fontFamily:"var(--font-mono)"}}>TURNERING:</span>
              <select
                value={selectedTournament[reg.id] || ""}
                onChange={e => setSelectedTournament(prev => ({...prev, [reg.id]: e.target.value}))}
                style={{background:"var(--bg-1)", border:"1px solid var(--line)", color:"var(--text)", padding:".3rem .6rem", fontFamily:"var(--font-mono)", fontSize:".8rem"}}
              >
                <option value="">— Velg turnering —</option>
                {tournaments.map(t => <option key={t.id} value={t.id}>{t.name} ({t.status})</option>)}
              </select>
            </div>
          </div>
          <div style={{display:"flex", gap:".5rem", flexShrink:0}}>
            <button
              onClick={() => approve(reg)}
              style={{background:tweaks.accent, border:"none", color:"#000", padding:".5rem 1rem", fontFamily:"var(--font-mono)", fontSize:".8rem", cursor:"pointer", fontWeight:700}}
            >✓ GODKJENN</button>
            <button
              onClick={() => reject(reg)}
              style={{background:"transparent", border:"1px solid var(--bad)", color:"var(--bad)", padding:".5rem 1rem", fontFamily:"var(--font-mono)", fontSize:".8rem", cursor:"pointer"}}
            >✕ AVVIS</button>
          </div>
        </div>
      ))}
      {toast && (
        <div className="toast" style={{borderColor: toast.type === "ok" ? tweaks.accent : "var(--warn)"}}>
          <span className="toast-pulse" style={{background: toast.type === "ok" ? tweaks.accent : "var(--warn)"}}/>
          <div><div className="toast-body">{toast.msg}</div></div>
          <button className="toast-x" onClick={() => setToast(null)}>✕</button>
        </div>
      )}
    </div>
  );
};

// ── DisputesView ─────────────────────────────────────────────────────────────
const DisputesView = ({ tweaks }) => {
  const accent = tweaks.accent;
  const [disputes, setDisputes] = React.useState([]);
  const [loading, setLoading]   = React.useState(true);
  const [filter, setFilter]     = React.useState("open");

  const load = async () => {
    setLoading(true);
    const data = await WZN_Store.getDisputes(filter === "alle" ? null : filter);
    setDisputes(data || []);
    setLoading(false);
  };

  React.useEffect(() => { load(); }, [filter]);

  const resolve = async (id, status, note = "") => {
    await WZN_Store.resolveDispute(id, status, note);
    load();
  };

  const STATUS_COLORS = {
    open:     "#f59e0b",
    resolved: "#22d3ee",
    rejected: "#ef4444",
  };

  return (
    <div style={{ padding: "32px 48px" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 16, marginBottom: 24 }}>
        {["open", "resolved", "rejected", "alle"].map(s => (
          <button
            key={s}
            onClick={() => setFilter(s)}
            style={{
              padding: "6px 16px",
              background: "transparent",
              border: `1px solid ${filter === s ? accent : "var(--line)"}`,
              color: filter === s ? accent : "var(--text-dim)",
              fontFamily: "var(--font-stencil)", fontSize: 12, cursor: "pointer",
              letterSpacing: "0.12em",
            }}
          >{s.toUpperCase()}</button>
        ))}
      </div>

      {loading && <div style={{ color: "var(--text-dim)" }}>LASTER PROTESTER…</div>}

      {!loading && disputes.length === 0 && (
        <div style={{
          padding: "48px 0", textAlign: "center", color: "var(--text-dim)",
        }}>
          <div style={{ fontSize: 36, marginBottom: 12 }}>⚖️</div>
          <div style={{ fontFamily: "var(--font-stencil)", fontSize: 18 }}>
            {filter === "open" ? "INGEN ÅPNE PROTESTER" : "INGEN PROTESTER"}
          </div>
        </div>
      )}

      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        {disputes.map(d => (
          <div key={d.id} style={{
            background: "var(--bg-2)", border: "1px solid var(--line)",
            padding: "20px 24px",
            borderLeft: `3px solid ${STATUS_COLORS[d.status] || "var(--line)"}`,
          }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12 }}>
              <div>
                <div style={{
                  fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-faint)", marginBottom: 4,
                }}>
                  {new Date(d.created_at).toLocaleString("no-NO")} · Submission {d.submission_id?.slice(0, 10) || "—"}
                </div>
                <div style={{
                  fontFamily: "var(--font-stencil)", fontSize: 16, marginBottom: 4,
                }}>
                  Team: {d.team_id?.slice(0, 16) || "Ukjent"} · Kaptein: {d.captain_discord_id || "—"}
                </div>
              </div>
              <div style={{
                padding: "3px 10px",
                border: `1px solid ${STATUS_COLORS[d.status] || "var(--line)"}`,
                color: STATUS_COLORS[d.status] || "var(--text-dim)",
                fontFamily: "var(--font-mono)", fontSize: 11,
              }}>{d.status?.toUpperCase()}</div>
            </div>

            <div style={{ fontSize: 14, color: "var(--text)", marginBottom: 8, lineHeight: 1.5 }}>
              <strong>Årsak:</strong> {d.reason}
            </div>

            {d.evidence_url && (
              <div style={{ fontSize: 13, color: "var(--text-dim)", marginBottom: 12 }}>
                <strong>Bevis:</strong>{" "}
                <a href={d.evidence_url} target="_blank" rel="noopener noreferrer"
                  style={{ color: accent }}>{d.evidence_url.slice(0, 60)}…</a>
              </div>
            )}

            {d.resolution_note && (
              <div style={{ fontSize: 13, color: "var(--text-dim)", marginBottom: 12 }}>
                <strong>Løsning:</strong> {d.resolution_note}
              </div>
            )}

            {d.status === "open" && (
              <div style={{ display: "flex", gap: 10, marginTop: 12 }}>
                <button
                  onClick={() => resolve(d.id, "resolved", "Admin har vurdert og godkjent protesten.")}
                  style={{
                    padding: "8px 18px",
                    background: "#22d3ee20", border: "1px solid #22d3ee",
                    color: "#22d3ee", fontFamily: "var(--font-stencil)",
                    fontSize: 12, cursor: "pointer",
                  }}
                >✓ GODKJENN PROTEST</button>
                <button
                  onClick={() => resolve(d.id, "rejected", "Admin har vurdert og avvist protesten.")}
                  style={{
                    padding: "8px 18px",
                    background: "#ef444420", border: "1px solid #ef4444",
                    color: "#ef4444", fontFamily: "var(--font-stencil)",
                    fontSize: 12, cursor: "pointer",
                  }}
                >✗ AVVIS PROTEST</button>
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
};

Object.assign(window, { AdminDashboard });
