/* Lodestay — the account screens and the auth shell.

   Profile is STAGED: every control is a form field, Save and Cancel are
   disabled until it is dirty, and nothing applies until Save.
   Payment methods is INSTANT: each control confirms itself — making a card the
   default applies at once with an undo toast, and removing one is irreversible,
   so it opens a confirm dialog naming the bookings that would be left without
   a card.

   Auth is its own shell (AGENTS §7.1): no navigation owner, no destinations, no
   account menu — the product mark above the form is the only navigation. One
   layout variant, split, with the form side the wider one. One primary
   credential strategy: password, with a reveal toggle. No providers are offered
   because this design system ships no official provider marks, and drawing them
   is forbidden. */
(() => {
  const {
    Button, Input, Select, Badge, Separator, Checkbox,
    Field, FieldLabel, FieldDescription, FieldError,
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter, CardAction,
    Alert, AlertTitle, AlertDescription,
  } = window.OriginDesignSystem_7c998b;

  /* ── Your profile — staged ─────────────────────────────────────────────── */
  function ProfileScreen({ user, data, onNavigate, onSave }) {
    const [draft, setDraft] = React.useState({ name: user.name, email: user.email, phone: user.phone, homeCity: user.homeCity });
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    React.useEffect(() => { setDraft({ name: user.name, email: user.email, phone: user.phone, homeCity: user.homeCity }); setSubmitted(false); }, [user]);

    const dirty = draft.name !== user.name || draft.email !== user.email || draft.phone !== user.phone || draft.homeCity !== user.homeCity;
    const errors = {};
    if (draft.name.trim().length < 2) errors.name = "Hosts see this name on your bookings.";
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draft.email.trim())) errors.email = "Enter a valid email address.";
    const valid = Object.keys(errors).length === 0;
    const set = (fields) => setDraft((d) => Object.assign({}, d, fields));

    const stayed = data.bookings.filter((b) => b.status === "completed");

    return (
      <div className="ls-page ls-page--narrow">
        <PageHead
          path="/account/profile" onNavigate={onNavigate}
          title="Your profile"
          lede={"On Lodestay since " + formatDay(user.joinedAt) + " · " + stayed.length + (stayed.length === 1 ? " stay" : " stays") + " · " + formatNights(nightsStayed(data.bookings)) + " in " + LODESTAY_PRODUCT.city}
        />
        <Card>
          <CardHeader>
            <CardTitle>What hosts see</CardTitle>
            <CardDescription>Your name and the city you come from. Your phone number is shared only once a booking is confirmed.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="ls-stack">
              <Field>
                <FieldLabel htmlFor="ls-name">Name</FieldLabel>
                <Input id="ls-name" value={draft.name} invalid={submitted && !!errors.name} onChange={(e) => set({ name: e.target.value })} autoComplete="name" />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="ls-email">Email</FieldLabel>
                <Input id="ls-email" type="email" value={draft.email} invalid={submitted && !!errors.email} onChange={(e) => set({ email: e.target.value })} autoComplete="email" />
                {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : <FieldDescription>Booking confirmations and host messages go here.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="ls-phone">Phone</FieldLabel>
                <Input id="ls-phone" value={draft.phone} onChange={(e) => set({ phone: e.target.value })} autoComplete="tel" />
                <FieldDescription>Shared with the host of a confirmed stay, nobody else.</FieldDescription>
              </Field>
              <Field>
                <FieldLabel htmlFor="ls-city">Where you live</FieldLabel>
                <Input id="ls-city" value={draft.homeCity} onChange={(e) => set({ homeCity: e.target.value })} autoComplete="address-level2" />
              </Field>
            </div>
          </CardPanel>
          <CardFooter>
            <div className="ls-row">
              <Button loading={pending} disabled={!dirty} onClick={() => { setSubmitted(true); if (!valid) return; setPending(true); window.setTimeout(() => { setPending(false); onSave(draft); }, 500); }}>Save profile</Button>
              {dirty ? <Button variant="outline" onClick={() => { setDraft({ name: user.name, email: user.email, phone: user.phone, homeCity: user.homeCity }); setSubmitted(false); }}>Cancel</Button> : null}
            </div>
          </CardFooter>
        </Card>
      </div>
    );
  }

  /* ── Payment methods — instant ─────────────────────────────────────────── */
  function PaymentsScreen({ data, methods, onNavigate, onMakeDefault, onRemove }) {
    /* Which bookings are still going to charge each card — one predicate, and
       the only reason removing one is irreversible. */
    const scheduledOn = (methodId) => data.bookings.filter((b) => owedPayments(b).some((p) => p.method === methodId));
    const paidOn = (methodId) => data.bookings.filter((b) => paidPayments(b).some((p) => p.method === methodId));

    return (
      <div className="ls-page ls-page--narrow">
        <PageHead
          path="/account/payments" onNavigate={onNavigate}
          title="Payment methods"
          lede={methods.length + (methods.length === 1 ? " card" : " cards") + " · " + formatPrice(data.bookings.reduce((sum, b) => sum + owedCents(b), 0)) + " scheduled across your open stays"}
        />
        <div className="ls-stack">
          {methods.map((method) => {
            const scheduled = scheduledOn(method.id);
            const used = paidOn(method.id);
            const failing = data.bookings.filter((b) => failedPayments(b).some((p) => p.method === method.id));
            return (
              <Card key={method.id}>
                <CardHeader>
                  <CardTitle>{method.brand} ···· {method.last4}</CardTitle>
                  <CardDescription>Expires {method.expiry} · {used.length ? used.length + (used.length === 1 ? " stay paid with it" : " stays paid with it") : "never used"}</CardDescription>
                  <CardAction>{method.isDefault ? <Badge variant="secondary">Default</Badge> : null}</CardAction>
                </CardHeader>
                <CardPanel>
                  {failing.length ? (
                    <Alert variant="error">
                      <Icon name="credit-card" size={16} />
                      <AlertTitle>A payment on this card was declined</AlertTitle>
                      <AlertDescription>{failing.map((b) => listingById(data.listings, b.listingId).name + " — " + formatPrice(failedPayments(b)[0].amountCents)).join(" · ")}. Retry it from the trip.</AlertDescription>
                    </Alert>
                  ) : (
                    <span className="ls-note">
                      {scheduled.length
                        ? scheduled.length + (scheduled.length === 1 ? " stay is" : " stays are") + " scheduled to charge it: " + scheduled.map((b) => listingById(data.listings, b.listingId).name + ", " + formatPrice(owedCents(b)) + " on " + formatDay(owedPayments(b)[0].dueAt)).join(" · ") + "."
                        : "Nothing is scheduled to charge it."}
                    </span>
                  )}
                </CardPanel>
                <CardFooter>
                  <div className="ls-row">
                    {method.isDefault ? null : <Button variant="outline" size="sm" onClick={() => onMakeDefault(method)}>Make default</Button>}
                    {failing.length ? <Button variant="outline" size="sm" onClick={() => onNavigate("/trips/" + failing[0].id)}>Open the trip</Button> : null}
                    {method.isDefault ? (
                      <FloatingTip label="Make another card the default first — new bookings need one." side="bottom">
                        <Button variant="destructive-outline" size="sm" disabled>Remove card</Button>
                      </FloatingTip>
                    ) : (
                      <Button variant="destructive-outline" size="sm" onClick={() => onRemove(method)}>Remove card</Button>
                    )}
                  </div>
                </CardFooter>
              </Card>
            );
          })}
        </div>
      </div>
    );
  }

  /* ── Auth shell ────────────────────────────────────────────────────────── */
  function AuthShell({ children, quote, attribution }) {
    return (
      <div className="ls-auth">
        <div className="ls-auth__form">
          <div className="ls-auth__inner">
            <span className="ls-row ls-row--tight">
              <img className="ls-brand__logo" src="../../assets/templates/logos/28-logo-demo.svg" alt="" width="28" height="28" />
              <span className="ls-brand__name">{LODESTAY_PRODUCT.name}</span>
            </span>
            {children}
          </div>
        </div>
        <div className="ls-auth__aside">
          <span className="ls-auth__photo"><Photo label="Lisbon rooftops, Graça" icon="image" shape="flat" /></span>
          <p className="ls-auth__quote">{quote}</p>
          <span className="ls-note">{attribution}</span>
        </div>
      </div>
    );
  }

  /* One state per screen: idle, field-invalid, credentials-rejected. Never a
     validation error and a server error at once, and neither on first paint. */
  function SignInScreen({ user, onSignIn, onNavigate, onLock }) {
    const [email, setEmail] = React.useState(user.email);
    const [password, setPassword] = React.useState("");
    const [reveal, setReveal] = React.useState(false);
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    const [rejected, setRejected] = React.useState(false);
    /* Attempts are counted, not asserted: the sentence under the error reads
       the same number the lock does. */
    const [used, setUsed] = React.useState(0);
    const left = AUTH_POLICY.signInAttempts - used;

    const errors = {};
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email.trim())) errors.email = "Enter a valid email address.";
    if (password.length < AUTH_POLICY.passwordMinLength) errors.password = "Your password is at least " + AUTH_POLICY.passwordMinLength + " characters.";
    const valid = Object.keys(errors).length === 0;
    const dirty = password.length > 0 || email !== user.email;

    const submit = () => {
      setSubmitted(true);
      setRejected(false);
      if (!valid) return;
      setPending(true);
      window.setTimeout(() => {
        setPending(false);
        /* The kit has one account. Anything else is rejected without saying
           whether the address exists. */
        if (password === "lodestay") onSignIn();
        else {
          const now = used + 1;
          setUsed(now);
          setPassword("");
          if (now >= AUTH_POLICY.signInAttempts) onLock();
          else setRejected(true);
        }
      }, 600);
    };

    return (
      <AuthShell
        quote="Ten places in Lisbon, priced for the nights you actually asked for."
        attribution="Photography drops in here — the frame is the placeholder, not the design."
      >
        <div className="ls-stack">
          <div className="ls-head__text">
            <h1 className="ls-title ls-title--sm">Sign in</h1>
            <p className="ls-lede">Your trips, your saved places and your conversations with hosts.</p>
          </div>
          {rejected ? (
            <Alert variant="error">
              <Icon name="triangle-alert" size={16} />
              <AlertTitle>Email or password is incorrect</AlertTitle>
              <AlertDescription>{left === 1 ? "One attempt left" : left + " attempts left"} before the account is locked for {AUTH_POLICY.lockMinutes} minutes.</AlertDescription>
            </Alert>
          ) : null}
          <Field>
            <FieldLabel htmlFor="ls-auth-email">Email</FieldLabel>
            <Input id="ls-auth-email" type="email" autoComplete="email" value={email} invalid={submitted && !rejected && !!errors.email} onChange={(e) => setEmail(e.target.value)} />
            {submitted && !rejected && errors.email ? <FieldError>{errors.email}</FieldError> : null}
          </Field>
          <Field>
            <div className="ls-spread">
              <FieldLabel htmlFor="ls-auth-password">Password</FieldLabel>
              <button type="button" className="ls-link ls-note" onClick={() => onNavigate("/forgot-password")}>Forgot password?</button>
            </div>
            <Input
              id="ls-auth-password" type={reveal ? "text" : "password"} autoComplete="current-password"
              value={password} invalid={submitted && !rejected && !!errors.password}
              onChange={(e) => setPassword(e.target.value)}
              endAddon={<Button variant="ghost" size="icon-xs" aria-label={reveal ? "Hide password" : "Show password"} onClick={() => setReveal(!reveal)}><Icon name={reveal ? "eye-off" : "eye"} size={14} /></Button>}
            />
            {submitted && !rejected && errors.password ? <FieldError>{errors.password}</FieldError> : <FieldDescription>The demo password is <span className="ls-mono">lodestay</span>.</FieldDescription>}
          </Field>
          <Button size="lg" loading={pending} disabled={!dirty} onClick={submit}>Sign in</Button>
          <p className="ls-auth__switch">New to Lodestay? <button type="button" className="ls-link" onClick={() => onNavigate("/signup")}>Create account</button></p>
          <span className="ls-note">Trouble signing in? Write to <span className="ls-mono">{AUTH_POLICY.supportEmail}</span> and a person answers.</span>
        </div>
      </AuthShell>
    );
  }

  function SignedOutScreen({ user, onSignIn }) {
    return (
      <AuthShell
        quote="Signed out on this device only. Your stays are where you left them."
        attribution="Nothing was cancelled, and nothing was charged."
      >
        <div className="ls-stack">
          <div className="ls-head__text">
            <h1 className="ls-title ls-title--sm">You are signed out</h1>
            <p className="ls-lede">{user.name.split(" ")[0]}, your trips and saved places are kept. Sign in again whenever you like.</p>
          </div>
          <Button size="lg" onClick={onSignIn}>Sign in</Button>
          <span className="ls-note">Need a hand with a stay that is already booked? <span className="ls-mono">help@lodestay.travel</span></span>
        </div>
      </AuthShell>
    );
  }

  Object.assign(window, { ProfileScreen, PaymentsScreen, SignInScreen, SignedOutScreen, AuthShell });
})();
