/* iBD Coliseum — Gallery screen */
const { useState, useMemo } = React;

function EmptyState({ icon, title, message, cta, onCta, compact }) {
  return (
    <div className={"empty" + (compact ? " compact" : "")}>
      <div className="empty-ic"><Icon name={icon || "sparkle"} className="ic" /></div>
      <div className="empty-title">{title}</div>
      {message && <p className="empty-msg">{message}</p>}
      {cta &&
      <button className="btn btn-primary" onClick={onCta}><Icon name="plus" className="ic" />{cta}</button>}
    </div>);

}

function UseCaseCard({ card, voted, onVote, voteQuota, layout, tone, justVoted, cards, openProfile, openDetail, onEdit, onDelete, userId, displayName, isExecOrAdmin, onAddComment, canHof, inHof, onHallOfFame, onArchive }) {
  const { TOOLS, CATEGORIES, REPRO, COMMENTS, avatarColor, initials, authorStats, isOwnEntry, classifyEntryShareFromCard, entryInCurrentSeason } = window.COLISEUM_DATA;
  const cat = CATEGORIES.find((c) => c.id === card.cat);
  const catColor = cat ? cat.color : "var(--accent)";
  const trending = card.votes >= 30;
  const isAuthor = (userId && card.authorId === userId) || (!card.authorId && displayName && card.author === displayName);
  const [open, setOpen] = useState(false);
  const [showComments, setShowComments] = useState(false);
  const seedComments = (COMMENTS[card.id] || []).map((c) => ({ ...c }));
  const [comments, setComments] = useState(() => (card.comments && card.comments.length ? card.comments : seedComments));
  const repro = (card.reproSteps && card.reproSteps.length) ? card.reproSteps : (REPRO[card.id] || REPRO.default);
  const share = classifyEntryShareFromCard(card);

  React.useEffect(() => {
    if (card.comments) setComments(card.comments);
  }, [card.id, card.comments]);

  const addComment = async (text) => {
    if (onAddComment) {
      const added = await onAddComment(card.id, text);
      if (added) setComments((cs) => [...cs, added]);
      return;
    }
    setComments((cs) => [...cs, { author: displayName || "You", team: "iBD · Pilot", when: "now", text, mine: true }]);
  };

  const head =
  <div className="ctop">
      <span className="cat"><span className="sq"></span>{cat ? cat.label : card.cat}</span>
      <span className="rgt">
        {isAuthor &&
        <span className="card-manage">
          <button className="cm-btn" onClick={() => onEdit && onEdit(card)}><Icon name="pencil" className="ic" />Edit</button>
          <button className="cm-btn danger" onClick={() => onDelete && onDelete(card.id)}><Icon name="trash" className="ic" />Delete</button>
        </span>}
        {trending && <span className="trend"><Icon name="fire" className="ic" />Trending</span>}
        <span className="when">{card.when} ago</span>
      </span>
    </div>;

  const toolRow =
  <div className="tools">
      {card.tools.map((t) =>
    <span className="tool" key={t}><span className="blob" style={{ background: TOOLS[t] || "#999" }}></span>{t}</span>
    )}
    </div>;

  const links =
  <div className="clinks">
      {card.hasRepro &&
    <button className="clink" onClick={() => setOpen((o) => !o)} style={{ background: "none", border: "none", padding: 0, cursor: "pointer" }}>
          <Icon name="steps" className="ic" />{open ? "Hide steps" : "Reproduction steps"}
        </button>
    }
      {share.type === "link" &&
    <a className="clink" href={share.href} target="_blank" rel="noopener noreferrer" onClick={(e) => e.stopPropagation()} title={share.value}>
          <Icon name="link" className="ic" />Output link
        </a>
    }
      {share.type === "download" &&
    <a className="clink" href={share.href} download={share.downloadName} onClick={(e) => e.stopPropagation()} title={share.value}>
          <Icon name="download" className="ic" />{share.downloadLabel}
        </a>
    }
      <button className="clink dm-link" onClick={() => openDetail && openDetail(card)} style={{ background: "none", border: "none", padding: 0, cursor: "pointer" }}>
        <Icon name="sparkle" className="ic" />Skill &amp; output
      </button>
      <button className={"clink comment-toggle" + (showComments ? " on" : "")} onClick={() => setShowComments((s) => !s)} style={{ background: "none", border: "none", padding: 0, cursor: "pointer", marginLeft: "auto" }}>
        <Icon name="chat" className="ic" />{comments.length ? `${comments.length} ${comments.length === 1 ? "comment" : "comments"}` : "Comment"}
      </button>
    </div>;

  const commentSection = showComments && <CommentThread comments={comments} onAdd={addComment} catColor={catColor} />;

  const isOwn = isOwnEntry(card, userId, displayName);
  const isCurrentSeason = entryInCurrentSeason(card);
  const atVoteLimit = !voted && isCurrentSeason && voteQuota && voteQuota.remaining <= 0;
  const voteBtn = isOwn
    ? <span className="vote own" title="You can't upvote your own card"><Icon name="up" className="ic" />{card.votes}</span>
    : <button className={"vote" + (voted ? " " : "") + (justVoted ? " pop" : "") + (atVoteLimit ? " disabled" : "")} aria-pressed={voted} disabled={atVoteLimit} onClick={() => onVote(card.id)} title={voted ? "Remove upvote" : atVoteLimit ? "No votes left this quarter" : "Upvote"}>
        <Icon name="up" className="ic" />{card.votes}
      </button>;

  const authorEl =
  <button className="author author-btn" onClick={() => openProfile && openProfile(card.author)} title={`View ${card.author}'s profile`}>
      <span className="av" style={{ background: avatarColor(card.author) }}>{initials(card.author)}</span>
      <div className="author-meta">
        <div className="nm">{card.author}<TierBadge points={authorStats(cards, card.author).points} size="sm" /></div>
        <div className="tm">{card.team}</div>
      </div>
    </button>;

  const hofRow = canHof &&
  <div className="manage-row">
      <button className={"manage-btn hof" + (inHof ? " on" : "")} onClick={() => onHallOfFame && onHallOfFame(card, !inHof)}>
        <Icon name="trophy" className="ic" />{inHof ? "Remove from Hall of Fame" : "Hall of Fame"}
      </button>
      <button className="manage-btn archive" onClick={() => onArchive && onArchive(card)} title="Hide this card everywhere; the submitter keeps their points">
        <Icon name="archive" className="ic" />Archive
      </button>
    </div>;


  if (layout === "list") {
    return (
      <div className="card" style={{ "--cat": catColor }}>
        <div className="lmain">
          {head}
          <h3 className="card-title" onClick={() => openDetail && openDetail(card)} title="See prompt & output">{card.title}</h3>
          <p className="desc">{card.desc}</p>
          {toolRow}
          {open && <ReproBox steps={repro} />}
          {links}
          {commentSection}
          {hofRow}
        </div>
        <div className="lside">
          {voteBtn}
          {authorEl}
        </div>
      </div>);

  }

  return (
    <div className="card" style={{ "--cat": catColor }}>
      {head}
      <h3 className="card-title" onClick={() => openDetail && openDetail(card)} title="See prompt & output">{card.title}</h3>
      <p className="desc">{card.desc}</p>
      {toolRow}
      {open && <ReproBox steps={repro} />}
      {links}
      {commentSection}
      <div className="cfoot">
        {authorEl}
        {voteBtn}
      </div>
      {hofRow}
    </div>);

}

