/* People — the workspace's own team, and one person's page.

   Commit model: INSTANT. Inviting somebody opens a staged dialog from this
   instant screen (three fields), and permissions are not edited here: role,
   approval limit and card issuing belong to /settings/team, which this screen
   links to rather than duplicating. One entry point per action.

   Data state: populated. Every figure is an array filtered by the person's id
   in metrics.js — their cards, their settled expenses, the payouts their name
   is on — so nothing about a person's work is stored on the person. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter, CardAction,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell,
    Button, Badge, Separator, Alert, AlertTitle, AlertDescription,
  } = window.OriginDesignSystem_7c998b;

  function PersonTile({ member, data, now, signedInId, onNavigate }) {
    const isSelf = member.id === signedInId;
    const cards = cardsHeldBy(data.cards, member).filter((c) => c.status !== "cancelled");
    const spend = spendBy(data.expenses, member);
    const owed = expensesBy(data.expenses, member).filter((e) => EXPENSE_FLAGS.waitsOnSpender(e, data.policy));
    const notes = data.comments.filter((c) => c.authorId === member.id).length;
    const accounts = customersOwnedBy(data.customers, member);
    return (
      <Card className="fd-card">
        <CardHeader>
          <CardTitle>
            <span className="fd-holder">
              <Face person={member} size={40} />
              <span className="fd-record">
                <span className="fd-record__name">{member.name}{member.id === signedInId ? " (you)" : ""}</span>
                <span className="fd-record__meta">{member.role}</span>
              </span>
            </span>
          </CardTitle>
          <CardAction><Badge size="sm" variant={member.teamRole === "member" ? "secondary" : "outline"}>{labelOf(TEAM_ROLES, member.teamRole)}</Badge></CardAction>
        </CardHeader>
        <CardPanel className="fd-stack">
          <dl className="fd-defs">
            <div><dt>Spend, last {CARD_WINDOW_DAYS} days</dt><dd>{formatMoney(spend)}</dd></div>
            <div><dt>Cards held</dt><dd>{cards.length ? cards.map((c) => c.label).join(", ") : "None"}</dd></div>
            <div><dt>Accounts owned</dt><dd>{accounts.length ? formatCount(accounts.length) : "None"}</dd></div>
            <div><dt>Can approve up to</dt><dd>{member.approvalLimit ? formatMoney(member.approvalLimit) : "Nothing"}</dd></div>
          </dl>
          {owed.length ? <span className="fd-waiting">{owed.length} of {isSelf ? "your" : "their"} expenses {owed.length === 1 ? "is" : "are"} waiting on a receipt from {isSelf ? "you" : "them"}.</span> : null}
        </CardPanel>
        <CardFooter className="fd-card-footer">
          <span className="fd-footnote">{notes ? notes + (notes === 1 ? " note" : " notes") + " written across the desk" : (isSelf ? "You have written no notes yet" : "No notes yet")}</span>
          <Button variant="outline" size="sm" onClick={() => onNavigate(recordRoute({ type: "member", id: member.id }))}>Open<Icon name="arrow-right" /></Button>
        </CardFooter>
      </Card>
    );
  }

  function PeopleScreen({ data, now, onNavigate, onInvite }) {
    const members = data.members;
    const canApprove = members.filter((m) => m.approvalLimit > 0);
    const spend = members.reduce((total, m) => total + spendBy(data.expenses, m), 0);
    const held = data.cards.filter((c) => c.status !== "cancelled");

    return (
      <div className="fd-page">
        <PageHeader
          path="/people"
          title="People"
          actions={<Button size="sm" onClick={onInvite}><Icon name="plus" />Invite teammate</Button>}
        />

        <div className="fd-metrics">
          <MetricTile icon="users" label="People" value={formatCount(members.length)} qualifier={canApprove.length + " of them can approve a payout; the other " + (members.length - canApprove.length) + " cannot"} />
          <MetricTile icon="credit-card" label="Cards in their hands" value={formatCount(held.length)} qualifier={(data.cards.length - held.length) + " cancelled " + (data.cards.length - held.length === 1 ? "card is" : "cards are") + " kept for the record"} />
          <MetricTile icon="receipt" label={"Spend, last " + CARD_WINDOW_DAYS + " days"} value={formatMoney(spend)} qualifier={settledExpenses(expensesInPeriod(data.expenses, CARD_WINDOW_DAYS, MERIDIAN_NOW)).length + " settled expenses across every card"} />
          <MetricTile icon="message-square" label="Notes waiting on a reply" value={formatCount(data.comments.filter((c) => c.mentions.some((id) => COMMENT_FLAGS.isAwaitingReply(c, id, data.comments))).length)} qualifier="Somebody was mentioned and has not answered on that record" />
        </div>

        <div className="fd-cardgrid">
          {members.map((member) => (
            <PersonTile key={member.id} member={member} data={data} now={now} signedInId={MERIDIAN_SIGNED_IN} onNavigate={onNavigate} />
          ))}
        </div>

        <Card>
          <CardFooter className="fd-card-footer">
            <span className="fd-footnote">Roles, approval limits and card issuing are edited together, so they live on one form.</span>
            <Button variant="outline" size="sm" onClick={() => onNavigate("/settings/team")}>Team and approvals<Icon name="arrow-right" /></Button>
          </CardFooter>
        </Card>
      </div>
    );
  }

  function PersonScreen({ data, now, memberId, onNavigate, onExpenseTransition, onPostComment }) {
    const member = data.members.find((m) => m.id === memberId);
    const self = member.id === MERIDIAN_SIGNED_IN;
    const cards = cardsHeldBy(data.cards, member);
    const expenses = expensesBy(data.expenses, member).slice().sort((a, b) => b.occurredAt - a.occurredAt);
    const settled = settledExpenses(expenses);
    const approvals = approvalsBy(data.payouts, member);
    const accounts = customersOwnedBy(data.customers, member);
    const owed = expenses.filter((e) => EXPENSE_FLAGS.waitsOnSpender(e, data.policy));

    return (
      <div className="fd-page">
        <PageHeader
          path="/people/:id"
          params={{ id: member.id }}
          title={member.name}
          actions={<Button variant="outline" size="sm" onClick={() => onNavigate(self ? "/settings/profile" : "/settings/team")}>{self ? "Edit your profile" : "Edit permissions"}</Button>}
        />

        {owed.length ? (
          <Alert variant="warning">
            <AlertTitle>{owed.length} {owed.length === 1 ? "expense is" : "expenses are"} waiting on {self ? "you" : member.name.split(" ")[0]}</AlertTitle>
            <AlertDescription>
              {formatMoney(sumBy(owed, "amount"))} cannot be approved by anybody until {self ? "you attach the receipts" : member.name.split(" ")[0] + " attaches the receipts"}. Those rows are recessed below — the work is {self ? "yours" : "theirs"}, not the reviewer's.
            </AlertDescription>
          </Alert>
        ) : null}

        <div className="fd-metrics">
          <MetricTile icon="receipt" label={"Spend, last " + CARD_WINDOW_DAYS + " days"} value={formatMoney(spendBy(data.expenses, member))} qualifier={settledExpenses(expensesInPeriod(expenses, CARD_WINDOW_DAYS, now)).length + " settled expenses on " + cards.filter((c) => c.status !== "cancelled").length + " live " + (cards.filter((c) => c.status !== "cancelled").length === 1 ? "card" : "cards")} />
          <MetricTile icon="check-check" label={self ? "Payouts you approved" : "Payouts they approved"} value={formatCount(approvals.length)} qualifier={approvals.length ? formatMoney(sumBy(approvals, "amount")) + " signed off in " + (self ? "your" : "their") + " name" : (self ? "Nothing has carried your name yet" : "Nothing has carried their name yet")} />
          <MetricTile icon="building-2" label="Accounts owned" value={formatCount(accounts.length)} qualifier={accounts.length ? formatMoney(accounts.reduce((t, c) => t + customerVolume(data.payments, c), 0)) + " of volume sits with " + (self ? "you" : "them") : "No customer accounts"} />
          <MetricTile icon="shield-check" label={self ? "You can approve up to" : "Can approve up to"} value={member.approvalLimit ? formatMoney(member.approvalLimit) : "Nothing"} qualifier={labelOf(TEAM_ROLES, member.teamRole) + " · " + (member.canIssueCards ? "can issue cards" : "cannot issue cards")} />
        </div>

        <div className="fd-columns">
          <div className="fd-col">
            <Card>
              <CardHeader>
                <CardTitle>What {self ? "you put" : "they put"} on a card</CardTitle>
                <CardDescription>Every expense of theirs, newest first. {settled.length} of {expenses.length} have settled.</CardDescription>
              </CardHeader>
              {expenses.length ? (
                <div className="fd-card-table">
                  <Table variant="card">
                    <TableHeader>
                      <TableRow>
                        <TableHead>Expense</TableHead>
                        <TableHead className="fd-drop-md">Card</TableHead>
                        <TableHead>Status</TableHead>
                        <TableHead className="fd-num">Amount</TableHead>
                        <TableHead className="fd-num fd-drop-lg">Occurred</TableHead>
                        <TableHead className="fd-actions-head">Action</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {expenses.map((expense) => {
                        const card = data.cards.find((c) => c.id === expense.cardId);
                        const waiting = EXPENSE_FLAGS.waitsOnSpender(expense, data.policy);
                        return (
                          <TableRow key={expense.id} className={waiting ? "fd-row--recessed" : ""}>
                            <TableCell>
                              <span className="fd-record">
                                <span className="fd-record__name">{expense.merchant}</span>
                                <span className="fd-record__meta">{labelOf(EXPENSE_CATEGORIES, expense.category)}</span>
                              </span>
                            </TableCell>
                            <TableCell className="fd-drop-md fd-muted">
                              <button type="button" className="fd-link" onClick={() => onNavigate(recordRoute({ type: "card", id: card.id }))}>{card.label}</button>
                            </TableCell>
                            <TableCell>
                              <span className="fd-status">
                                <StatusBadge values={EXPENSE_STATUS} value={expense.status} />
                                {EXPENSE_FLAGS.needsReceipt(expense, data.policy) ? <Badge size="sm" variant="warning">No receipt</Badge> : null}
                              </span>
                            </TableCell>
                            <TableCell className="fd-num fd-amount">{formatMoney(expense.amount)}</TableCell>
                            <TableCell className="fd-num fd-muted fd-drop-lg" title={formatAbsolute(expense.occurredAt)}>{formatWhen(expense.occurredAt, now)}</TableCell>
                            <TableCell className="fd-actions">
                              <RowActions transitions={expenseTransitions(expense, data.policy)} onRun={(t) => onExpenseTransition(expense, t)} label={"Actions for " + expense.id} />
                            </TableCell>
                          </TableRow>
                        );
                      })}
                    </TableBody>
                  </Table>
                </div>
              ) : (
                <CardPanel><span className="fd-footnote">They have never put anything on a card.</span></CardPanel>
              )}
              <CardFooter className="fd-card-footer">
                <span className="fd-footnote">{expenses.length} expenses · {expenses.filter((e) => e.status === "needs_review").length} still in review.</span>
                <Button variant="ghost" size="sm" onClick={() => onNavigate("/expenses")}>All expenses<Icon name="arrow-right" /></Button>
              </CardFooter>
            </Card>

            <ThreadCard
              record={{ type: "member", id: member.id }}
              data={data}
              signedInId={MERIDIAN_SIGNED_IN}
              now={now}
              onPost={onPostComment}
              description={self ? "Notes about your own work — handovers, cover, anything the records do not say." : "Handover notes about " + member.name.split(" ")[0] + "'s work. Mention somebody to put it in their queue."}
            />
          </div>

          <div className="fd-col">
            <Card className="fd-card">
              <CardHeader>
                <CardTitle>The person</CardTitle>
                <CardDescription>{member.role}</CardDescription>
              </CardHeader>
              <CardPanel className="fd-stack">
                <span className="fd-holder">
                  <Face person={member} size={40} />
                  <span className="fd-record">
                    <span className="fd-record__name">{member.name}{self ? " (you)" : ""}</span>
                    <span className="fd-record__meta">{member.email}</span>
                  </span>
                </span>
                <dl className="fd-defs">
                  <div><dt>Permission</dt><dd>{labelOf(TEAM_ROLES, member.teamRole)}</dd></div>
                  <div><dt>Approval limit</dt><dd>{member.approvalLimit ? formatMoney(member.approvalLimit) : "Cannot approve"}</dd></div>
                  <div><dt>Card issuing</dt><dd>{member.canIssueCards ? "Allowed" : "Not allowed"}</dd></div>
                  <div><dt>Email alerts</dt><dd>{member.notify.length ? member.notify.length + " of " + NOTIFICATION_KINDS.length + " kinds" : "None"}</dd></div>
                </dl>
              </CardPanel>
            </Card>

            {cards.length ? (
              <Card className="fd-card">
                <CardHeader>
                  <CardTitle>Cards in {self ? "your" : "their"} name</CardTitle>
                  <CardDescription>Each meter is spend against its own {CARD_WINDOW_DAYS}-day limit.</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="fd-picklist">
                    {cards.map((card) => {
                      const use = cardUtilisation(card, data.expenses, now, data.policy);
                      return (
                        <button type="button" className="fd-pick" key={card.id} onClick={() => onNavigate(recordRoute({ type: "card", id: card.id }))}>
                          <span className="fd-list__main">
                            <span className="fd-record__name">{card.label}</span>
                            <span className="fd-record__meta"><span className="fd-pan">•••• {card.last4}</span> · {labelOf(CARD_TYPES, card.type)}</span>
                          </span>
                          <span className="fd-list__side">
                            <span className="fd-amount">{formatMoney(use.spent)}</span>
                            <span className="fd-clock">of {formatMoney(use.limit)}</span>
                          </span>
                          <span className="fd-pick__foot"><StatusBadge values={CARD_STATUS} value={card.status} /></span>
                        </button>
                      );
                    })}
                  </div>
                </CardPanel>
              </Card>
            ) : null}

            {accounts.length ? (
              <Card className="fd-card">
                <CardHeader>
                  <CardTitle>Accounts {self ? "you own" : "they own"}</CardTitle>
                  <CardDescription>{formatMoney(accounts.reduce((t, c) => t + customerVolume(data.payments, c), 0))} of volume across {accounts.length}.</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="fd-picklist">
                    {customersByVolume(accounts, data.payments).map((customer) => (
                      <button type="button" className="fd-pick" key={customer.id} onClick={() => onNavigate(recordRoute({ type: "customer", id: customer.id }))}>
                        <span className="fd-list__main">
                          <span className="fd-record__name">{customer.name}</span>
                          <span className="fd-record__meta">{customer.contact.name}</span>
                        </span>
                        <span className="fd-list__side">
                          <span className="fd-amount">{formatMoney(customerVolume(data.payments, customer))}</span>
                        </span>
                        <span className="fd-pick__foot"><StatusBadge values={CUSTOMER_STATUS} value={customer.status} /></span>
                      </button>
                    ))}
                  </div>
                </CardPanel>
              </Card>
            ) : null}
          </div>
        </div>
      </div>
    );
  }

  Object.assign(window, { PeopleScreen, PersonScreen });
})();
