/* Dailies · Past Approvals — the archive of signed-off work.
   ---------------------------------------------------------------------------
   A secondary surface off the feed (and the IC desk), not the main queue:
   once an asset is approved it leaves the feed entirely and lands here. There
   is no "locked" resting state — an asset is either still being discussed in
   the feed, or approved and filed here.

   Role-scoped from one archive:
     - An IC sees the work they authored.
     - A reviewer sees every cut they were ASSIGNED to, even the ones they never
       personally signed (a single decisive sign-off approves the asset).
   The "Viewing as" switch swaps perspective; ?as=<id> sets the entry identity
   (the feed links in as Brian, the IC desk as Maya).
   ============================================================ */

const { useState, useMemo } = React;

/* ---------- People who can open this archive ---------- */
const PEOPLE = {
  maya:  { id: 'maya',  name: 'Maya Chen',     role: 'Lead Character Artist', initials: 'MC', kind: 'ic' },
  brian: { id: 'brian', name: 'Brian Robbins', role: 'Co-Founder \u00b7 CEO',  initials: 'BR', kind: 'reviewer' },
  eve:   { id: 'eve',   name: 'Eve Park',      role: 'Creative Director',     initials: 'EP', kind: 'reviewer' },
};
const PERSON_ORDER = ['maya', 'brian', 'eve'];

/* ---------- The archive: approved assets with their prior iterations ----------
   `author`  — the IC who made it.
   `reviewers` — everyone assigned to review (drives the reviewer scope).
   `approvals` — who actually signed off (a subset of reviewers; one is enough).
   `rounds`  — the iterations the asset went through before the sign-off. */
const APPROVALS = [
  {
    id: 'a1', ip: 'ELOISE', assetType: 'Endpaper', version: 'Final ink', kind: 'image',
    blurb: 'Illustration \u2014 final ink pass.',
    author: 'Maya Chen', reviewers: ['Brian Robbins', 'Eve Park'],
    approvals: [{ who: 'Brian Robbins', when: 'May 25' }],
    approvedOn: 'May 25', approvedSort: '2026-05-25',
    rounds: [
      { label: 'v1', when: 'May 22', notes: [{ who: 'Brian Robbins', text: 'Line wobble on the spine \u2014 steady the long curves before ink.' }] },
      { label: 'v2', when: 'May 24', notes: [{ who: 'Eve Park', text: 'Warm the gold a touch so it sits with the cover stock.' }] },
    ],
  },
  {
    id: 'a2', ip: 'ELOISE', assetType: 'Character pose', version: 'v2', kind: 'image',
    blurb: 'Reading on the radiator \u2014 silhouette locked.',
    author: 'Maya Chen', reviewers: ['Brian Robbins'],
    approvals: [{ who: 'Brian Robbins', when: 'Today' }],
    approvedOn: 'Today', approvedSort: '2026-06-04',
    rounds: [
      { label: 'v1', when: 'Yesterday', notes: [
        { who: 'Brian Robbins', text: 'Silhouette reads flat. Push the back arch and lift the chin.' },
        { who: 'Brian Robbins', text: 'Warm the radiator glow on her face.' },
      ] },
    ],
  },
  {
    id: 'a3', ip: 'BUCKET LIST', assetType: 'Sponsor reel', version: 'Cut B', kind: 'video',
    blurb: 'Pacing fix landed \u2014 cut B is the one.',
    author: 'Marcus Reed', reviewers: ['Brian Robbins', 'Eve Park'],
    approvals: [{ who: 'Eve Park', when: '2 days ago' }],
    approvedOn: '2 days ago', approvedSort: '2026-06-02',
    rounds: [
      { label: 'Cut A', when: '3 days ago', notes: [{ who: 'Brian Robbins', text: 'Tighten the middle 20 seconds. It drags before the logo.' }] },
    ],
  },
  {
    id: 'a4', ip: 'IS\u00d7OP', assetType: 'Title card', version: 'Final', kind: 'image',
    blurb: '\u201cThe Crew Lands\u201d \u2014 lockup approved.',
    author: 'Lin Wei', reviewers: ['Brian Robbins', 'Eve Park'],
    approvals: [{ who: 'Eve Park', when: 'May 24' }, { who: 'Brian Robbins', when: 'May 24' }],
    approvedOn: 'May 24', approvedSort: '2026-05-24',
    rounds: [
      { label: 'Variant', when: 'May 23', notes: [{ who: 'Eve Park', text: 'Go with the condensed direction \u2014 it carries the speed.' }] },
    ],
  },
  {
    id: 'a5', ip: 'ELOISE', assetType: 'Spread', version: 'Layout B', kind: 'image',
    blurb: 'Double-page \u2014 gutter cleared.',
    author: 'Maya Chen', reviewers: ['Eve Park'],
    approvals: [{ who: 'Eve Park', when: 'Yesterday' }],
    approvedOn: 'Yesterday', approvedSort: '2026-06-03',
    rounds: [
      { label: 'Layout A', when: '2 days ago', notes: [{ who: 'Eve Park', text: 'Art falls in the gutter \u2014 shift the figure a column right.' }] },
    ],
  },
  {
    id: 'a6', ip: 'BUCKET LIST', assetType: 'Narration script', version: '2nd pass', kind: 'request',
    blurb: 'Q3 trailer VO \u2014 approved to record.',
    author: 'Priya Iyer', reviewers: ['Brian Robbins'],
    approvals: [{ who: 'Brian Robbins', when: 'May 26' }],
    approvedOn: 'May 26', approvedSort: '2026-05-26',
    rounds: [
      { label: '1st pass', when: 'May 25', notes: [{ who: 'Brian Robbins', text: 'Trim the setup line \u2014 hit the hook in the first eight seconds.' }] },
    ],
  },
];

