/* prototype-app.jsx — unified single-page prototype (all screens + motion) */
const { useState, useEffect, useRef } = React;

const PKEY = 'sx_proto_nav';
function loadNav() { try { return JSON.parse(localStorage.getItem(PKEY)) || {}; } catch (e) { return {}; } }

/* ---- menu data (ported from menu-app.jsx) ---- */
const MENU_SECTIONS = [
  { label: 'Community', items: [
    { id: 'feed', label: 'Feed', icon: Ic.Feed, count: 3 },
    { id: 'groups', label: 'Groups', icon: Ic.People },
    { id: 'connections', label: 'Connections', icon: Ic.Connections },
    { id: 'messages', label: 'Messages', icon: Ic.Mail, count: 5 }] },
  { label: 'Recognition', items: [
    { id: 'badges', label: 'Badges', icon: Ic.Rosette, active: true }] }];
const SETTINGS_ITEM = { id: 'settings', label: 'Settings', icon: Ic.Cog };

function MenuRow({ item, onClick }) {
  return (
    <button className={'ms-row' + (item.active ? ' active' : '')} onClick={onClick} aria-current={item.active ? 'page' : undefined}>
      <span className="ms-ic"><item.icon s={22} c={item.active ? 'var(--purple)' : 'var(--ink)'} /></span>
      <span className="ms-label">{item.label}</span>
      {item.count ? <span className="ms-count">{item.count}</span> : null}
    </button>);
}

/* ============ HOME (Badges list) ============ */
function BadgesHome({ onGive, onMenu, recessed }) {
  const [cat, setCat] = useState('All');
  const [query, setQuery] = useState('');
  const [focus, setFocus] = useState(false);
  const [sort, setSort] = useState('newest');
  const [sortOpen, setSortOpen] = useState(false);
  const [scrolled, setScrolled] = useState(false);
  const [detailBadge, setDetailBadge] = useState(null);
  const [menuBadge, setMenuBadge] = useState(null);
  const [confirmBadge, setConfirmBadge] = useState(null);
  const [deletedIds, setDeletedIds] = useState(() => new Set());
  const [toast, setToast] = useState(null);

  const filtered = React.useMemo(() => {
    let r = BADGES.filter((b) =>
      !deletedIds.has(b.id) && (cat === 'All' || b.cat === cat) &&
      b.name.toLowerCase().includes(query.trim().toLowerCase()));
    if (sort === 'az') r = [...r].sort((a, b) => a.name.localeCompare(b.name));
    else if (sort === 'za') r = [...r].sort((a, b) => b.name.localeCompare(a.name));
    else if (sort === 'oldest') r = [...r].reverse();
    return r;
  }, [cat, query, sort, deletedIds]);

  const sortLabel = (SORT_OPTIONS.find((o) => o.id === sort) || SORT_OPTIONS[0]).label;
  const flashToast = (msg) => { setToast(msg); setTimeout(() => setToast((t) => t === msg ? null : t), 2200); };
  const pickSort = (opt) => { setSort(opt.id); setTimeout(() => { setSortOpen(false); flashToast(`Sorted by ${opt.label}`); }, 230); };
  const doDelete = () => { const b = confirmBadge; setDeletedIds((s) => new Set(s).add(b.id)); setConfirmBadge(null); flashToast(`“${b.name}” deleted`); };

  return (
    <div className="proto-home" data-recessed={recessed} style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      <Header scrolled={scrolled} />
      <SearchBar value={query} onChange={setQuery} focus={focus} setFocus={setFocus} />
      <FilterChips cats={CATS} active={cat} onPick={setCat} />

      <div className="sort-bar">
        <span className="sort-bar-count">{filtered.length} badge{filtered.length === 1 ? '' : 's'}</span>
        <button className="sort-bar-btn" onClick={() => setSortOpen(true)}>
          <Ic.Sort s={16} c="var(--ink-2)" /> Sort: {sortLabel}
        </button>
      </div>

      <div className="feed" onScroll={(e) => setScrolled(e.target.scrollTop > 4)}>
        {query.trim() &&
          <div className="count-line">
            {filtered.length === 0 ? `No badges match “${query.trim()}”` :
              `${filtered.length} result${filtered.length > 1 ? 's' : ''} for “${query.trim()}”`}
          </div>}
        {filtered.length === 0 && !query.trim() &&
          <div className="empty">
            <div className="empty-title">No badges here yet</div>
            <div className="empty-sub">Try a different category.</div>
          </div>}
        {filtered.map((b) =>
          <BadgeCard key={b.id} badge={b}
            onOpen={() => setDetailBadge(b)}
            onReadMore={() => setDetailBadge(b)}
            onGive={() => onGive(b)}
            onMore={() => setMenuBadge(b)} />)}
      </div>

      <BottomNav manager={MANAGER} onMenu={onMenu} />

      <DetailSheet badge={detailBadge} open={!!detailBadge}
        onClose={() => setDetailBadge(null)}
        onGive={() => { const b = detailBadge; setDetailBadge(null); setTimeout(() => onGive(b), 160); }} />

      <ActionSheet badge={menuBadge} open={!!menuBadge}
        onClose={() => setMenuBadge(null)}
        onDelete={() => { const b = menuBadge; setMenuBadge(null); setTimeout(() => setConfirmBadge(b), 120); }} />

      <DeleteBadgeModal badge={confirmBadge} open={!!confirmBadge}
        onCancel={() => setConfirmBadge(null)} onConfirm={doDelete} />

      <SortSheet open={sortOpen} value={sort} onClose={() => setSortOpen(false)} onPick={pickSort} />

      <div className={'toast' + (toast ? ' show' : '')}>{toast}</div>
    </div>);
}

