/* Receipt — the one page a guest sends to somebody else. Every other screen in
   Lodestay is for choosing or arriving; this is the document that says what was
   charged, on which card, and what the policy was.
   Commit model: none. There is not a control on it except Download, which
   changes nothing.
   Data state: one branch. A booking with movements gets the receipt; a booking
   with none gets the designed state that says why — a request the host has not
   answered has taken nothing, and a declined one never will.
   Every figure is quoteForBooking and the booking's own payment rows: the same
   two things the trip screen and the checkout print, so a receipt can never
   disagree with the screen it was opened from. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell, TableFooter,
    Button, Separator, Alert, AlertTitle, AlertDescription,
  } = window.OriginDesignSystem_7c998b;

  function Fact({ label, children }) {
    return (
      <div className="ls-rc__fact">
        <span className="ls-rc__label">{label}</span>
        <span className="ls-rc__value">{children}</span>
      </div>
    );
  }

  function ReceiptScreen({ booking, data, user, onNavigate, pushToast }) {
    const now = data.now;
    const listing = listingById(data.listings, booking.listingId);
    const host = hostById(data.hosts, booking.hostId);
    const quote = quoteForBooking(booking);
    const lines = quoteLines(quote);
    const payments = paymentsOf(booking);
    const paid = paidCents(booking);
    const refunded = refundedCents(booking);
    const owed = owedCents(booking);
    const policy = policyOf(booking.cancelPolicy);
    const nights = nightsBetween(booking.checkIn, booking.checkOut);
    /* A receipt is issued when money first moved; before that there is nothing
       to date it by, so it carries the booking's own date instead. */
    const settled = paidPayments(booking).slice().sort((a, b) => a.paidAt - b.paidAt)[0];
    const issuedAt = settled ? settled.paidAt : booking.bookedAt;
    const guest = user;

    const head = (
      <PageHead
        path="/trips/:id/receipt"
        params={{ id: booking.id }}
        labels={{ "/trips/:id": listing.name, "/trips/:id/receipt": "Receipt" }}
        onNavigate={onNavigate}
        title={"Receipt " + booking.reference}
        lede={listing.name + " · " + formatDayFull(booking.checkIn) + " to " + formatDayFull(booking.checkOut) + " · charged to " + guest.name}
        actions={payments.length ? (
          <Button variant="outline" onClick={() => pushToast({ title: "Receipt downloaded", description: booking.reference + " · " + formatPrice(paid - refunded) + " charged to " + guest.name + "." })}>
            <Icon name="download" size={16} />Download
          </Button>
        ) : null}
      />
    );

    if (!payments.length) {
      return (
        <div className="ls-page">
          {head}
          <Alert>
            <Icon name="receipt" size={16} />
            <AlertTitle>There is nothing to receipt yet</AlertTitle>
            <AlertDescription>
              {booking.status === "requested"
                ? host.name.split(" ")[0] + " has not answered the request, so no money has moved. The card is only charged when a host accepts — " + formatPrice(quote.total) + " for " + nights + " " + (nights === 1 ? "night" : "nights") + "."
                : "This request was never accepted, so nothing was ever taken from the card."}
            </AlertDescription>
          </Alert>
          <div>
            <Button variant="outline" onClick={() => onNavigate("/trips/" + booking.id)}>Back to the trip<Icon name="arrow-right" size={16} /></Button>
          </div>
        </div>
      );
    }

    return (
      <div className="ls-page">
        {head}

        <Card className="ls-rc">
          <CardHeader>
            <CardTitle>{listing.name}</CardTitle>
            <CardDescription>
              Issued {formatDayFull(issuedAt)} · {booking.reference} · {labelOf(PLACE_KINDS, listing.kind)} in {labelOf(NEIGHBOURHOODS, listing.neighbourhood)}
            </CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="ls-rc__facts">
              <Fact label="Guest">{guest.name}</Fact>
              <Fact label="Host">{host.name}</Fact>
              <Fact label="Stay">{formatDayFull(booking.checkIn)} → {formatDayFull(booking.checkOut)}</Fact>
              <Fact label="Nights and guests">{nights} {nights === 1 ? "night" : "nights"} · {booking.guests} {booking.guests === 1 ? "guest" : "guests"}</Fact>
              <Fact label="Booked">{formatDayFull(booking.bookedAt)}</Fact>
              <Fact label="Status"><StatusBadge values={BOOKING_STATUS} value={booking.status} /></Fact>
            </div>
          </CardPanel>

          <Separator />

          <CardPanel style={{ padding: 0 }}>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>What was charged</TableHead>
                  <TableHead style={{ textAlign: "right" }}>Amount</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {lines.map((line) => (
                  <TableRow key={line.id}>
                    <TableCell>{line.label}</TableCell>
                    <TableCell style={{ textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{formatPrice(line.amount)}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
              <TableFooter>
                <TableRow>
                  <TableCell>Total for the stay</TableCell>
                  <TableCell style={{ textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{formatPrice(quote.total)}</TableCell>
                </TableRow>
              </TableFooter>
            </Table>
          </CardPanel>

          <Separator />

          <CardPanel style={{ padding: 0 }}>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Movement</TableHead>
                  <TableHead>Card</TableHead>
                  <TableHead>When</TableHead>
                  <TableHead style={{ textAlign: "right" }}>Amount</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {payments.map((payment) => {
                  const method = methodById(data.methods, payment.method);
                  return (
                    <TableRow key={payment.id}>
                      <TableCell>
                        <span className="ls-row ls-row--tight">
                          {labelOf(PAYMENT_KINDS, payment.kind)}
                          <StatusBadge values={PAYMENT_STATUS} value={payment.status} />
                        </span>
                      </TableCell>
                      <TableCell className="ls-muted">{method.brand} ···· {method.last4}</TableCell>
                      <TableCell title={formatAbsolute(payment.paidAt || payment.dueAt)}>
                        {payment.paidAt ? formatDayFull(payment.paidAt) : "Due " + formatDayFull(payment.dueAt)}
                      </TableCell>
                      <TableCell style={{ textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{payment.kind === "refund" ? "−" : ""}{formatPrice(payment.amountCents)}</TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
              <TableFooter>
                <TableRow>
                  <TableCell colSpan={3}>{refunded ? "Charged, less what came back" : owed ? "Charged so far" : "Charged in full"}</TableCell>
                  <TableCell style={{ textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{formatPrice(paid - refunded)}</TableCell>
                </TableRow>
              </TableFooter>
            </Table>
          </CardPanel>

          <CardFooter className="ls-stack ls-stack--tight" style={{ alignItems: "flex-start" }}>
            <span className="ls-note">
              {owed
                ? formatPrice(owed) + " of the " + formatPrice(quote.total) + " is still to come, on " + formatDayFull(owedPayments(booking)[0].dueAt) + ", from the same card."
                : refunded
                  ? formatPrice(refunded) + " came back on " + formatDayFull(payments.filter((p) => p.status === "refunded")[0].paidAt) + ", so " + formatPrice(paid - refunded) + " was kept."
                  : "Nothing further is owed on this stay."}
            </span>
            <span className="ls-note">
              {policy ? policy.label + " cancellation: " + policy.note : "No cancellation policy on file."}
            </span>
            <span className="ls-note">
              Lodestay collects for the host and shows on a statement as LODESTAY. Questions about the stay itself go to {host.name.split(" ")[0]}.
            </span>
          </CardFooter>
        </Card>

        <div className="ls-row">
          <Button variant="outline" onClick={() => onNavigate("/trips/" + booking.id)}>Back to the trip<Icon name="arrow-right" size={16} /></Button>
          <Button variant="ghost" onClick={() => onNavigate("/inbox")}>Message {host.name.split(" ")[0]}</Button>
        </div>
      </div>
    );
  }

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