/* Lodestay — checkout. COMMIT MODEL: staged. Every control on this screen is a
   form field, nothing happens until the one primary action at the bottom, and
   that action is disabled until the form is both dirty and valid. Cancel
   appears once it is dirty; the submit shows pending; errors render on
   validation, never on first paint.

   The verb is the place's booking mode, product-wide: an instant place says
   Reserve, a host-confirmed one says Request to book — and the second one
   charges nothing, which the screen says beside the button rather than after
   it. The money is quoteFor and paymentPlan, the same two functions the place
   screen and the trip screen call. */
(() => {
  const {
    Button, Input, Textarea, Select, RadioGroup, Checkbox, Separator,
    Field, FieldLabel, FieldDescription, FieldError,
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Alert, AlertTitle, AlertDescription,
  } = window.OriginDesignSystem_7c998b;

  function CheckoutScreen({ listing, data, scope, user, methods, onNavigate, onSubmit }) {
    const host = hostById(data.hosts, listing.hostId);
    const quote = quoteForListing(listing, scope);
    const policy = policyOf(listing.cancelPolicy);
    const instant = LISTING_FLAGS.isInstant(listing);
    const plan = paymentPlan({ total: quote.total, checkIn: scope.checkIn, bookedAt: data.now });

    const [draft, setDraft] = React.useState({
      purpose: "",
      message: "",
      method: (methods.find((m) => m.isDefault) || methods[0]).id,
      guests: String(scope.guests),
    });
    const [dirty, setDirty] = React.useState(false);
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);

    const set = (fields) => { setDirty(true); setDraft((d) => Object.assign({}, d, fields)); };
    const guests = parseInt(draft.guests, 10);
    const liveQuote = quoteFor({ nightlyCents: listing.nightlyCents, cleaningCents: listing.cleaningCents, checkIn: scope.checkIn, checkOut: scope.checkOut, guests: guests });
    const livePlan = paymentPlan({ total: liveQuote.total, checkIn: scope.checkIn, bookedAt: data.now });

    const errors = {};
    if (!draft.purpose) errors.purpose = "Hosts ask, so we ask once.";
    if (!instant && draft.message.trim().length < 20) errors.message = "Write a line or two — " + host.name.split(" ")[0] + " reads these before accepting.";
    if (guests > listing.sleeps) errors.guests = "This place sleeps " + listing.sleeps + ".";
    const valid = Object.keys(errors).length === 0;

    const submit = () => {
      setSubmitted(true);
      if (!valid) return;
      setPending(true);
      window.setTimeout(() => { setPending(false); onSubmit(listing, { guests: guests, purpose: draft.purpose, message: draft.message.trim(), method: draft.method }); }, 700);
    };

    return (
      <div className="ls-page">
        <PageHead
          path="/stays/:id/book" params={{ id: listing.id }} labels={{ "/stays/:id": listing.name }} onNavigate={onNavigate}
          title={instant ? "Reserve " + listing.name : "Ask " + host.name.split(" ")[0] + " about these dates"}
          lede={formatStayLine(scope.checkIn, scope.checkOut, guests) + " · " + labelOf(NEIGHBOURHOODS, listing.neighbourhood)}
        />

        <div className="ls-columns">
          <div className="ls-col">
            {!instant ? (
              <Alert variant="info">
                <Icon name="clock" size={16} />
                <AlertTitle>Nothing is charged yet</AlertTitle>
                <AlertDescription>{host.name.split(" ")[0]} has 24 hours to answer. {replyLine(host).replace("Usually answers", "They usually answer")}. If they accept, the card below is charged {formatPrice(livePlan[0].amountCents)} straight away.</AlertDescription>
              </Alert>
            ) : null}

            <Card>
              <CardHeader>
                <CardTitle>Who is coming</CardTitle>
                <CardDescription>Sleeps {listing.sleeps}. {host.name.split(" ")[0]} is told the number, not the names.</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="ls-stack">
                  <Field>
                    <FieldLabel htmlFor="ls-guests">Guests</FieldLabel>
                    <Select
                      id="ls-guests" size="default" value={draft.guests}
                      items={[1, 2, 3, 4, 5, 6].map((n) => ({ value: String(n), label: formatGuests(n) }))}
                      invalid={submitted && !!errors.guests}
                      onValueChange={(value) => set({ guests: value })}
                    />
                    {submitted && errors.guests ? <FieldError>{errors.guests}</FieldError> : <FieldDescription>The city tax is per guest, per night, and moves with this.</FieldDescription>}
                  </Field>
                  <Field>
                    <FieldLabel htmlFor="ls-purpose">What brings you</FieldLabel>
                    <RadioGroup id="ls-purpose" name="ls-purpose" items={TRIP_PURPOSES} value={draft.purpose} onValueChange={(value) => set({ purpose: value })} />
                    {submitted && errors.purpose ? <FieldError>{errors.purpose}</FieldError> : null}
                  </Field>
                </div>
              </CardPanel>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Message to {host.name.split(" ")[0]}</CardTitle>
                <CardDescription>{instant ? "Optional — it goes into the conversation with your booking." : "Required. It is what they decide on."}</CardDescription>
              </CardHeader>
              <CardPanel>
                <Field>
                  <FieldLabel htmlFor="ls-message">Your message</FieldLabel>
                  <Textarea
                    id="ls-message" rows={4} value={draft.message}
                    placeholder={instant ? "Arriving on the evening train, nothing needed from you." : "Four of us, two light sleepers — how bad is the noise at the back?"}
                    invalid={submitted && !!errors.message}
                    onChange={(e) => set({ message: e.target.value })}
                  />
                  {submitted && errors.message ? <FieldError>{errors.message}</FieldError> : <FieldDescription>Arrival time can wait — the trip screen asks for it nearer the day.</FieldDescription>}
                </Field>
              </CardPanel>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>How it is paid</CardTitle>
                <CardDescription>{livePlan.length === 1 ? "One payment, taken now." : "Two payments: half now, the rest " + STAY_POLICY.balanceDueDaysBefore + " days before you arrive."}</CardDescription>
              </CardHeader>
              <CardPanel>
                <div className="ls-stack">
                  <Field>
                    <FieldLabel htmlFor="ls-method">Card</FieldLabel>
                    <Select
                      id="ls-method" value={draft.method}
                      items={methods.map((m) => ({ value: m.id, label: m.brand + " ending " + m.last4 + " · expires " + m.expiry }))}
                      onValueChange={(value) => set({ method: value })}
                    />
                    <FieldDescription>Cards are managed on your account, not here.</FieldDescription>
                  </Field>
                  <div className="ls-lines">
                    {livePlan.map((row) => (
                      <div className="ls-line" key={row.kind}>
                        <span>{labelOf(PAYMENT_KINDS, row.kind)}</span>
                        <span className="ls-line__amount">{formatPrice(row.amountCents)}</span>
                        <span className="ls-line__note">{row.dueAt <= data.now ? (instant ? "Taken when you reserve" : "Taken if the host accepts") : "Due " + formatDayFull(row.dueAt)}</span>
                      </div>
                    ))}
                  </div>
                </div>
              </CardPanel>
            </Card>
          </div>

          <div className="ls-col">
            <div className="ls-sticky ls-stack">
              <Card>
                <CardHeader>
                  <CardTitle>{listing.name}</CardTitle>
                  <CardDescription>{labelOf(PLACE_KINDS, listing.kind)} · {labelOf(NEIGHBOURHOODS, listing.neighbourhood)}</CardDescription>
                </CardHeader>
                <CardPanel>
                  <div className="ls-stack ls-stack--tight">
                    <Photo label={listing.photos[0]} icon={iconOfKind(listing)} shape="wide" />
                    <div className="ls-facts">
                      <div className="ls-fact"><span className="ls-fact__label">Check in</span><span className="ls-fact__value">{formatDayFull(scope.checkIn)}</span></div>
                      <div className="ls-fact"><span className="ls-fact__label">Check out</span><span className="ls-fact__value">{formatDayFull(scope.checkOut)}</span></div>
                    </div>
                    <Separator />
                    <QuoteBreakdown quote={liveQuote} />
                  </div>
                </CardPanel>
                <CardFooter className="ls-stack ls-stack--tight" style={{ alignItems: "stretch" }}>
                  <Button size="lg" loading={pending} disabled={!dirty} onClick={submit}>{instant ? "Reserve" : "Request to book"}</Button>
                  {dirty ? <Button variant="outline" onClick={() => onNavigate("/stays/" + listing.id)}>Cancel</Button> : null}
                  <span className="ls-note">{policy.note} Nothing else is charged, and the {formatPrice(liveQuote.cityTax)} city tax is Lisbon's, not ours.</span>
                </CardFooter>
              </Card>
            </div>
          </div>
        </div>
      </div>
    );
  }

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