function CommentThread({ comments, onAdd, catColor }) {
  const { avatarColor, initials } = window.COLISEUM_DATA;
  const [draft, setDraft] = useState("");
  const submit = () => {
    const t = draft.trim();
    if (!t) return;
    onAdd(t);
    setDraft("");
  };
  return (
    <div className="cthread" style={{ "--cat": catColor }}>
      <div className="cthread-list">
        {comments.length === 0 &&
        <div className="cthread-empty">No replies yet — be the first to ask or share a tip.</div>}
        {comments.map((c, i) =>
        <div className={"cmt" + (c.mine ? " mine" : "")} key={i}>
            <span className="cmt-av" style={{ background: avatarColor(c.author) }}>{initials(c.author)}</span>
            <div className="cmt-body">
              <div className="cmt-meta"><b>{c.author}</b><span className="cmt-team">{c.team}</span><span className="cmt-when">{c.when === "now" ? "just now" : c.when + " ago"}</span></div>
              <div className="cmt-text">{c.text}</div>
            </div>
          </div>
        )}
      </div>
      <div className="cthread-form">
        <input type="text" value={draft} placeholder="Add a reply…"
        onChange={(e) => setDraft(e.target.value)}
        onKeyDown={(e) => {if (e.key === "Enter") submit();}} />
        <button className="cthread-send" onClick={submit} disabled={!draft.trim()} aria-label="Send reply">
          <Icon name="send" className="ic" />
        </button>
      </div>
    </div>);

}