/* ---------- scope + format helpers ---------- */
function initialPersonId() {
  try {
    const p = new URLSearchParams(window.location.search).get('as');
    if (p && PEOPLE[p]) return p;
  } catch (e) { /* no search params */ }
  return 'brian';
}
function visibleFor(person) {
  const mine = person.kind === 'ic'
    ? APPROVALS.filter(a => a.author === person.name)
    : APPROVALS.filter(a => (a.reviewers || []).includes(person.name));
  return mine.slice().sort((a, b) => (a.approvedSort < b.approvedSort ? 1 : a.approvedSort > b.approvedSort ? -1 : 0));
}
function initialsOf(name) {
  const parts = name.trim().split(/\s+/);
  const last = parts.length > 1 ? parts[parts.length - 1][0] : '';
  return (parts[0][0] + last).toUpperCase();
}
function nameList(names) {
  if (names.length === 0) return '';
  if (names.length === 1) return names[0];
  return names.slice(0, -1).join(', ') + ' & ' + names[names.length - 1];
}
/* The sign-off line, told from the current identity's point of view. */
function signoff(person, item) {
  const signed = item.approvals.map(a => a.who);
  if (person.kind === 'ic') return { label: 'Approved by ' + nameList(signed), tone: 'plain' };
  const mine = item.approvals.find(a => a.who === person.name);
  if (mine) return { label: 'You signed off \u00b7 ' + mine.when, tone: 'you' };
  return { label: 'Assigned to you \u00b7 signed off by ' + nameList(signed), tone: 'observed' };
}