/* ============ MENU SHEET ============ */
function MenuSheet({ open, onClose }) {
  const [mounted, setMounted] = useState(false);
  const [entered, setEntered] = useState(false);
  const [toast, setToast] = useState(null);
  useEffect(() => {
    let t;
    if (open) { setMounted(true); t = setTimeout(() => setEntered(true), 24); return () => clearTimeout(t); }
    else if (mounted) { setEntered(false); t = setTimeout(() => setMounted(false), 420); return () => clearTimeout(t); }
  }, [open]);
  if (!mounted) return null;
  const flash = (msg) => { setToast(msg); setTimeout(() => setToast((x) => x === msg ? null : x), 2000); };
  const pick = (item) => { if (item.id === 'badges') { onClose(); return; } flash(`${item.label} isn't part of this prototype yet`); };

  return (
    <React.Fragment>
      <div className="menu-scrim" data-in={entered} onClick={onClose}></div>
      <div className="menu-sheet" data-in={entered}>
        <div className="ms-top"><div className="ms-grabber"></div></div>
        <div className="ms-brand">
          <button className="ms-back" onClick={() => {}} aria-label="Workspaces"><Ic.ChevronLeft s={22} c="var(--ink)" /></button>
          <img className="ms-logo" src={SCHOOX_LOGO_URI} alt="Schoox" />
        </div>
        <div className="ms-scroll">
          {MENU_SECTIONS.map((sec) =>
            <div key={sec.label} className="ms-section">
              <div className="ms-section-label">{sec.label}</div>
              {sec.items.map((it) => <MenuRow key={it.id} item={it} onClick={() => pick(it)} />)}
            </div>)}
          <div className="ms-divider"></div>
          <div className="ms-section">
            <MenuRow item={SETTINGS_ITEM} onClick={() => pick(SETTINGS_ITEM)} />
          </div>
        </div>
        <div className="ms-footer">
          <button className="ms-logout" onClick={() => flash('Logging out…')}>
            <Ic.Logout s={21} c="var(--ios-red-strong)" /> Log out
          </button>
          <div className="ms-version">Schoox · Version 4.20.1</div>
        </div>
      </div>
      <div className={'toast' + (toast ? ' show' : '')}>{toast}</div>
    </React.Fragment>);
}

