/* Brand — the client's file. The record behind every brand name on a brief, a
   deal, an invoice and an exclusivity clause.
   Commit model: INSTANT. Nothing here commits: it is a document that navigates.
   Chasing an invoice belongs to the money ledger and passing on a brief to the
   briefs desk, so each action keeps exactly one entry point in the product.
   Data state: populated. A brand exists here because something names it; the
   sections whose arrays are empty say so in a sentence rather than rendering a
   second state beside the first.
   Actions derive from the record: a brand with an open brief is offered it, a
   brand holding an exclusivity says whose, and a brand with nothing on the desk
   is offered neither — the control is omitted, never disabled.
   Primary display: a document read top to bottom. What they ask for, what they
   have run, what they owe, what we owe them.
   Nothing about a brand is stored except its name, sector and city: every
   figure below is read off the briefs, deals and invoices that name it. */
(() => {
  const { Button, Badge, Separator, Alert, AlertTitle, AlertDescription, AlertAction } = window.OriginDesignSystem_7c998b;

  function BriefRow({ brief, now, onNavigate }) {
    const open = BRIEF_FLAGS.isOpen(brief);
    return (
      <div className="mq-tl__item" data-live={brief.status === "won" ? "yes" : "no"}>
        <span className="mq-tl__when" title={formatAbsolute(brief.receivedAt)}>{formatAbsolute(brief.receivedAt).split(",")[0]}</span>
        <div className="mq-tl__main">
          <button type="button" className="mq-link mq-tl__title" onClick={() => onNavigate("/briefs/" + brief.id)}>{brief.title}</button>
          <span className="mq-row__meta">
            {brief.id} · {formatMoney(brief.budgetCents)} · {labelOf(CATEGORIES, brief.category)} · {briefUnits(brief)} pieces
            {brief.status === "passed" ? " · we passed: " + labelOf(PASS_REASONS, brief.passReason).toLowerCase() : ""}
            {brief.status === "lost" ? " · lost" : ""}
          </span>
        </div>
        <div className="mq-tl__side">
          <StatusBadge values={BRIEF_STATUS} value={brief.status} />
          {open
            ? <span className="mq-mono mq-warn" title={formatAbsolute(brief.respondByAt)}>{formatCountdown(brief.respondByAt, now)}</span>
            : <span className="mq-mono mq-muted">{brief.contact.name}</span>}
        </div>
      </div>
    );
  }

  function CampaignRow({ deal, creator, now, onNavigate }) {
    const index = deliveryIndex(deal);
    const state = campaignState(deal);
    const rightsEnd = RIGHTS_FLAGS.endsAt(deal);
    const expiring = RIGHTS_FLAGS.isExpiring(deal, now);
    return (
      <div className="mq-tl__item" data-live={state === "complete" ? "yes" : "no"}>
        <span className="mq-tl__when" title={formatAbsolute(deal.agreedAt)}>{formatAbsolute(deal.agreedAt).split(",")[0]}</span>
        <div className="mq-tl__main">
          <button type="button" className="mq-link mq-tl__title" onClick={() => onNavigate("/deals/" + deal.id)}>{deal.title} · {creator.name}</button>
          <span className="mq-row__meta">
            {formatMoney(deal.feeCents)} · {publishedOf(deal).length} of {deal.deliverables.length} pieces live · {usageOf(deal.usage).label.toLowerCase()}
            {rightsEnd === null ? "" : ", rights " + (RIGHTS_FLAGS.hasLapsed(deal, now) ? "lapsed " : "run to ") + formatAbsolute(rightsEnd).split(",")[0]}
          </span>
          {expiring ? <span className="mq-note mq-warn">{formatCountdown(rightsEnd, now)} on the usage window — renew it or the ads come down.</span> : null}
        </div>
        <div className="mq-tl__side">
          <StatusBadge values={CONTRACT_STATUS} value={deal.contract.status} />
          {index === null
            ? <span className="mq-mono mq-muted">{state === "not_started" ? "Nothing live" : "In flight"}</span>
            : <button type="button" className={"mq-link mq-mono " + (index >= 1 ? "mq-good" : "mq-warn")} onClick={() => onNavigate("/performance/" + deal.id)}>{formatPercent(index)} of promise</button>}
        </div>
      </div>
    );
  }

  function BrandScreen({ brand, data, now, onNavigate, pushToast }) {
    const briefs = briefsForBrand(data.briefs, brand);
    const open = briefs.filter(BRIEF_FLAGS.isOpen);
    const won = briefs.filter((b) => b.status === "won");
    const deals = dealsForBrand(data.deals, brand);
    const invoices = invoiceRows(deals);
    const overdue = invoicesOverdue(invoices, now);
    const outstanding = invoicesOutstanding(invoices);
    const banked = invoicesPaid(invoices);
    const habit = brandDaysToPay(data.deals, brand);
    const rate = brandWinRate(data.briefs, brand);
    const owedTo = exclusivitiesTo(data.creators, brand, now);
    const outside = outsideBookings(data.creators, brand);
    const firstAt = brandFirstBriefAt(data.briefs, brand);
    const blockedPayouts = payoutsBlocked(payoutRows(deals, data.creators));
    const expiring = deals.filter((d) => RIGHTS_FLAGS.isExpiring(d, now));

    return (
      <div className="mq-page mq-page--tight">
        <RecordHead
          crumb={<Crumbs path="/brands/:id" params={{ id: brand.id }} labels={{ "/brands/:id": brand.name }} />}
          id={labelOf(CATEGORIES, brand.sector) + " · " + brand.hq + (firstAt ? " · first brief " + formatAbsolute(firstAt).split(",")[0] : " · no brief on this desk")}
          status={deals.length ? <Badge size="sm" variant="secondary">{deals.length} {deals.length === 1 ? "campaign" : "campaigns"}</Badge> : null}
          title={brand.name}
          lede={brand.note}
          actions={
            <div className="mq-actions__row">
              {open.length ? <Button size="sm" onClick={() => onNavigate("/briefs/" + open[0].id)}>Open the live brief<Icon name="arrow-right" /></Button> : null}
              <ExportMenu scope={brand.name} onExport={(format) => pushToast({ title: "Export started", description: brand.name + " · " + format + " — briefs, campaigns and every invoice they have had." })} />
            </div>
          }
        />

        {overdue.length ? (
          <Alert variant="error">
            <AlertTitle>{brand.name} is {INVOICE_FLAGS.daysOverdue(overdue[0].invoice, now)} days past due on {formatMoney(moneyTotal(overdue))}</AlertTitle>
            <AlertDescription>
              {overdue.map((r) => r.invoice.id + " was due " + formatAbsolute(INVOICE_FLAGS.dueAt(r.invoice)).split(",")[0]).join(" · ")}.
              {blockedPayouts.length ? " " + blockedPayouts.map((r) => r.creator.name.split(" ")[0] + "'s " + formatMoney(r.amount)).join(" and ") + " cannot move until it lands." : ""}
            </AlertDescription>
            <AlertAction><Button variant="outline" size="sm" onClick={() => onNavigate("/money")}>Open the ledger</Button></AlertAction>
          </Alert>
        ) : null}

        <div className="mq-split">
          <div className="mq-col">
            <section className="mq-section">
              <div className="mq-section__head">
                <h2 className="mq-h2">Briefs<span className="mq-tab-count">{briefs.length}</span></h2>
                <p className="mq-note">
                  {briefs.length === 0
                    ? "Nothing has come in from " + brand.name + " on this desk. They are on file because " + (owedTo.length ? "we owe them an exclusivity." : "they booked one of our creators direct.")
                    : rate === null
                      ? open.length + " open, and no brief from them has been decided yet."
                      : formatPercent(rate.rate) + " of the " + rate.decided.length + " " + (rate.decided.length === 1 ? "brief" : "briefs") + " they have had an answer on became a deal" + (open.length ? ", and " + open.length + " " + (open.length === 1 ? "is" : "are") + " still open." : ".")}
                </p>
              </div>
              {briefs.length ? (
                <>
                  <div className="mq-tl">
                    {briefs.map((brief) => <BriefRow key={brief.id} brief={brief} now={now} onNavigate={onNavigate} />)}
                  </div>
                  <div className="mq-foot">
                    <span>{formatMoney(briefValue(briefs))} of budget across {briefs.length} {briefs.length === 1 ? "brief" : "briefs"} · {formatMoney(briefValue(won))} of it won</span>
                    <span>Oldest {formatAbsolute(briefs[briefs.length - 1].receivedAt).split(",")[0]}, newest {formatAbsolute(briefs[0].receivedAt).split(",")[0]}</span>
                  </div>
                </>
              ) : null}
            </section>

            <section className="mq-section">
              <div className="mq-section__head">
                <h2 className="mq-h2">Campaigns<span className="mq-tab-count">{deals.length}</span></h2>
                <p className="mq-note">
                  {deals.length === 0
                    ? "No campaign has run through the desk for " + brand.name + "."
                    : completeDeals(deals).length
                      ? completeDeals(deals).length + " of " + deals.length + " ran to completion, and only those are measured against what we promised them."
                      : "Nothing has finished running, so there is no promise to judge yet."}
                </p>
              </div>
              {deals.length ? (
                <>
                  <div className="mq-tl">
                    {deals.map((deal) => <CampaignRow key={deal.id} deal={deal} creator={creatorById(data.creators, deal.creatorId)} now={now} onNavigate={onNavigate} />)}
                  </div>
                  <div className="mq-foot">
                    <span>{formatMoney(sumBy(deals, "feeCents"))} of fees · {formatMoney(sumOf(deals, commissionOf))} of it ours</span>
                    <span>{expiring.length ? expiring.length + " usage " + (expiring.length === 1 ? "window" : "windows") + " ends inside " + AGENCY_POLICY.rightsNoticeDays + " days" : "No usage window ends inside " + AGENCY_POLICY.rightsNoticeDays + " days"}</span>
                  </div>
                </>
              ) : null}
            </section>
          </div>

          <div className="mq-col">
            <section className="mq-section">
              <div className="mq-section__head"><h2 className="mq-h2">Money</h2></div>
              <div className="mq-sheet mq-sheet--tight">
                {deals.length === 0 ? (
                  <p className="mq-note">No campaign, so no invoice and no commission. A zero here would be a figure about nothing.</p>
                ) : (
                  <>
                    <div className="mq-lg">
                      <LedgerRow label="Billed" hint={invoices.length + " " + (invoices.length === 1 ? "invoice" : "invoices") + " across " + deals.length + " " + (deals.length === 1 ? "campaign" : "campaigns")} value={formatMoney(moneyTotal(invoices))} />
                      <LedgerRow label="Banked" hint={banked.length ? banked.length + " settled, latest " + formatAbsolute(banked.slice().sort((a, b) => b.invoice.paidAt - a.invoice.paidAt)[0].invoice.paidAt).split(",")[0] : "Nothing settled yet"} value={banked.length ? formatMoney(moneyTotal(banked)) : <span className="mq-muted">Nothing yet</span>} />
                      <LedgerRow label="Outstanding" hint={outstanding.length ? outstanding.map((r) => r.invoice.id + " — " + statusValue(INVOICE_STATUS, r.invoice.status).label.toLowerCase()).join(", ") : "Nothing owed"} value={outstanding.length ? <span className={overdue.length ? "mq-bad" : ""}>{formatMoney(moneyTotal(outstanding))}</span> : <span className="mq-muted">Nothing</span>} />
                      <LedgerRow label="Commission from them" hint={banked.length ? "Only on invoices they have actually paid" : "Commission on an unpaid invoice is a hope, not revenue"} value={banked.length ? formatMoney(commissionBanked(invoices)) : <span className="mq-muted">Nothing banked</span>} variant="net" />
                    </div>
                    <p className="mq-note">
                      {habit === null
                        ? "They have never settled an invoice with us, so there is no habit to read. Terms are net " + AGENCY_POLICY.paymentTermsDays + " from issue."
                        : "They take " + habit.days + " days to pay on average across " + habit.rows.length + " settled " + (habit.rows.length === 1 ? "invoice" : "invoices") + ", against terms of net " + AGENCY_POLICY.paymentTermsDays + "."}
                    </p>
                  </>
                )}
              </div>
            </section>

            <section className="mq-section">
              <div className="mq-section__head"><h2 className="mq-h2">What we owe them</h2></div>
              <div className="mq-sheet mq-sheet--tight">
                <div className="mq-col mq-col--tight">
                  <Eyebrow>Exclusivity</Eyebrow>
                  {owedTo.length === 0 ? (
                    <p className="mq-note">Nothing. No creator on the book is held to {brand.name} in any category, so every brief they send can be matched against the whole roster.</p>
                  ) : owedTo.map((row) => (
                    <p className="mq-note" key={row.creator.id + row.exclusivity.category}>
                      <button type="button" className="mq-link" onClick={() => onNavigate("/talent/" + row.creator.id)}><strong>{row.creator.name}</strong></button> is theirs in {labelOf(CATEGORIES, row.exclusivity.category).toLowerCase()} until {formatAbsolute(row.exclusivity.until).split(",")[0]} — {formatCountdown(row.exclusivity.until, now)}. Signed {formatAbsolute(row.exclusivity.signedAt).split(",")[0]}.
                    </p>
                  ))}
                </div>
                {outside.length ? (
                  <>
                    <Separator />
                    <div className="mq-col mq-col--tight">
                      <Eyebrow>Booked outside the desk</Eyebrow>
                      {outside.map((creator) => (
                        <p className="mq-note" key={creator.id}>
                          <button type="button" className="mq-link" onClick={() => onNavigate("/talent/" + creator.id)}><strong>{creator.name}</strong></button> is with them until {formatAbsolute(creator.bookedUntil).split(",")[0]} on a campaign that predates this desk, so there is no deal, no invoice and no commission on it here.
                        </p>
                      ))}
                    </div>
                  </>
                ) : null}
              </div>
            </section>

            <section className="mq-section">
              <div className="mq-section__head"><h2 className="mq-h2">Who we deal with</h2></div>
              <div className="mq-sheet mq-sheet--tight">
                {briefs.length === 0 ? (
                  <p className="mq-note">No brief, so nobody on their side is on file. The contact comes in with the brief.</p>
                ) : (
                  <dl className="mq-specs">
                    {briefs
                      .filter((b, i) => briefs.findIndex((x) => x.contact.name === b.contact.name) === i)
                      .map((b) => (
                        <React.Fragment key={b.contact.name}>
                          <dt>{b.contact.role}</dt>
                          <dd>{b.contact.name} — last brief {formatAbsolute(b.receivedAt).split(",")[0]}, {b.id}</dd>
                        </React.Fragment>
                      ))}
                  </dl>
                )}
              </div>
            </section>
          </div>
        </div>
      </div>
    );
  }

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