/* ---------- Icons ---------- */
const Check = ({ size = 12 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
);
const Chevron = ({ size = 14 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6"/></svg>
);
const BackChevron = ({ size = 14 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
);
const KindGlyph = ({ kind, size = 13 }) => {
  if (kind === 'video') return <svg viewBox="0 0 24 24" width={size} height={size} fill="currentColor" stroke="none"><path d="M8 5v14l11-7z"/></svg>;
  if (kind === 'request') return <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 5h16M4 10h16M4 15h10"/></svg>;
  /* image / pdf share the document-with-image mark */
  return <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="1.6"/><path d="M21 16l-5-5-7 7"/></svg>;
};

/* ---------- Thumbnail: IP monogram + a kind badge ---------- */
function PaThumb({ item }) {
  const mono =
    item.ip === 'BUCKET LIST' ? 'BLF' :
    item.ip === 'IS\u00d7OP'  ? 'IS\u00d7OP' :
    item.ip === 'ELOISE'      ? 'ELO' : 'BSP';
  return (
    <div className="pa-thumb">
      <span className="pa-thumb-mono">{mono}</span>
      <span className="pa-thumb-kind" aria-hidden="true"><KindGlyph kind={item.kind}/></span>
    </div>
  );
}

/* ---------- Assigned-reviewer chips: signed (gold) vs assigned-only ---------- */
function ReviewerChips({ item, me }) {
  return (
    <div className="pa-chips">
      {item.reviewers.map(name => {
        const signed = item.approvals.some(a => a.who === name);
        const isMe = name === me.name;
        return (
          <span
            key={name}
            className={'pa-chip' + (signed ? ' signed' : '') + (isMe ? ' me' : '')}
            title={name + (signed ? ' \u2014 signed off' : ' \u2014 assigned, no sign-off')}
          >
            <span className="pa-chip-dot" aria-hidden="true"></span>
            <span className="pa-chip-init">{initialsOf(name)}</span>
            {isMe && <span className="pa-chip-you">You</span>}
          </span>
        );
      })}
    </div>
  );
}

/* ---------- One archive card ---------- */
function PaCard({ item, person, index }) {
  const [open, setOpen] = useState(false);
  const so = signoff(person, item);
  const rounds = item.rounds || [];
  return (
    <article className="pa-card reveal" style={{ animationDelay: (index * 50) + 'ms' }}>
      <div className="pa-card-head">
        <div className="pa-tags">
          <span className="pa-ip">{item.ip}</span>
          <span className="pa-type">{item.assetType}{item.version ? ' \u00b7 ' + item.version : ''}</span>
        </div>
        <span className="pa-stamp"><Check size={11}/> Approved</span>
      </div>

      <div className="pa-card-main">
        <PaThumb item={item}/>
        <div className="pa-card-info">
          <h3 className="pa-title">{item.blurb}</h3>
          <div className="pa-byline">
            <span className="pa-author">{item.author}</span>
            <span className="pa-dot" aria-hidden="true"></span>
            <span className="pa-when">{item.approvedOn}</span>
          </div>
          <div className={'pa-signoff tone-' + so.tone}>{so.label}</div>
        </div>
      </div>

      <div className="pa-reviewers">
        <span className="pa-rev-lbl">Assigned</span>
        <ReviewerChips item={item} me={person}/>
      </div>

      {rounds.length > 0 && (
        <div className="pa-rounds-wrap">
          <button className="pa-rounds-toggle" onClick={() => setOpen(o => !o)} aria-expanded={open}>
            <span className={'pa-rounds-chev' + (open ? ' open' : '')}><Chevron size={13}/></span>
            {rounds.length} {rounds.length === 1 ? 'iteration' : 'iterations'} before sign-off
          </button>
          {open && (
            <ol className="pa-rounds">
              {rounds.map((r, i) => (
                <li className="pa-round" key={i}>
                  <div className="pa-round-head">
                    <span className="pa-round-label">{r.label}</span>
                    <span className="pa-round-when">{r.when}</span>
                  </div>
                  <ul className="pa-round-notes">
                    {r.notes.map((n, k) => (
                      <li className="pa-round-note" key={k}>
                        <span className="pa-note-who">{n.who}</span>
                        <span className="pa-note-text">{n.text}</span>
                      </li>
                    ))}
                  </ul>
                </li>
              ))}
              <li className="pa-round final">
                <div className="pa-round-head">
                  <span className="pa-round-label"><Check size={10}/> {item.version || 'Final'}</span>
                  <span className="pa-round-when">Approved {'\u00b7'} {item.approvedOn}</span>
                </div>
              </li>
            </ol>
          )}
        </div>
      )}
    </article>
  );
}

/* ---------- Identity switch ---------- */
function IdentitySwitch({ personId, onChange }) {
  return (
    <div className="pa-switch" role="tablist" aria-label="View this archive as">
      <span className="pa-switch-lbl">Viewing as</span>
      <div className="pa-switch-seg">
        {PERSON_ORDER.map(id => {
          const p = PEOPLE[id];
          return (
            <button
              key={id}
              type="button"
              role="tab"
              aria-selected={id === personId}
              className={'pa-switch-opt' + (id === personId ? ' active' : '')}
              onClick={() => onChange(id)}
            >
              <span className="pa-av">{p.initials}</span>
              <span className="pa-switch-who">
                <strong>{p.name.split(' ')[0]}</strong>
                <span>{p.kind === 'ic' ? 'IC' : 'Reviewer'}</span>
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- App ---------- */
function PastApprovals() {
  const [personId, setPersonId] = useState(initialPersonId);
  const person = PEOPLE[personId];
  const items = useMemo(() => visibleFor(person), [personId]);
  const backHref = person.kind === 'ic' ? 'IC Home.html' : 'Dailies Feed.html';
  const backLabel = person.kind === 'ic' ? 'IC desk' : 'Feed';

  return (
    <div className="pa">
      <header className="pa-head">
        <div className="pa-head-left">
          <a className="pa-back" href={backHref}><BackChevron size={14}/> {backLabel}</a>
          <a className="pa-mark" href="../index.html" aria-label="Dailies home">
            <img className="pa-mark-icon" src="assets/logo/dailies-icon-flat.svg" alt="" />
            <img className="pa-mark-word" src="assets/logo/dailies-wordmark.svg" alt="Dailies" />
          </a>
          <SurfaceNav current="approvals"/>
        </div>
        <IdentitySwitch personId={personId} onChange={setPersonId}/>
      </header>

      <div className="pa-scroll">
        <section className="pa-hero">
          <div className="pa-eyebrow"><span className="dot" aria-hidden="true"></span> In the can</div>
          <h1 className="pa-h1">Past Approvals</h1>
          <p className="pa-sub">
            {person.kind === 'ic'
              ? 'Your work that cleared review and shipped.'
              : 'Signed-off work from every cut you were assigned \u2014 including the ones the room closed without you.'}
          </p>
          <div className="pa-count">
            <span className="n">{items.length}</span>
            <span className="l">{items.length === 1 ? 'approval' : 'approvals'} {person.kind === 'ic' ? 'of your work' : 'on your slate'}</span>
          </div>
        </section>

        {items.length > 0 ? (
          <div className="pa-grid">
            {items.map((it, i) => <PaCard key={it.id} item={it} person={person} index={i}/>)}
          </div>
        ) : (
          <div className="pa-empty">
            <div className="pa-empty-mark"><Check size={22}/></div>
            <div className="pa-empty-eb">Nothing filed yet</div>
            <div className="pa-empty-msg">
              {person.kind === 'ic'
                ? 'When a reviewer signs off your work, it lands here.'
                : 'Cuts you sign off \u2014 or that close on your slate \u2014 will collect here.'}
            </div>
          </div>
        )}

        <div className="pa-foot">
          <span className="rule"></span>
          <span className="lbl">Dailies {'\u00b7'} The cut, in the can</span>
          <span className="rule"></span>
        </div>
      </div>
    </div>
  );
}

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