/* Inbox — the threads, and the mentions still owed.

   Commit model: INSTANT. A note posts on its own and a reaction applies on
   click; there is no Save on this screen.
   Data state: one branch — populated. The two sections are subsets of one array
   (the threads), each running its own predicate, and a predicate that matches
   nothing says so in place of its rows.

   A mention is owed until the person mentioned writes on that record
   (COMMENT_FLAGS.isAwaitingReply). That is the one predicate: the sidebar badge
   counts it, the section heading counts it, and each note states it. */
(() => {
  const { Button, Badge } = window.OriginDesignSystem_7c998b;

  const RECORD_ICON = { journey: "workflow", broadcast: "send", audience: "users", content: "file-text" };

  function ThreadTile({ thread, data, viewer, now, span, onNavigate, onPostNote, onReactToNote }) {
    const people = thread.people.map((id) => memberById(data.members, id));
    return (
      <Tile span={span}
        title={
          <button type="button" className="md-link" onClick={() => onNavigate(thread.route)}>{thread.title}</button>
        }
        note={thread.comments.length + " notes · last " + formatWhen(thread.lastAt, now)}
        actions={
          <>
            <Chip icon={RECORD_ICON[thread.type]}>{thread.type}</Chip>
            {thread.awaiting.length ? <Badge size="sm" variant="warning">{thread.awaiting.length} waiting on you</Badge> : null}
            <FaceStack people={people} max={4} size={24} />
          </>
        }>
        <div className="md-notes">
          {thread.comments.map((comment) => (
            <Note key={comment.id} comment={comment} comments={data.comments} members={data.members}
              viewer={viewer} now={now} onReact={onReactToNote} />
          ))}
        </div>
        <Composer viewer={viewer} members={data.members}
          placeholder={"Reply on " + thread.title + "…"}
          onPost={(body) => onPostNote({ type: thread.type, id: thread.id }, body)} />
      </Tile>
    );
  }

  function InboxScreen({ data, now, viewer, onNavigate, onPostNote, onReactToNote }) {
    const threads = commentThreads(data, viewer);
    const waiting = threads.filter((t) => t.awaiting.length);
    const rest = threads.filter((t) => !t.awaiting.length);
    const owed = mentionsOwedTo(data.comments, viewer.id);
    const mineOut = data.comments.filter((c) => c.authorId === viewer.id && c.mentions.length
      && c.mentions.some((id) => COMMENT_FLAGS.isAwaitingReply(c, id, data.comments)));

    return (
      <>
        <PageHeader path="/inbox" title="Inbox" actions={
          <Button variant="outline" size="sm" onClick={() => onNavigate("/activity")}><Icon name="history" size={14} />Activity</Button>
        } />

        <Tiles>
          <Tile span="5" tone="hero" title="What is waiting on you"
            note="A mention is owed until you write on that record. Nothing here is a status somebody set — it is the thread reading itself.">
            <StatRow>
              <StatTile label="Owed by you" value={formatCount(owed.length)} tone={owed.length ? "warning" : undefined}
                qualifier={owed.length ? "Across " + waiting.length + (waiting.length === 1 ? " thread" : " threads") : "Every mention of you has an answer after it"} />
              <StatTile label="Owed to you" value={formatCount(mineOut.length)}
                qualifier={mineOut.length ? "Notes you wrote where the person you pulled in has not replied" : "Nobody owes you a reply"} />
            </StatRow>
            <PillMeter label={"Threads: " + threads.length + " in total"}
              parts={[
                { key: "waiting", percent: (waiting.length / threads.length) * 100, tone: "warning" },
                { key: "rest", percent: (rest.length / threads.length) * 100, tone: "soft" },
              ]}
              foot={waiting.length + " waiting on you · " + rest.length + " you are simply in."} />
          </Tile>

          <Tile span="7" title="Who is in the conversation" note="Everybody who has written on a record or been pulled into one. Faces, not a count of seats.">
            <div className="md-queue">
              {data.members.map((member) => {
                const wrote = data.comments.filter((c) => c.authorId === member.id).length;
                const theirOwed = mentionsOwedTo(data.comments, member.id).length;
                return (
                  <div className="md-queue__row" key={member.id}>
                    <div className="md-person">
                      <Face person={member} size={30} />
                      <div className="md-person__text">
                        <button type="button" className="md-link md-person__name" onClick={() => onNavigate("/people/" + member.id)}>{member.name}</button>
                        <span className="md-person__role">{wrote} {wrote === 1 ? "note" : "notes"} written</span>
                      </div>
                    </div>
                    <div className="md-queue__side">
                      {theirOwed ? <Chip tone="warning" icon="clock">{theirOwed} owed</Chip> : <Chip icon="check">nothing owed</Chip>}
                    </div>
                  </div>
                );
              })}
            </div>
          </Tile>

          {waiting.length === 0 ? (
            <Tile span="12" title="Waiting on you">
              <p className="md-empty">Nothing is waiting on you. Every mention of you has a note from you after it.</p>
            </Tile>
          ) : waiting.map((thread, i) => (
            <ThreadTile key={thread.key} thread={thread} span={i % 3 === 0 ? "7" : "5"} data={data} viewer={viewer} now={now}
              onNavigate={onNavigate} onPostNote={onPostNote} onReactToNote={onReactToNote} />
          ))}

          <Tile span="12" tone="muted" title={"Threads you are in — " + rest.length}
            note="No mention of you outstanding on these. They are here because the record is yours or you have written on it.">
            <div className="md-queue">
              {rest.map((thread) => (
                <div className="md-queue__row" key={thread.key}>
                  <div className="md-queue__main">
                    <button type="button" className="md-link" onClick={() => onNavigate(thread.route)}>{thread.title}</button>
                    <span className="md-footnote">
                      {thread.comments.length} notes · last {formatWhen(thread.lastAt, now)} by {memberById(data.members, thread.comments[thread.comments.length - 1].authorId).name}
                    </span>
                  </div>
                  <div className="md-queue__side">
                    <Chip icon={RECORD_ICON[thread.type]}>{thread.type}</Chip>
                    <FaceStack people={thread.people.map((id) => memberById(data.members, id))} max={4} size={24} />
                  </div>
                </div>
              ))}
            </div>
          </Tile>
        </Tiles>
      </>
    );
  }

  /* Activity — the whole workspace feed, grouped by day.
     Commit model: INSTANT (nothing commits here at all — the feed is read only).
     Data state: one branch — populated. */
  function ActivityScreen({ data, now, onNavigate }) {
    const days = activityDays(data.activity || [], now);
    const today = days.length && startOfDay(now) === days[0].at ? days[0].entries.length : 0;
    const byPerson = data.members.map((m) => ({ member: m, count: activityFor(data.activity || [], m.id).length }))
      .filter((row) => row.count).sort((a, b) => b.count - a.count);
    const total = (data.activity || []).length;

    return (
      <>
        <PageHeader path="/activity" title="Activity" actions={
          <ExportMenu scope={total + " entries"} onExport={() => {}} />
        } />

        <Tiles>
          <Tile span="4" fit title="Who has been working" note={"Every entry in the feed, decomposed by the person who did it. " + total + " in total."}>
            <div className="md-donutrow">
              <Donut
                slices={byPerson.map((row) => ({ key: row.member.id, value: row.count }))}
                centreValue={formatCount(total)} centreLabel="entries" />
              <DonutKey slices={byPerson.map((row) => ({ key: row.member.id, label: row.member.name.split(" ")[0], display: String(row.count) }))} />
            </div>
            <div className="md-tile__foot"><span>{today ? today + (today === 1 ? " entry" : " entries") + " today." : "Nothing recorded today yet."}</span></div>
          </Tile>

          <Tile span="8" title="The feed" note="One entry per act, newest first. Every entry names a record that has a screen.">
            <div className="md-feed">
              {days.map((day) => (
                <section className="md-feed__day" key={day.at}>
                  <h3 className="md-feed__date">
                    {startOfDay(now) === day.at ? "Today" : new Date(day.at).toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" })}
                  </h3>
                  {day.entries.map((entry) => {
                    const actor = memberById(data.members, entry.actorId);
                    const verb = ACTIVITY_VERBS.find((v) => v.value === entry.verb) || { label: entry.verb, icon: "dot" };
                    return (
                      <div className="md-feed__row" key={entry.id}>
                        <Face person={actor} size={28} />
                        <span className="md-feed__text">
                          <span>
                            <button type="button" className="md-link" onClick={() => onNavigate("/people/" + actor.id)}>{actor.name.split(" ")[0]}</button>
                            {" "}{verb.label}{" "}
                            {entry.record ? (
                              <button type="button" className="md-link" onClick={() => onNavigate(recordRoute(entry.record.type, entry.record.id))}>
                                {recordTitle(data, entry.record.type, entry.record.id)}
                              </button>
                            ) : null}
                          </span>
                          {entry.note ? <span className="md-feed__note">{entry.note}</span> : null}
                        </span>
                        <span className="md-feed__when" title={formatAbsolute(entry.at)}>{formatWhen(entry.at, now)}</span>
                      </div>
                    );
                  })}
                </section>
              ))}
            </div>
          </Tile>
        </Tiles>
      </>
    );
  }

  Object.assign(window, { InboxScreen, ActivityScreen });
})();