function ReproBox({ steps }) {
  return (
    <ol style={{ margin: 0, padding: "12px 14px 12px 30px", background: "rgba(120,90,50,0.07)", borderRadius: "var(--radius-md)", fontSize: "var(--fs-small)", color: "var(--fg-2)", lineHeight: "var(--lh-body)", display: "flex", flexDirection: "column", gap: 6 }}>
      {steps.map((s, i) => <li key={i}>{s}</li>)}
    </ol>);

}

function Leaderboard({ cards, openProfile }) {
  const { initials, avatarColor, authorStats } = window.COLISEUM_DATA;
  const top = [...cards].sort((a, b) => b.votes - a.votes).slice(0, 5);
  return (
    <div className="panel">
      <div className="ph">
        <h3><Icon name="fire" className="ic" />Popular this week</h3>
        <span className="tag">Not a ranking</span>
      </div>
      {top.length === 0 ?
      <EmptyState compact icon="fire" title="Nothing popular yet" message="Once cards are posted and upvoted, the most useful ones surface here." /> :
      top.map((c, i) =>
      <div className={"lb-item" + (i === 0 ? " top" : "")} key={c.id}>
          <span className="lb-rank">{i + 1}</span>
          <div className="lb-main">
            <div className="t">{c.title}</div>
            <div className="a">
              <button className="lb-author" onClick={() => openProfile && openProfile(c.author)}>{c.author}</button>
              <TierBadge points={authorStats(cards, c.author).points} size="sm" />
              <span className="lb-team">· {c.team}</span>
            </div>
          </div>
          <span className="lb-votes"><Icon name="up" className="ic" />{c.votes}</span>
        </div>
      )}
    </div>);

}

function RankBoard({ cards, openProfile }) {
  const { authorStats, tierFor, avatarColor, initials, currentSeason, entrySeasonKey } = window.COLISEUM_DATA;
  const eng = window.COLISEUM_DATA.ENGAGEMENT || {};
  const curKey = currentSeason().key;
  const seasonCards = cards.filter((c) => entrySeasonKey(c) === curKey);
  const authors = [...new Set([...seasonCards.map((c) => c.author), ...Object.keys(eng)])];
  const ranked = authors
    .map((a) => authorStats(seasonCards.length ? seasonCards : cards, a))
    .filter((s) => s.points > 0)
    .sort((x, y) => y.points - x.points);
  return (
    <div className="panel plaque">
      <div className="ph">
        <h3><Icon name="trophy" className="ic" />Leaderboard</h3>
        <span className="tag">By points</span>
      </div>
      <div className="plaque-ribbon"><span>Champions of the Arena</span></div>
      {ranked.length === 0 ?
      <EmptyState compact icon="trophy" title="No champions yet" message="Points are earned from submissions and upvotes. Post the first card to claim the top of the plaque." /> :
      <div className="rankboard scroll">
        {ranked.map((s, i) => {
          const { tier } = tierFor(s.points);
          return (
            <button className={"rb-item" + (i < 3 ? " top" : "")} key={s.author} onClick={() => openProfile && openProfile(s.author)} style={{ "--tier": tier.color }}>
              <span className={"rb-rank r" + (i + 1)}>{i < 3 ? <><Icon name="trophy" className="ic" /><span className="rb-num">{i + 1}</span></> : i + 1}</span>
              <span className="rb-av" style={{ background: avatarColor(s.author) }}>{initials(s.author)}</span>
              <span className="rb-main">
                <span className="rb-name">{s.author}</span>
                <span className="rb-tier"><TierEmblem tier={tier.id} className="ic" />{tier.name}</span>
              </span>
              <span className="rb-pts">{s.points.toLocaleString()}<span className="u">pts</span></span>
            </button>);

        })}
      </div>
      }
    </div>);

}