/* ============ FILTERS HUB (push) ============ */
const FCATS = () => [FILTER_DATA.type, FILTER_DATA.aboveUnit, FILTER_DATA.unit, FILTER_DATA.job];
function FiltersHubView({ filters, onClose, onClearOne, onReset, onRow }) {
  const cats = FCATS();
  const active = Object.values(filters).some(Boolean);
  const count = Object.values(filters).filter(Boolean).length;
  return (
    <div className="fh">
      <div className="flt-header">
        <button className="flt-nav" onClick={onClose} aria-label="Close filters"><Ic.Close s={21} c="var(--ink)" /></button>
        <div className="flt-title">Filters</div>
      </div>
      <div className="fh-body">
        <div className="fh-toprow">
          <span className="fh-section-label">Active filters{active ? ` · ${count}` : ''}</span>
          <button className="fh-reset" disabled={!active} onClick={onReset}>
            <Ic.Refresh s={15} c={active ? 'var(--purple-strong)' : 'var(--ink-3)'} /> Reset filters
          </button>
        </div>
        <div className="fh-chipzone">
          {active ?
            cats.filter((c) => filters[c.key]).map((c) =>
              <span key={c.key} className="fh-chip">
                <span><b>{c.name}:</b> {filters[c.key]}</span>
                <button className="fh-chip-x" onClick={() => onClearOne(c.key)} aria-label={'Clear ' + c.name}><Ic.Close s={11} c="var(--purple-strong)" /></button>
              </span>) :
            <div className="fh-chip-empty">Filters you apply will appear here</div>}
        </div>
        <div className="fh-rows">
          {cats.map((c) => {
            const v = filters[c.key];
            return (
              <button key={c.key} className="fh-row" onClick={() => onRow(c.key)}>
                <span className="fh-row-label">{c.name}</span>
                <span className={'fh-row-value' + (v ? ' set' : '')}>{v || 'Any'}</span>
                <span className="fh-row-chev"><Ic.ChevronRight s={18} c="var(--ink-3)" /></span>
              </button>);
          })}
        </div>
      </div>
      <div className="flt-footer">
        <div className="fh-hint">{active ? `${count} filter${count > 1 ? 's' : ''} applied` : 'No filters — all members will be shown'}</div>
        <button className="flt-cta" onClick={onClose}>Select members</button>
      </div>
    </div>);
}

/* ============ FILTER SUB-SCREEN (push) ============ */
function FilterSubView({ catKey, value, onBack, onApply }) {
  const cat = FILTER_DATA[catKey];
  const [sel, setSel] = useState(value || null);
  const [q, setQ] = useState('');
  if (!cat) return null;
  const list = cat.options.filter((o) => !cat.search || o.toLowerCase().includes(q.trim().toLowerCase()));
  return (
    <div className="fs">
      <div className="flt-header">
        <button className="flt-nav" onClick={onBack} aria-label="Back to Filters">
          <Ic.ChevronLeft s={20} c="var(--ink)" /><span className="flt-nav-lbl">Filters</span>
        </button>
        <div className="flt-title">Filters</div>
      </div>
      <div className="fs-body">
        <h2 className="fs-cat">{cat.name}</h2>
        {cat.search &&
          <div className="fs-search">
            <div className="search" style={{ height: 46 }}>
              <Ic.Search s={19} />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder={'Search ' + cat.name.toLowerCase()} aria-label="Search" />
              {q && <button className="filter-btn" onClick={() => setQ('')} aria-label="Clear"><Ic.Close s={16} /></button>}
            </div>
          </div>}
        {list.length === 0 ?
          <div className="fs-empty">No options match “{q.trim()}”.</div> :
          list.map((o) => {
            const on = sel === o;
            return (
              <button key={o} className={'fs-opt' + (on ? ' sel' : '')} onClick={() => setSel(on ? null : o)} role="radio" aria-checked={on}>
                <span className="fs-radio">{on && <span className="fs-dot"></span>}</span>
                <span className="fs-opt-label">{o}</span>
              </button>);
          })}
      </div>
      <div className="flt-footer">
        <div className="fs-hint">{sel ? `Apply “${sel}”` : 'No selection — applying clears this filter'}</div>
        <button className="flt-cta" onClick={() => onApply(cat.key, sel)}>Apply</button>
      </div>
    </div>);
}

