/* One application, read properly — the screen this product exists for.
   Instant commit model: the stage moves, the watch toggle and the notes apply
   immediately; consequential ones raise an undo toast; declining opens a staged
   dialog and then a confirm. The header's actions are whatever the record's
   stage allows (transitionsFor) — never a fixed set.
   The panel, checks and offer sections render only when the record has reached
   them or holds their sub-records: one data state per screen. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Button, Badge, Avatar, Alert, AlertTitle, AlertDescription, Separator, Progress, MenuItem,
  } = window.OriginDesignSystem_7c998b;

  function OfferPanel({ application, requisition, now }) {
    const offer = application.offer;
    const position = bandPosition(requisition, offer.salaryMinor);
    const left = daysBetween(now, offer.expiresAt);
    return (
      <Card>
        <CardHeader>
          <CardTitle>Offer</CardTitle>
          <CardDescription>
            {offer.acceptedAt
              ? "Accepted " + formatDay(offer.acceptedAt) + ", starting " + formatDay(offer.startAt) + "."
              : "Sent " + formatDay(offer.sentAt) + " and valid to " + formatDay(offer.expiresAt) + " — " + durationWords(left) + "."}
          </CardDescription>
        </CardHeader>
        <CardPanel>
          <div className="rd-stack">
            <span className="rd-part">
              <span className="rd-spread">
                <span className="rd-anchor__figure" style={{ fontSize: "var(--text-2xl)" }}>{money(offer.salaryMinor)}</span>
                <span className="rd-foot">{percent(position)} up the band</span>
              </span>
              <Bar ratio={position} />
              <span className="rd-foot">Band {bandLabel(requisition)} on {requisition.ref}.</span>
            </span>
            <KeyValues items={[
              { label: "Start date", value: formatDay(offer.startAt) },
              { label: "Expires", value: formatDay(offer.expiresAt), note: offer.acceptedAt ? "Answered before it ran out" : durationWords(left) },
              { label: "Expectation", value: application.salaryExpectationMinor ? money(application.salaryExpectationMinor) : "Not stated",
                note: application.salaryExpectationMinor ? (offer.salaryMinor >= application.salaryExpectationMinor ? "Met" : money(application.salaryExpectationMinor - offer.salaryMinor) + " below what they asked") : null },
            ]} />
            {offer.note ? <p className="rd-quote">{offer.note}</p> : null}
          </div>
        </CardPanel>
      </Card>
    );
  }

  function ChecksPanel({ application, data, now, onRun }) {
    const refs = referenceState(application);
    const missing = checksMissing(application);
    return (
      <Card>
        <CardHeader>
          <CardTitle>Checks</CardTitle>
          <CardDescription>
            {refs.received} of {refs.required} references back · right to work {statusWords(RIGHT_TO_WORK, application.rightToWork)} · DBS {statusWords(DBS_STATUS, application.dbs)}.
          </CardDescription>
        </CardHeader>
        <CardPanel>
          <div className="rd-stack">
            {missing.length ? (
              <Alert variant="warning">
                <Icon name="clock" size={16} />
                <AlertTitle>An offer waits on {plural(missing.length, "thing", "things")}</AlertTitle>
                <AlertDescription>{missing.join(" · ")}. Nothing here is ours to hurry except the chasing.</AlertDescription>
              </Alert>
            ) : (
              <Alert variant="success">
                <Icon name="circle-check" size={16} />
                <AlertTitle>Everything is in</AlertTitle>
                <AlertDescription>Both references, right to work verified and a clear DBS. The offer is the desk's to send.</AlertDescription>
              </Alert>
            )}
            <div className="rd-list">
              {refs.refs.map((reference) => (
                <div className="rd-list__row" key={reference.id}>
                  <div className="rd-list__main">
                    <span className="rd-record__name">{reference.name}</span>
                    <span className="rd-record__meta">{reference.relationship}</span>
                    {reference.note ? <p className="rd-quote">{reference.note}</p> : null}
                  </div>
                  <div className="rd-list__side">
                    <StatusBadge values={REFERENCE_STATUS} value={reference.status} />
                    <span className="rd-clock" title={formatAbsolute(reference.requestedAt)}>
                      {reference.receivedAt ? "Back " + formatDayShort(reference.receivedAt) : "Asked " + formatDayShort(reference.requestedAt)}
                    </span>
                    {reference.status !== "received" ? <Button variant="outline" size="xs" onClick={() => onRun(reference)}>Chase</Button> : null}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </CardPanel>
      </Card>
    );
  }

  function ApplicationScreen({ application, data, now, session, onNavigate, onApplicationTransition, onInterviewTransition, onPostNote, onReact, onToggleWatch, onChaseReference }) {
    const me = staffById(data.staff, session.personId);
    const requisition = requisitionById(data.requisitions, application.requisitionId);
    const owner = staffById(data.staff, application.ownerId);
    const score = scoresOf(application);
    const interviews = interviewsFor(data.interviews, application.id);
    const thread = threadFor(data.notes, application.id);
    const followers = followersOf(application, data.notes, data.staff);
    const watching = (application.watcherIds || []).indexOf(me.id) > -1;
    const [replyingTo, setReplyingTo] = React.useState(null);
    const transitions = transitionsFor(application);
    const reachedChecks = stageIndex(application.stage) >= stageIndex("checks") || (application.references || []).length > 0;
    const c = application.candidate;

    return (
      <div className="rd-page">
        <PageHead path="/applications/:id" params={{ id: application.id }} labels={{ "/applications/:id": c.name }}
          title={c.name} note={requisition.title + " · " + requisition.ref + " · applied " + formatDay(application.appliedAt) + " through " + labelOf(SOURCES, application.source).toLowerCase()} />

        <Card>
          <div className="rd-cover">
            <div className="rd-cover__body">
              <div className="rd-cover__id">
                <Avatar size={88} src={c.photo} alt="" fallback={c.initials} />
                <div className="rd-cover__text">
                  <span className="rd-cover__name">{c.name}</span>
                  <span className="rd-cover__meta">
                    <span>{c.headline}</span>
                    <span>· {c.location}</span>
                    {application.registration ? <span>· {application.registration}</span> : null}
                  </span>
                  <span className="rd-status">
                    <StatusBadge values={APPLICATION_STAGE} value={application.stage} />
                    <StatusBadge values={RIGHT_TO_WORK} value={application.rightToWork} />
                    {APPLICATION_FLAGS.isStalled(application, now) ? <Badge size="sm" variant="warning">{plural(stageOverBy(application, now), "day", "days")} over its service level</Badge> : null}
                  </span>
                </div>
              </div>
              <div className="rd-cover__actions">
                <Button variant={watching ? "outline" : "ghost"} size="sm" aria-pressed={watching} onClick={() => onToggleWatch(application)}>
                  <Icon name={watching ? "eye-off" : "eye"} size={14} />{watching ? "Stop watching" : "Watch"}
                </Button>
                <RowActions transitions={transitions} onRun={(t) => onApplicationTransition(application, t)} label={"Actions for " + c.name}
                  extra={(close) => <MenuItem onClick={() => { close(); onNavigate("/requisitions/" + requisition.id); }}>Open the requisition</MenuItem>} />
              </div>
            </div>
          </div>
          <CardPanel>
            <div className="rd-stack">
              <Stepper application={application} data={data} now={now} />
              <StageNote application={application} data={data} now={now} />
              <Followers people={followers} />
            </div>
          </CardPanel>
        </Card>

        <div className="rd-columns">
          <div className="rd-col">
            {score.count ? (
              <Card>
                <CardHeader>
                  <CardTitle>Panel scorecards</CardTitle>
                  <CardDescription>
                    {plural(score.count, "scorecard", "scorecards")} of {score.required} · {score.average.toFixed(2)} average · {score.yeses} recommending yes.
                  </CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="rd-stack">
                    {score.complete ? null : (
                      <Alert variant="warning">
                        <Icon name="triangle-alert" size={16} />
                        <AlertTitle>One more scorecard before this can move</AlertTitle>
                        <AlertDescription>
                          {score.required} are needed from different people. {firstNameOf(staffById(data.staff, score.cards[0].byId))} has filed hers; the panel's other seat has not.
                        </AlertDescription>
                      </Alert>
                    )}
                    <ScoreMatrix application={application} data={data} />
                    <Separator />
                    {score.cards.map((card) => {
                      const author = staffById(data.staff, card.byId);
                      return (
                        <div className="rd-note" key={card.byId}>
                          <Avatar size={32} src={author.photo} alt="" fallback={author.initials} />
                          <div className="rd-note__body">
                            <div className="rd-note__head">
                              <span className="rd-note__who">{author.name}</span>
                              <span className="rd-note__role">{author.title}</span>
                              <Badge size="sm" variant={card.recommend === "yes" ? "success" : "warning"}>{card.recommend === "yes" ? "Recommends" : "Not sure"}</Badge>
                              <span className="rd-note__at" title={formatAbsolute(card.at)}>{formatWhen(card.at, now)}</span>
                            </div>
                            <p className="rd-note__text">{card.note}</p>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </CardPanel>
              </Card>
            ) : null}

            {reachedChecks ? <ChecksPanel application={application} data={data} now={now} onRun={onChaseReference} /> : null}

            <Card>
              <CardHeader>
                <CardTitle>The thread</CardTitle>
                <CardDescription>
                  {plural(notesFor(data.notes, application.id).length, "note", "notes")} from {plural(followers.length, "person", "people")}. The candidate never sees any of it.
                </CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="rd-thread">
                  {thread.length ? null : (
                    <p className="rd-foot">
                      Nothing on the thread yet. The first note is usually why this one is worth reading —
                      who referred them, what stood out in the CV, or what somebody else should check.
                    </p>
                  )}
                  {thread.map(({ note, replies }) => (
                    <React.Fragment key={note.id}>
                      <Note note={note} staff={data.staff} me={me} now={now} onReact={onReact} onReply={setReplyingTo} />
                      {replies.map((reply) => (
                        <Note key={reply.id} note={reply} staff={data.staff} me={me} now={now} reply onReact={onReact} />
                      ))}
                    </React.Fragment>
                  ))}
                  <Composer me={me} staff={data.staff} replyingTo={replyingTo} onCancelReply={() => setReplyingTo(null)}
                    onPost={(body, kind, parent) => { onPostNote(application, body, kind, parent); setReplyingTo(null); }} />
                </div>
              </CardPanel>
            </Card>
          </div>

          <div className="rd-col">
            <Card>
              <CardHeader><CardTitle>The application</CardTitle></CardHeader>
              <CardPanel>
                <div className="rd-stack">
                  <KeyValues items={[
                    { label: "Applied", value: formatDay(application.appliedAt), note: plural(daysSinceApplied(application, now), "day", "days") + " with us" },
                    { label: "Source", value: labelOf(SOURCES, application.source), note: application.referredById ? "Referred by " + staffById(data.staff, application.referredById).name : null },
                    { label: "Owner", value: owner ? owner.name : "Unassigned" },
                    { label: "First read", value: application.firstReadAt ? formatWhen(application.firstReadAt, now) : "Not yet", note: application.firstReadAt ? null : "It counts as unread on the desk" },
                  ]} />
                  <Separator />
                  <span className="rd-part">
                    <span className="rd-kv__label">Expectation against the band</span>
                    {application.salaryExpectationMinor ? (
                      <>
                        <span className="rd-spread">
                          <span className="rd-kv__value">{money(application.salaryExpectationMinor)}</span>
                          <span className="rd-foot">{bandLabel(requisition)}</span>
                        </span>
                        <Bar ratio={bandPosition(requisition, application.salaryExpectationMinor)}
                          tone={application.salaryExpectationMinor > requisition.bandMinor[1] ? "warn" : null} />
                        <span className="rd-foot">
                          {application.salaryExpectationMinor > requisition.bandMinor[1]
                            ? money(application.salaryExpectationMinor - requisition.bandMinor[1]) + " above the top of the band — it has to be settled before an offer."
                            : percent(bandPosition(requisition, application.salaryExpectationMinor)) + " up the band, which the seat can pay."}
                        </span>
                      </>
                    ) : <span className="rd-foot">Not stated on the application.</span>}
                  </span>
                </div>
              </CardPanel>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Documents</CardTitle>
                <CardDescription>{plural(application.documents.length, "file", "files")} on the record.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="rd-list">
                  {application.documents.map((document) => (
                    <div className="rd-list__row" key={document.name}>
                      <div className="rd-list__main">
                        <span className="rd-record__name">{document.name}</span>
                        <span className="rd-record__meta">{document.kind === "cv" ? "CV" : document.kind === "case" ? "Assessment response" : "Supporting statement"}</span>
                      </div>
                      <div className="rd-list__side">
                        <span className="rd-clock" title={formatAbsolute(document.at)}>{formatWhen(document.at, now)}</span>
                        <Button variant="outline" size="xs"><Icon name="download" size={12} />Download</Button>
                      </div>
                    </div>
                  ))}
                </div>
              </CardPanel>
            </Card>

            {interviews.length ? (
              <Card>
                <CardHeader>
                  <CardTitle>Interviews</CardTitle>
                  <CardDescription>{plural(interviews.length, "conversation", "conversations")} booked on this application.</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="rd-list">
                    {interviews.map((interview) => (
                      <div className="rd-list__row" key={interview.id}>
                        <div className="rd-list__main">
                          <span className="rd-record__name">{statusValue(APPLICATION_STAGE, interview.kind === "screening" ? "screening" : interview.kind === "panel" ? "panel" : "assessment").label} · {formatWeekday(interview.at)} {formatTime(interview.at)}</span>
                          <span className="rd-record__meta">{interview.where} · {panelOf(data.staff, interview).map((p) => p.name).join(", ")}</span>
                          {interview.note ? <p className="rd-quote">{interview.note}</p> : null}
                        </div>
                        <div className="rd-list__side">
                          <StatusBadge values={INTERVIEW_STATUS} value={interview.status} />
                          <RowActions transitions={interviewTransitions(interview)} onRun={(t) => onInterviewTransition(interview, t)} label={"Actions for the " + interview.kind} />
                        </div>
                      </div>
                    ))}
                  </div>
                </CardPanel>
              </Card>
            ) : null}

            {application.offer ? <OfferPanel application={application} requisition={requisition} now={now} /> : null}
          </div>
        </div>
      </div>
    );
  }

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