/* Performance — what went live, measured against what we promised in the pitch.
   Commit model: INSTANT. Nothing on this screen commits anything; it is a
   reading surface. Figures move when a deliverable is marked published on the
   deliverables desk, because they are computed from the posts.
   Data state: populated. A campaign with nothing live is not an empty state —
   it is a campaign whose figure is suppressed, and it says so in words.
   Scope: stated in words rather than filtered. The agency figure is over
   completed campaigns only; the wall shows every campaign with at least one
   post live. There is no period control, so nothing here moves under you.
   Primary display: the promise wall — one row per campaign, the promise a
   fixed vertical rule at the same place on every track, so over and under are
   read as position rather than arithmetic. */
(() => {
  const { Button, Badge, Separator } = window.OriginDesignSystem_7c998b;

  /* The wall sits at the same place on every track, so the bars are comparable
     across campaigns of very different sizes. A bar can run to the end of the
     track, which is 143% of promise; anything beyond that is stated in the
     figure rather than drawn. */
  const WALL = 70;
  const TRACK_CAP = 100 / (WALL / 100);

  function PromiseRow({ deal, creator, now, onNavigate }) {
    const state = campaignState(deal);
    const index = deliveryIndex(deal);
    const share = (actualReach(deal) / deal.promise.reach) * WALL;
    const width = Math.min(100, share);
    const under = index !== null && index < 1;
    return (
      <div className="mq-prow">
        <div className="mq-who">
          <Portrait creator={creator} size={40} />
          <span className="mq-who__text">
            <button type="button" className="mq-link" onClick={() => onNavigate("/performance/" + deal.id)}>{deal.brand}</button>
            <span className="mq-who__meta">{creator.name} · {publishedOf(deal).length} of {deal.deliverables.length} live</span>
          </span>
        </div>
        <div className="mq-prow__track">
          <div className="mq-ptrack">
            <span className="mq-ptrack__fill" data-under={under ? "yes" : "no"} data-flight={state === "in_flight" ? "yes" : "no"} style={{ width: width.toFixed(1) + "%" }} />
            <span className="mq-ptrack__wall" style={{ insetInlineStart: WALL + "%" }} />
            <span className="mq-ptrack__walllabel" style={{ insetInlineStart: WALL + "%" }}>promised {formatFollowers(deal.promise.reach)}</span>
          </div>
        </div>
        <div>
          <div className={"mq-pindex" + (index === null ? " mq-muted" : under ? " mq-warn" : " mq-good")} style={index === null ? { fontSize: "var(--text-sm)" } : null}>
            {index === null ? (state === "in_flight" ? "In flight" : "Not yet live") : formatPercent(index)}
          </div>
          <div className="mq-figure__note" style={{ textAlign: "right" }}>{formatFollowers(actualReach(deal))} reached</div>
        </div>
      </div>
    );
  }

  function PerformanceScreen({ data, now, onNavigate, pushToast }) {
    const measurable = measurableDeals(data.deals);
    const complete = completeDeals(data.deals);
    const notStarted = data.deals.filter((d) => campaignState(d) === "not_started");
    const kept = promiseKeptRate(data.deals);
    const liveRows = deliverablesLive(allDeliverables(data.deals, data.creators)).slice().sort((a, b) => b.item.metrics.reach - a.item.metrics.reach);
    const reachTotal = sumOf(liveRows, (r) => r.item.metrics.reach);
    const savesTotal = sumOf(liveRows, (r) => r.item.metrics.saves);
    const engagementsTotal = sumOf(liveRows, (r) => r.item.metrics.engagements);
    const missed = complete.filter((d) => deliveryIndex(d) < 1);

    return (
      <div className="mq-page">
        <PageHead
          path="/performance"
          title="Against the promise"
          lede={kept === null
            ? "No campaign has finished yet, so there is nothing to judge."
            : "Across the " + complete.length + " campaigns that have finished, we delivered " + formatPercent(kept) + " of the reach we promised" + (missed.length ? " — and " + missed.map((d) => d.brand).join(", ") + " came in under, which is the conversation to have before the renewal." : ".") + " Campaigns still in flight are not counted: half a campaign is not underdelivery."}
          actions={<ExportMenu scope="Campaign performance" onExport={(format) => pushToast({ title: "Export started", description: "Performance · " + format + " — we'll email it to " + MARQUE_USER.name.split(" ")[0].toLowerCase() + "@marque.example" })} />}
        />

        <div className="mq-bleed">
          <div className="mq-figures">
            <Figure size="xl" label="Promise kept" value={kept === null ? "—" : formatPercent(kept)} note={"Reach delivered against reach promised, over the " + complete.length + " finished campaigns"} />
            <Figure size="xl" label="Reach delivered" value={formatFollowers(reachTotal)} note={liveRows.length + " posts live across " + measurable.length + " campaigns"} />
            <Figure size="xl" label="Engagement" value={formatPercent(reachTotal ? engagementsTotal / reachTotal : null)} note={formatCount(engagementsTotal) + " engagements on the same " + liveRows.length + " posts"} />
            <Figure size="xl" label="Saves" value={formatCount(savesTotal)} note="The number brands ask about second, and the one creators are proudest of" />
          </div>
        </div>

        <section className="mq-section">
          <div className="mq-section__head">
            <h2 className="mq-h2">The promise wall<span className="mq-tab-count">{measurable.length}</span></h2>
            <p className="mq-note">Every campaign with at least one post live. The rule is the reach we promised in the pitch; the bar is what the posts actually did. A bar reaching the end of its track is {Math.round(TRACK_CAP)}% of promise — past that the figure carries it.</p>
          </div>
          <div className="mq-promise">
            {measurable
              .slice()
              .sort((a, b) => (deliveryIndex(a) === null ? -1 : deliveryIndex(b) === null ? 1 : deliveryIndex(a) - deliveryIndex(b)))
              .map((deal) => (
                <PromiseRow key={deal.id} deal={deal} creator={creatorById(data.creators, deal.creatorId)} now={now} onNavigate={onNavigate} />
              ))}
          </div>
          {notStarted.length ? (
            <p className="mq-note">
              {notStarted.map((d) => d.brand + " × " + creatorById(data.creators, d.creatorId).name.split(" ")[0]).join(", ")} {notStarted.length === 1 ? "has" : "have"} nothing live yet, so {notStarted.length === 1 ? "it is" : "they are"} not on the wall. {notStarted.length === 1 ? "Its" : "Their"} first post is due {formatAbsolute(byDue(notStarted[0].deliverables.map((i) => ({ item: i })))[0].item.dueAt).split(",")[0]}.
            </p>
          ) : null}
        </section>

        <section className="mq-section">
          <div className="mq-section__head">
            <h2 className="mq-h2">Every post live<span className="mq-tab-count">{liveRows.length}</span></h2>
            <p className="mq-note">Sorted by reach. These are the rows every figure above is summed from.</p>
          </div>
          <div className="mq-posts">
            {liveRows.map((row) => (
              <article className="mq-post" key={row.item.id}>
                <div className="mq-col mq-col--tight">
                  <Eyebrow>{row.deal.brand} · {formatAbsolute(row.item.publishedAt).split(",")[0]}</Eyebrow>
                  <button type="button" className="mq-link mq-row__title" onClick={() => onNavigate("/deliverables/" + row.item.id)}>{row.item.title}</button>
                  <span className="mq-who__meta">{row.creator.name} · {labelOf(DELIVERABLE_KINDS, row.item.kind)}</span>
                </div>
                <div className="mq-post__metrics">
                  <Figure size="sm" label="Reach" value={formatFollowers(row.item.metrics.reach)} />
                  <Figure size="sm" label="Engaged" value={formatPercent(row.item.metrics.engagements / row.item.metrics.reach)} />
                  <Figure size="sm" label="Saves" value={formatCount(row.item.metrics.saves)} />
                </div>
                <span className="mq-mono mq-muted">{row.item.url}</span>
              </article>
            ))}
          </div>
        </section>
      </div>
    );
  }

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