/* Overview — what sending did, and what is waiting on somebody.

   Commit model: INSTANT. Pausing a journey applies immediately with an undo
   toast; approving a broadcast the same; nothing on this screen stages.
   Data state: one branch — populated. Each tile below runs its own predicate,
   and a predicate that matches nothing says so in place of its rows.
   Scope: the period control sits above the tiles and moves the sending figures
   and the chart together (§5.3). Every tile that is NOT scoped by it says so.

   The composition is tiles, not bands: a hero that spans seven tracks, a rate
   tile beside it, the day chart across eight, and the three queues beneath in
   uneven spans, so no grid line runs the length of the page. */
(() => {
  const { Select, Button, Badge } = window.OriginDesignSystem_7c998b;

  function OverviewScreen({ data, now, period, onPeriodChange, onNavigate, viewer, onJourneyTransition, onBroadcastTransition, onReactToNote }) {
    const days = Number(period);
    const series = deliverySeries(data, days, now);
    const totals = deliveryTotals(series);

    const attention = journeysNeedingAttention(data.journeys, now);
    const review = broadcastsToReview(data.broadcasts, viewer).slice().sort((a, b) => a.scheduledAt - b.scheduledAt);
    const mine = broadcastsInReview(data.broadcasts).filter((b) => BROADCAST_FLAGS.isMine(b, viewer));
    const owed = mentionsOwedTo(data.comments, viewer.id);
    const urgentReview = review.filter((b) => BROADCAST_FLAGS.isReviewUrgent(b, now));
    const reviewReach = review.reduce((n, b) => n + broadcastRecipients(b, data.audiences).count, 0);
    const upcoming = calendarEntries(data).filter((e) => e.at >= now).sort((a, b) => a.at - b.at);
    const recentNotes = data.comments.slice().sort((a, b) => b.at - a.at).slice(0, 2);

    const openRate = rate(totals.opened, totals.delivered);
    const clickRate = rate(totals.clicked, totals.delivered);
    const journeyShare = rate(totals.journey.delivered, totals.delivered);

    const chartDays = series.map((entry) => ({
      at: entry.at,
      total: entry.delivered,
      segments: [
        { key: "journey", value: entry.journey.delivered },
        { key: "broadcast", value: entry.broadcast.delivered, tone: "soft" },
      ],
      tip: [
        { label: "Delivered", value: formatCount(entry.delivered) },
        { label: "From journeys", value: formatCount(entry.journey.delivered) },
        { label: "From broadcasts", value: formatCount(entry.broadcast.delivered) },
        { label: "Opens", value: formatCount(entry.opened) },
        { label: "Clicks", value: formatCount(entry.clicked) },
        { label: "Unsubscribes", value: formatCount(entry.unsubs) },
      ].concat(entry.broadcasts.map((b) => ({ label: b.name, value: formatCount(b.delivered) }))),
    }));

    return (
      <>
        <PageHeader path="/" title="Overview" actions={
          <Button variant="outline" size="sm" onClick={() => onNavigate("/reports")}><Icon name="chart-line" size={14} />Reports</Button>
        } />

        <div className="md-scope">
          <span className="md-scope__control">
            <span className="md-scope__label">Period</span>
            <span className="md-scope__select">
              <Select size="sm" items={PERIODS} value={period} aria-label="Period for the sending figures and the chart" onValueChange={onPeriodChange} />
            </span>
          </span>
          <p className="md-scope__note">The sending figures and the chart cover the last {days} days, journeys and broadcasts together. The queues below are not scoped by it.</p>
        </div>

        <Tiles>
          <Tile span="7" tone="hero" distribute="spread" title={"Sending, last " + days + " days"}
            note="One series, two sources: the journey send log, plus each broadcast on the day it went out.">
            <StatRow>
              <StatTile label="Delivered" value={formatCount(totals.delivered)}
                spark={<Spark points={series.map((d) => d.delivered)} />}
                qualifier={formatCount(totals.journey.delivered) + " from journeys · " + formatCount(totals.broadcast.delivered) + " from broadcasts"} />
              <StatTile label="Opens" value={formatCount(totals.opened)}
                spark={<Spark points={series.map((d) => d.opened)} tone="success" />}
                qualifier={formatPercent(openRate) + " of what was delivered"} />
              <StatTile label="Unsubscribes" value={formatCount(totals.unsubs)}
                spark={<Spark points={series.map((d) => d.unsubs)} tone="warning" />}
                qualifier={formatPercent(rate(totals.unsubs, totals.delivered)) + " of the same delivered total"} />
            </StatRow>
            <PillMeter label={"Where the " + formatCount(totals.delivered) + " came from"}
              parts={[
                { key: "journeys", percent: journeyShare * 100 },
                { key: "broadcasts", percent: (1 - journeyShare) * 100, tone: "soft" },
              ]}
              foot={formatPercent(journeyShare) + " came from journeys running continuously; the rest is " + sentBroadcasts(data.broadcasts, days, now).length + " one-off sends inside the window."} />
          </Tile>

          <Tile span="5" title="Are they reading it?" note="Both rates read the delivered total beside them, so they are comparable.">
            <div style={{ display: "flex", flexWrap: "wrap", gap: "var(--space-4)", justifyContent: "space-around" }}>
              <Gauge percent={openRate * 100} value={formatPercent(openRate)} label="opened"
                tone={openRate > 0.3 ? "success" : "warning"}
                note={formatCount(totals.opened) + " opens across " + formatCount(totals.delivered) + " delivered."} />
              <Gauge percent={clickRate * 100 * 4} value={formatPercent(clickRate)} label="clicked"
                note={"Against a 25% ceiling · " + formatCount(totals.clicked) + " clicks."} />
            </div>
            <div className="md-tile__foot">
              <span>Audience-by-audience and person-by-person breakdowns are on Reports.</span>
              <Button variant="ghost" size="sm" onClick={() => onNavigate("/reports")}>Open<Icon name="arrow-right" size={14} /></Button>
            </div>
          </Tile>

          <Tile span="8" title="Delivered a day" note="Bars, not curves: the reader is comparing days against each other. Hover a day for the numbers it is drawn from.">
            <DayChart
              days={chartDays}
              label={"Delivery a day over the last " + days + " days"}
              legend={[{ label: "Journeys" }, { label: "Broadcasts", tone: "soft" }]}
              foot={sentBroadcasts(data.broadcasts, days, now).length + " broadcasts went out inside the window."}
            />
          </Tile>

          <Tile span="4" tone="muted" distribute="bottom" title="Waiting on your review"
            note="In review, submitted by somebody else, and your role can approve. Not scoped by the period."
            actions={review.length > 1 ? <Button variant="outline" size="sm" onClick={() => onNavigate("/approvals")}>All {review.length}</Button> : null}
            foot={
              <>
                <span>
                  {mine.length
                    ? (mine.length === 1 ? "One more is in review" : mine.length + " more are in review") + " — you submitted " + (mine.length === 1 ? "it" : "them") + ", so it needs one of"
                    : "Anyone who can approve, other than whoever submitted:"}
                </span>
                <FaceStack size={24} people={data.members.filter((m) => ROLE_CAN_APPROVE[m.teamRole] && m.id !== viewer.id)} />
              </>
            }>
            <StatRow>
              <StatTile label="On your desk" value={formatCount(review.length)}
                qualifier={urgentReview.length
                  ? urgentReview.length + (urgentReview.length === 1 ? " of them sends" : " of them send") + " within two days"
                  : review.length ? "None of them sends within two days" : "Nothing is in review that you can approve"}
                onClick={() => onNavigate("/approvals")} />
              <StatTile label="People they reach" value={formatCount(reviewReach)}
                qualifier={review.length
                  ? "Across " + review.length + (review.length === 1 ? " audience" : " audiences") + ", counted as each stands now"
                  : "Nothing is waiting to go out through you"} />
            </StatRow>
            {review.length === 0 ? (
              <p className="md-empty">Nothing is waiting on you.{mine.length ? " The " + mine.length + " you submitted need somebody else." : ""}</p>
            ) : (
              <div className="md-queue">
                {review.slice(0, 3).map((broadcast) => {
                  const recipients = broadcastRecipients(broadcast, data.audiences);
                  return (
                    <div className="md-queue__row" key={broadcast.id}>
                      <div className="md-queue__main">
                        <button type="button" className="md-link" onClick={() => onNavigate("/broadcasts/" + broadcast.id)}>{broadcast.name}</button>
                        <span className="md-footnote">
                          {formatCount(recipients.count)} in {audienceName(data.audiences, broadcast.audienceId)} · from {memberName(data.members, broadcast.submittedById)}
                        </span>
                      </div>
                      <div className="md-queue__side">
                        <span className={"md-clock" + (BROADCAST_FLAGS.isReviewUrgent(broadcast, now) ? " md-clock--warning" : " md-muted")} title={formatAbsolute(broadcast.scheduledAt)}>
                          {formatCountdown(broadcast.scheduledAt, now)}
                        </span>
                        <Transitions transitions={broadcastTransitions(broadcast, viewer).filter((t) => t.primary)} onRun={(t) => onBroadcastTransition(broadcast, t)} />
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </Tile>

          <Tile span="6" title="Journeys needing attention"
            note="Live journeys failing to deliver or no longer matching anyone. Not scoped by the period.">
            {attention.length === 0 ? (
              <p className="md-empty">All {liveJourneys(data.journeys).length} live journeys are delivering and still matching people.</p>
            ) : (
              <div className="md-queue">
                {attention.map((journey) => (
                  <div className="md-queue__row" key={journey.id}>
                    <div className="md-queue__main">
                      <button type="button" className="md-link" onClick={() => onNavigate("/journeys/" + journey.id)}>{journey.name}</button>
                      <span className="md-footnote">{journeyConcern(journey, now)}</span>
                    </div>
                    <div className="md-queue__side">
                      <StatusBadge values={JOURNEY_STATUS} value={journey.status} />
                      <span className="md-footnote">{formatCount(journeyEnrolled(journey))} enrolled</span>
                      <Transitions transitions={journeyTransitions(journey, data.content).filter((t) => t.primary)} onRun={(t) => onJourneyTransition(journey, t)} />
                    </div>
                  </div>
                ))}
              </div>
            )}
          </Tile>

          <Tile span="6" tone="muted" title="The desk is talking"
            note="The two most recent notes anywhere in the workspace. A mention is owed until the person named writes on that record."
            actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/inbox")}>{owed.length ? owed.length + " waiting on you" : "Inbox"}</Button>}>
            <div className="md-notes">
              {recentNotes.map((comment) => (
                <div key={comment.id}>
                  <button type="button" className="md-link md-footnote" onClick={() => onNavigate(recordRoute(comment.record.type, comment.record.id))}>
                    on {recordTitle(data, comment.record.type, comment.record.id)}
                  </button>
                  <Note comment={comment} comments={data.comments} members={data.members} viewer={viewer} now={now} onReact={onReactToNote} />
                </div>
              ))}
            </div>
          </Tile>

          <Tile span="5" title="Next out of the door" note="Dated sends from now on, soonest first. Live journeys have no date and are not here.">
            {upcoming.length === 0 ? <p className="md-empty">Nothing is scheduled.</p> : (
              <div className="md-queue">
                {upcoming.slice(0, 3).map((entry) => {
                  const broadcast = data.broadcasts.find((b) => b.id === entry.id);
                  return (
                    <div className="md-queue__row" key={entry.id}>
                      <div className="md-queue__main">
                        <button type="button" className="md-link" onClick={() => onNavigate(entry.route)}>{entry.name}</button>
                        <span className="md-footnote">{formatCount(broadcastRecipients(broadcast, data.audiences).count)} in {audienceName(data.audiences, broadcast.audienceId)}</span>
                      </div>
                      <div className="md-queue__side">
                        <StatusBadge values={BROADCAST_STATUS} value={broadcast.status} />
                        <span className="md-clock md-muted">{formatCountdown(entry.at, now)}</span>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
            <div className="md-tile__foot">
              <span>The month and the week are on Calendar.</span>
              <Button variant="ghost" size="sm" onClick={() => onNavigate("/calendar")}>Open calendar<Icon name="arrow-right" size={14} /></Button>
            </div>
          </Tile>

          <Tile span="7" tone="muted" title="Who is on it" note="Everybody in the workspace, and what each of them is carrying right now.">
            <div className="md-queue">
              {data.members.map((member) => {
                const load = personLoad(data, member.id, now);
                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">{member.role}</span>
                      </div>
                    </div>
                    <div className="md-queue__side">
                      {load.liveJourneys.length ? <Chip icon="workflow">{load.liveJourneys.length} live</Chip> : null}
                      {load.submitted.length ? <Chip icon="send">{load.submitted.length} in review</Chip> : null}
                      {load.owed.length ? <Chip tone="warning" icon="clock">{load.owed.length} owed</Chip> : null}
                      {!load.liveJourneys.length && !load.submitted.length && !load.owed.length ? <span className="md-footnote">nothing outstanding</span> : null}
                    </div>
                  </div>
                );
              })}
            </div>
            <div className="md-tile__foot">
              <span>Roles and entitlements are on Team and roles.</span>
              <Button variant="ghost" size="sm" onClick={() => onNavigate("/people")}>Open people<Icon name="arrow-right" size={14} /></Button>
            </div>
          </Tile>
        </Tiles>
      </>
    );
  }

  Object.assign(window, { OverviewScreen });
})();
