/* Auth — its own shell, and the only shell in the product with NO navigation
   owner (AGENTS §7.1): no rail, no panel, no account menu. Split layout, chosen
   once for the product; the form side is the wider of the two.
   Every screen here is STAGED. One state per screen, and a server error and a
   field error never render for the same submission.
   Strategy: password, one credential. No providers are offered because no
   official provider mark is held in this product's assets (§7.4) — an entry
   point without a screen behind it is worse than none. */
(() => {
  const {
    Button, Input, Alert, AlertTitle, AlertDescription, Field, FieldLabel, FieldDescription, FieldError, Separator,
  } = window.OriginDesignSystem_7c998b;

  function AuthShell({ title, lede, claim, fine, children, foot }) {
    return (
      <div className="hd-auth">
        <aside className="hd-auth__brandside">
          <span className="hd-auth__art" aria-hidden="true" />
          <span className="hd-auth__mark">
            <img src={HD_BRAND_MARK} alt="" width="20" height="20" />
            Ward Desk
          </span>
          <p className="hd-auth__claim">{claim}</p>
          <p className="hd-auth__fine">{fine}</p>
        </aside>
        <main className="hd-auth__formside">
          <div className="hd-auth__form">
            <div>
              <h1 className="hd-auth__title">{title}</h1>
              <p className="hd-auth__lede">{lede}</p>
            </div>
            {children}
            {foot ? <p className="hd-auth__foot">{foot}</p> : null}
          </div>
        </main>
      </div>
    );
  }

  const CLAIM = "One board for the wards, the theatres and the pharmacy.";
  const FINE = HD_HOSPITAL.trust + " · Ward Desk holds patient data. Everything you open is logged against your name.";

  function SignInScreen({ onSignIn, onNavigate }) {
    const [email, setEmail] = React.useState("");
    const [password, setPassword] = React.useState("");
    const [reveal, setReveal] = React.useState(false);
    const [submitted, setSubmitted] = React.useState(false);
    const [rejected, setRejected] = React.useState(false);
    const dirty = !!email || !!password;

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

    const submit = () => {
      setSubmitted(true);
      if (!valid) { setRejected(false); return; }
      /* One state per submission: a server error only where there is no field
         error, and the password field is the only thing cleared. */
      if (email.trim().toLowerCase().indexOf("@haldengeneral.nhs.uk") < 0) { setRejected(true); setPassword(""); return; }
      setRejected(false);
      onSignIn();
    };

    return (
      <AuthShell title="Sign in" claim={CLAIM} fine={FINE}
        lede={"Use your " + HD_HOSPITAL.short + " account. Ward Desk does not hold a separate password."}
        foot={<>Cannot get in? The service desk is on ext 4000, or write to {HD_HOSPITAL.recordsEmail}.</>}>
        {rejected ? (
          <Alert variant="error">
            <AlertTitle>Email or password is incorrect</AlertTitle>
            <AlertDescription>Check the address and try again. After five attempts the account locks for fifteen minutes.</AlertDescription>
          </Alert>
        ) : null}
        <div className="hd-auth__fields">
          <Field>
            <FieldLabel htmlFor="hd-signin-email">Work email</FieldLabel>
            <Input id="hd-signin-email" type="email" autoComplete="email" value={email} placeholder="i.vance@haldengeneral.nhs.uk"
              invalid={submitted && !!errors.email} onChange={(e) => setEmail(e.target.value)} />
            {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : null}
          </Field>
          <Field>
            <span className="hd-auth__row">
              <FieldLabel htmlFor="hd-signin-password">Password</FieldLabel>
              <Button variant="link" size="xs" onClick={() => onNavigate("/forgot-password")}>Forgot password?</Button>
            </span>
            <Input id="hd-signin-password" type={reveal ? "text" : "password"} autoComplete="current-password" value={password}
              invalid={submitted && !!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 && errors.password ? <FieldError>{errors.password}</FieldError> : null}
          </Field>
          <Button disabled={!dirty} onClick={submit}>Sign in</Button>
        </div>
      </AuthShell>
    );
  }

  function ForgotPasswordScreen({ email, onSubmit, onNavigate }) {
    const [value, setValue] = React.useState(email || "");
    const [submitted, setSubmitted] = React.useState(false);
    const error = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value.trim()) ? null : "Enter a valid email address.";
    return (
      <AuthShell title="Forgot password" claim={CLAIM} fine={FINE}
        lede="We will send a link that sets a new password. The link works once and expires after an hour."
        foot={<>Remembered it? <Button variant="link" size="xs" onClick={() => onNavigate("/signin")}>Back to sign in</Button></>}>
        <div className="hd-auth__fields">
          <Field>
            <FieldLabel htmlFor="hd-forgot-email">Work email</FieldLabel>
            <Input id="hd-forgot-email" type="email" autoComplete="username" value={value} placeholder="i.vance@haldengeneral.nhs.uk"
              invalid={submitted && !!error} onChange={(e) => setValue(e.target.value)} />
            {submitted && error ? <FieldError>{error}</FieldError> : <FieldDescription>The address your rota and payslips go to.</FieldDescription>}
          </Field>
          <Button disabled={!value} onClick={() => { setSubmitted(true); if (!error) onSubmit(value.trim()); }}>Send reset link</Button>
        </div>
      </AuthShell>
    );
  }

  function ResetLinkSentScreen({ email, onNavigate }) {
    return (
      <AuthShell title="Check your email" claim={CLAIM} fine={FINE}
        lede={"If an account exists for " + email + ", we have sent a link that sets a new password. It expires in " + HD_RESET_LINK.expiresInMinutes + " minutes."}
        foot={<>Nothing arrived within ten minutes? Check the junk folder, then call the service desk on ext 4000.</>}>
        <div className="hd-auth__fields">
          <Button variant="outline" onClick={() => onNavigate("/forgot-password")}>Send it again</Button>
          <Separator />
          <Button variant="link" onClick={() => onNavigate("/signin")}>Back to sign in</Button>
        </div>
      </AuthShell>
    );
  }

  function SetNewPasswordScreen({ now, onSubmit, onNavigate }) {
    const [value, setValue] = React.useState("");
    const [reveal, setReveal] = React.useState(false);
    const [submitted, setSubmitted] = React.useState(false);
    const met = PASSWORD_RULES.map((rule) => ({ id: rule.id, label: rule.label, ok: rule.test(value) }));
    const valid = met.every((r) => r.ok);
    const minutesLeft = Math.max(0, HD_RESET_LINK.expiresInMinutes - Math.round((now - HD_RESET_LINK.issuedAt) / 6e4));
    return (
      <AuthShell title="Set a new password" claim={CLAIM} fine={FINE}
        lede={"For " + HD_RESET_LINK.email + ". This link expires in " + minutesLeft + " minutes and works once."}
        foot={<>Link expired while you were reading? <Button variant="link" size="xs" onClick={() => onNavigate("/reset-password/expired")}>See what to do</Button></>}>
        <div className="hd-auth__fields">
          <Field>
            <FieldLabel htmlFor="hd-reset-password">New password</FieldLabel>
            <Input id="hd-reset-password" type={reveal ? "text" : "password"} autoComplete="new-password" value={value}
              invalid={submitted && !valid} onChange={(e) => setValue(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 && !valid ? <FieldError>Your password does not meet every requirement yet.</FieldError> : null}
          </Field>
          <div className="hd-checklist">
            {met.map((rule) => (
              <span className="hd-checklist__item" key={rule.id} data-met={rule.ok ? "true" : "false"}>
                <Icon name={rule.ok ? "check" : "dot"} size={14} />{rule.label}
              </span>
            ))}
          </div>
          <Button disabled={!value} onClick={() => { setSubmitted(true); if (valid) onSubmit(); }}>Set new password</Button>
        </div>
      </AuthShell>
    );
  }

  function ResetLinkExpiredScreen({ onNavigate }) {
    return (
      <AuthShell title="That link has expired" claim={CLAIM} fine={FINE}
        lede={"A reset link works once and lasts " + HD_RESET_LINK.expiresInMinutes + " minutes. Ask for a new one and it will arrive within a minute."}
        foot={<>Somebody else may have used it. If you did not ask for a reset, call the service desk on ext 4000.</>}>
        <div className="hd-auth__fields">
          <Button onClick={() => onNavigate("/forgot-password")}>Send a new link</Button>
          <Button variant="link" onClick={() => onNavigate("/signin")}>Back to sign in</Button>
        </div>
      </AuthShell>
    );
  }

  function PasswordResetDoneScreen({ email, onNavigate }) {
    return (
      <AuthShell title="Password changed" claim={CLAIM} fine={FINE}
        lede={"The password for " + email + " has been changed and every other session has been signed out — including the ward station you may have left open."}
        foot={<>Did not change it yourself? Call the service desk on ext 4000 immediately.</>}>
        <div className="hd-auth__fields">
          <Button onClick={() => onNavigate("/signin")}>Sign in</Button>
        </div>
      </AuthShell>
    );
  }

  Object.assign(window, { SignInScreen, ForgotPasswordScreen, ResetLinkSentScreen, SetNewPasswordScreen, ResetLinkExpiredScreen, PasswordResetDoneScreen });
})();