function Gallery({ cards, voted, onVote, justVotedId, voteQuota, openSubmit, openProfile, openDetail, onEdit, onDelete, tweak, userId, displayName, isExecOrAdmin, onAddComment, canHof, hofIds, onHallOfFame, onArchive }) {
  const { CATEGORIES, currentSeason, entrySeasonKey, visibleGallerySeasons, buildSeasonMeta, seasonProgress } = window.COLISEUM_DATA;
  const S = buildSeasonMeta();
  const prog = seasonProgress(S);
  const [filter, setFilter] = useState("all");
  const [sort, setSort] = useState("new");
  const seasons = useMemo(() => visibleGallerySeasons(cards), [cards]);
  const [activeSeason, setActiveSeason] = useState("all");
  const tone = tweak.tone;
  const curKey = currentSeason().key;

  const galleryPool = useMemo(
    () => (hofIds ? cards.filter((c) => !hofIds.has(c.id)) : cards),
    [cards, hofIds]
  );

  const listCards = useMemo(
    () => galleryPool.filter((c) => activeSeason === "all" || entrySeasonKey(c) === activeSeason),
    [galleryPool, activeSeason]
  );

  const seasonCards = useMemo(
    () => galleryPool.filter((c) => window.COLISEUM_DATA.entryInCurrentSeason(c)),
    [galleryPool]
  );

  const counts = useMemo(() => {
    const m = { all: listCards.length };
    CATEGORIES.forEach((c) => {m[c.id] = listCards.filter((x) => x.cat === c.id).length;});
    return m;
  }, [listCards]);

  const visible = useMemo(() => {
    let list = filter === "all" ? listCards : listCards.filter((c) => c.cat === filter);
    list = [...list];
    if (sort === "new") list.sort((a, b) => whenScore(a.when, a.createdAt) - whenScore(b.when, b.createdAt));else
    list.sort((a, b) => b.votes - a.votes);
    return list;
  }, [listCards, filter, sort]);

  const heroTitle = tone === "neutral" ?
  <>Internal AI use-case <em>gallery</em></> :
  <>Share <em>something you want</em> with AI</>;
  const heroSub = tone === "neutral" ?
  "Browse every card colleagues have shared across all seasons — follow the steps and upvote what's useful. Cards stay here until an executive archives or removes them." :
  "The lifetime wall: every season's wins in one place. Post in under 5 minutes, browse for ideas, upvote what helps you.";

  return (
    <>
      <section className={"ghero" + (tweak.heroBg === "arena" ? " arena" : "")}>
        <div className="wrap ghero-grid">
          <div className="ghero-left">
            <div className="eyebrow">IBD COLISEUM · AI GALLERY</div>
            <h1>{heroTitle}</h1>
            <p className="sub">{heroSub}</p>
            <div className="hero-actions">
              <button className="btn btn-primary btn-lg" onClick={openSubmit}>
                <Icon name="plus" className="ic" />{tone === "neutral" ? "New submission" : "Make A Submission"}
              </button>
            </div>
            <div className="stat-row">
              <div className="stat"><div className="v"><span className="accent">{listCards.length}</span></div><div className="l">Cards shared</div></div>
              <div className="stat"><div className="v">{listCards.reduce((s, c) => s + c.votes, 0)}</div><div className="l">Upvotes given</div></div>
              {userId && voteQuota &&
              <div className="stat"><div className="v"><span className="accent">{voteQuota.remaining}</span><span style={{ fontSize: "0.65em", opacity: 0.7 }}>/{voteQuota.limit}</span></div><div className="l">Votes left this quarter</div></div>}
              <div className="stat"><div className="v">{listCards.length ? 38 : 0}<span className="accent">%</span></div><div className="l">Have posted</div></div>
            </div>
          </div>
          <div className="ghero-right">
            <RankBoard cards={listCards} openProfile={openProfile} />
          </div>
        </div>
      </section>

      <section className="season-progress-wrap">
        <div className="wrap">
          <div className="sprog-card">
            <div className="sprog-head">
              <div>
                <div className="sprog-label">Season progress · {S.label}</div>
                <div className="sprog-sub">Three months from {S.start} to {S.end}</div>
              </div>
              <div className="sprog-pct">{prog.pct}<span>%</span></div>
            </div>
            <div className="sprog-track">
              <div className="sprog-fill" style={{ width: prog.pct + "%" }}>
                <span className="sprog-knob" title={"Today · " + prog.today}><span className="sk-label">{prog.today}</span></span>
              </div>
            </div>
            <div className="sprog-ends">
              <span><b>{S.start}</b> · Season opens</span>
              <span><b>{S.end}</b> · Season ends{prog.started ? ` · ${prog.endsIn} left` : ""}</span>
            </div>
          </div>

          <div className="sstats">
            <div className="sstat"><div className="v">{seasonCards.length}</div><div className="l">Cards shared this season</div></div>
            <div className="sstat"><div className="v">{new Set(seasonCards.map((c) => c.author).filter(Boolean)).size}</div><div className="l">Contributors</div></div>
            <div className="sstat"><div className="v">{new Set(seasonCards.map((c) => c.team).filter(Boolean)).size}</div><div className="l">Departments taking part</div></div>
          </div>
        </div>
      </section>

      <div className="controls">
        <div className="wrap">
          <div className="season-seg" role="tablist" aria-label="Gallery season">
            {seasons.map((s) =>
              <button key={s.key} className="season-tab" role="tab" aria-selected={activeSeason === s.key}
                onClick={() => setActiveSeason(s.key)}>{s.label}</button>
            )}
          </div>
          <div className="controls-row">
          <div className="chips">
            <button className="chip" aria-pressed={filter === "all"} onClick={() => setFilter("all")}>All<span className="cnt">{counts.all}</span></button>
            {CATEGORIES.map((c) =>
            <button className="chip" key={c.id} aria-pressed={filter === c.id} onClick={() => setFilter(c.id)}>
                {c.label}<span className="cnt">{counts[c.id]}</span>
              </button>
            )}
          </div>
          <div className="sortbox">
            <span className="lbl">Sort</span>
            <div className="sort-seg">
              <button aria-pressed={sort === "new"} onClick={() => setSort("new")}>Newest</button>
              <button aria-pressed={sort === "top"} onClick={() => setSort("top")}>Most upvoted</button>
            </div>
          </div>
          </div>
        </div>
      </div>

      <section className="gbody">
        <div className="wrap">
          <div>
            <div className="section-head">
              <h2>{filter === "all" ? "Everything shared" : CATEGORIES.find((c) => c.id === filter).label}</h2>
              <span className="muted">{visible.length} {visible.length === 1 ? "card" : "cards"}</span>
            </div>
            {visible.length === 0 ?
            <div className="cards-empty">
                {listCards.length === 0 ?
              <EmptyState icon="sparkle"
                title={tone === "neutral" ? "No submissions yet" : "Be the first to share"}
                message={tone === "neutral" ?
                "The gallery is empty. Add the first use-case to start the collection for your team." :
                "The gallery is empty for now. Share one thing you tried with AI and kick off the wall for your colleagues — no scoring, no pressure."}
                cta={tone === "neutral" ? "New submission" : "Make A Submission"} onCta={openSubmit} /> :

              <EmptyState compact icon="grid"
                title="Nothing in this category yet"
                message="No cards match this filter. Try another category, or be the first to post one here."
                cta={tone === "neutral" ? "New submission" : "Make A Submission"} onCta={openSubmit} />}
              </div> :

            <div className="cards" data-density={tweak.density} data-layout={tweak.layout}>
              {visible.map((c) =>
              <UseCaseCard key={c.id} card={c} voted={voted.has(c.id)} onVote={onVote} voteQuota={voteQuota}
              layout={tweak.layout} tone={tone} justVoted={justVotedId === c.id}
              cards={cards} openProfile={openProfile} openDetail={openDetail} onEdit={onEdit} onDelete={onDelete}
              userId={userId} displayName={displayName} isExecOrAdmin={isExecOrAdmin} onAddComment={onAddComment}
              canHof={canHof} inHof={hofIds && hofIds.has(c.id)} onHallOfFame={onHallOfFame} onArchive={onArchive} />
              )}
            </div>
            }
          </div>
          <aside className="aside">
            <Leaderboard cards={cards} openProfile={openProfile} />
            <div className="panel note">
              <h3><Icon name="heart" className="ic" />Everyone starts somewhere</h3>
              <p>This is a no-pressure space. There's no leaderboard prize here — "popular" just means useful to colleagues. Share the small wins; someone will learn from them.</p>
            </div>
          </aside>
        </div>
      </section>
    </>);

}

function whenScore(w, createdAt) {
  if (createdAt) return -new Date(createdAt).getTime();
  if (w === "now") return 0;
  const n = parseInt(w, 10);
  if (Number.isNaN(n)) return 9999;
  if (w.includes("h")) return n;
  if (w.includes("d")) return n * 24;
  if (w.includes("m")) return n / 60;
  return n;
}

Object.assign(window, { Gallery, UseCaseCard, Leaderboard, RankBoard, CommentThread });