/* ============ REVIEW (push) ============ */
function ReviewView({ badge, memberIds, groupIds, onBack, onAddMore, onRemoveMember, onRemoveGroup, onConfirm }) {
  const [note, setNote] = useState('');
  const recipients = MEMBERS.filter((m) => memberIds.includes(m.id));
  const groups = GROUPS.filter((g) => groupIds.includes(g.id));
  const headcount = recipients.length + groups.reduce((n, g) => n + g.count, 0);
  return (
    <div className="rv">
      <div className="rv-header">
        <button className="m-close" onClick={onBack} aria-label="Back"><Ic.ChevronLeft s={22} c="var(--ink)" /></button>
        <div className="rv-title">Review</div>
        <div className="step-pill"><span className="step-bar"><i className="on"></i><i className="on"></i></span>Step 2 of 2</div>
      </div>
      <div className="rv-scroll">
        <div className="rv-badge-block">
          <p className="rv-eyebrow">Badge</p>
          <div className="rv-stage">
            <div className="rv-glow"></div>
            <div className="rv-ped"></div>
            {badge.img ?
              <img className="rv-badge-img" src={badge.img} alt={badge.name} /> :
              <div style={{ width: 150, height: 150 }}><HexPlaceholder size={150} /></div>}
          </div>
          <h1 className="rv-badge-name">{badge.name}</h1>
          <div className="rv-cat"><CatTag cat={badge.cat} /></div>
          <p className="rv-desc">{badge.desc}</p>
        </div>
        <div className="rv-section-head">
          <span className="rv-section-title">Team members</span>
          <span className="rv-headcount">{headcount} recipient{headcount === 1 ? '' : 's'}</span>
        </div>
        <div className="rv-sel-label">Selected ({headcount})</div>
        <div className="rv-chips">
          {groups.map((g) =>
            <div key={g.id} className="rv-chip">
              <div className="grp-ic">{g.name.split(/\s+/).slice(0, 2).map((w) => w[0]).join('').toUpperCase()}</div>
              <div className="rv-chip-text">
                <div className="rv-chip-name">{g.name}</div>
                <div className="rv-chip-sub">{g.count} members</div>
              </div>
              <button className="rv-remove" onClick={() => onRemoveGroup(g.id)} aria-label={'Remove ' + g.name}><Ic.Close s={16} c="var(--ink-2)" /></button>
            </div>)}
          {recipients.map((m) =>
            <div key={m.id} className="rv-chip">
              <Avatar name={m.name} size={38} />
              <div className="rv-chip-text">
                <div className="rv-chip-name">{m.name}</div>
                <div className="rv-chip-sub">{m.role}</div>
              </div>
              <button className="rv-remove" onClick={() => onRemoveMember(m.id)} aria-label={'Remove ' + m.name}><Ic.Close s={16} c="var(--ink-2)" /></button>
            </div>)}
          {headcount === 0 && <div className="rv-empty">No recipients selected. Add someone to award this badge.</div>}
        </div>
        <button className="rv-add" onClick={onAddMore}><span className="rv-add-plus">+</span> Add member</button>
        <div className="rv-note-block">
          <label className="rv-note-label" htmlFor="rv-note">Add a note <span>(optional)</span></label>
          <textarea id="rv-note" className="rv-note" rows={3} value={note} onChange={(e) => setNote(e.target.value)} placeholder="Tell them why they earned it…"></textarea>
        </div>
      </div>
      <div className="rv-footer">
        <button className="btn-confirm" disabled={headcount === 0} onClick={onConfirm}>
          <Ic.Rosette s={20} c="#fff" /> Confirm &amp; Award
        </button>
      </div>
    </div>);
}

/* generic push wrapper with enter/exit */
function PushLayer({ open, z, children }) {
  const [mounted, setMounted] = useState(false);
  const [entered, setEntered] = useState(false);
  useEffect(() => {
    let t;
    if (open) { setMounted(true); t = setTimeout(() => setEntered(true), 24); return () => clearTimeout(t); }
    else if (mounted) { setEntered(false); t = setTimeout(() => setMounted(false), 400); return () => clearTimeout(t); }
  }, [open]);
  if (!mounted) return null;
  return <div className="proto-push" data-in={entered} style={{ zIndex: z }}>{children}</div>;
}

/* ============ ORCHESTRATOR ============ */
function PrototypeApp() {
  const saved = loadNav();
  const [awardBadgeId, setAwardBadgeId] = useState(saved.badgeId || null);
  const awardBadge = BADGES.find((b) => b.id === awardBadgeId) || BADGES[0];
  const [membersOpen, setMembersOpen] = useState(!!saved.membersOpen);
  const [filtersOpen, setFiltersOpen] = useState(!!saved.filtersOpen);
  const [filterSubKey, setFilterSubKey] = useState(saved.filterSubKey || null);
  const [filterSubOpen, setFilterSubOpen] = useState(!!saved.filterSubOpen);
  const [reviewOpen, setReviewOpen] = useState(!!saved.reviewOpen);
  const [menuOpen, setMenuOpen] = useState(!!saved.menuOpen);
  const [celebrate, setCelebrate] = useState(null);
  const [selMemberIds, setSelMemberIds] = useState(saved.selMemberIds || []);
  const [selGroupIds, setSelGroupIds] = useState(saved.selGroupIds || []);
  const [filters, setFilters] = useState(saved.filters || {});

  const filterCount = Object.values(filters).filter(Boolean).length;

  useEffect(() => {
    const nav = { badgeId: awardBadgeId, membersOpen, filtersOpen, filterSubKey, filterSubOpen, reviewOpen, menuOpen, selMemberIds, selGroupIds, filters };
    try { localStorage.setItem(PKEY, JSON.stringify(nav)); } catch (e) {}
  }, [awardBadgeId, membersOpen, filtersOpen, filterSubKey, filterSubOpen, reviewOpen, menuOpen, selMemberIds, selGroupIds, filters]);

  /* nav handlers */
  const giveBadge = (b) => { setAwardBadgeId(b.id); setSelMemberIds([]); setSelGroupIds([]); setMembersOpen(true); };
  const onReview = ({ memberIds, groupIds }) => { setSelMemberIds(memberIds); setSelGroupIds(groupIds); setReviewOpen(true); };
  const confirmAward = () => {
    const recips = MEMBERS.filter((m) => selMemberIds.includes(m.id));
    const grps = GROUPS.filter((g) => selGroupIds.includes(g.id));
    const count = recips.length + grps.reduce((n, g) => n + g.count, 0);
    if (count === 0) return;
    setCelebrate({ badge: awardBadge, count, names: recips.map((m) => m.name), eyebrow: 'Recognition sent', title: 'Badge awarded!' });
  };
  const celebrationDone = () => { setCelebrate(null); setReviewOpen(false); setMembersOpen(false); setFiltersOpen(false); setFilterSubOpen(false); };
  const celebrationAnother = () => { setCelebrate(null); setReviewOpen(false); };
  const openFilterSub = (key) => { setFilterSubKey(key); setFilterSubOpen(true); };
  const closeFilterSub = () => { setFilterSubOpen(false); setTimeout(() => setFilterSubKey(null), 420); };
  const applyFilterSub = (key, val) => { setFilters((f) => { const n = { ...f }; if (val) n[key] = val; else delete n[key]; return n; }); closeFilterSub(); };

  const recessed = membersOpen || menuOpen;

  return (
    <IOSDevice width={402} height={874}>
      <div className="app">
        <BadgesHome onGive={giveBadge} onMenu={() => setMenuOpen(true)} recessed={recessed} />

        <SelectMembersModal
          badge={awardBadge} open={membersOpen} step
          onClose={() => setMembersOpen(false)}
          members={MEMBERS} groups={GROUPS}
          initialMemberIds={selMemberIds} initialGroupIds={selGroupIds}
          onReview={onReview}
          onOpenFilters={() => setFiltersOpen(true)}
          filterCount={filterCount} />

        <PushLayer open={filtersOpen} z={70}>
          <FiltersHubView
            filters={filters}
            onClose={() => setFiltersOpen(false)}
            onClearOne={(key) => setFilters((f) => { const n = { ...f }; delete n[key]; return n; })}
            onReset={() => setFilters({})}
            onRow={openFilterSub} />
        </PushLayer>

        <PushLayer open={filterSubOpen} z={80}>
          <FilterSubView
            catKey={filterSubKey}
            value={filterSubKey ? filters[filterSubKey] : null}
            onBack={closeFilterSub}
            onApply={applyFilterSub} />
        </PushLayer>

        <PushLayer open={reviewOpen} z={76}>
          <ReviewView
            badge={awardBadge}
            memberIds={selMemberIds} groupIds={selGroupIds}
            onBack={() => setReviewOpen(false)}
            onAddMore={() => setReviewOpen(false)}
            onRemoveMember={(id) => setSelMemberIds((ids) => ids.filter((x) => x !== id))}
            onRemoveGroup={(id) => setSelGroupIds((ids) => ids.filter((x) => x !== id))}
            onConfirm={confirmAward} />
        </PushLayer>

        <MenuSheet open={menuOpen} onClose={() => setMenuOpen(false)} />

        <div className="proto-cele">
          <Celebration data={celebrate} open={!!celebrate} onClose={celebrationDone} onAnother={celebrationAnother} />
        </div>
      </div>
    </IOSDevice>);
}

ReactDOM.createRoot(document.getElementById('root')).render(<PrototypeApp />);
