/* Parley — settings and auth.

   Settings screens are STAGED: every control is a form field, nothing applies
   until Save, Save and Cancel are disabled until dirty. That is the opposite of
   the chat screen's instant model, which is legal because they are different
   screens and each states its model here.

   Auth is its own shell (AGENTS §7.1): no sidebar, no top nav, no account menu,
   no destinations. One layout variant for the product — centred card, 23rem.
   One credential strategy — email and password. No providers: the rules require
   official marks from the product's own assets folder and this template ships
   none, so offering "Continue with…" would mean drawing one. Every auth form is
   staged, every error renders on submit and never on first paint, and every
   entry point rendered has a screen behind it. */
(() => {
  const {
    Button, Input, InputGroup, InputGroupInput, InputGroupAddon, Select, Checkbox, RadioGroup, Switch,
    Field, FieldLabel, FieldDescription, FieldError, Label,
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Alert, AlertTitle, AlertDescription, Separator, Badge, Avatar,
  } = window.OriginDesignSystem_7c998b;

  /* ── Account (staged) ──────────────────────────────────────────────── */

  function AccountScreen({ user, data, onSave, onSignOutEverywhere }) {
    const blank = () => ({ name: user.name, email: user.email, role: user.role, avatar: user.avatar || null });
    const [draft, setDraft] = React.useState(blank);
    React.useEffect(() => { setDraft(blank()); }, [user]);
    const dirty = draft.name !== user.name || draft.email !== user.email || draft.role !== user.role || draft.avatar !== (user.avatar || null);
    const fileRef = React.useRef(null);
    const [photoError, setPhotoError] = React.useState(null);
    /* Staged like every other field here: the picked file is read into the draft
       and only reaches the account menu on Save. */
    const pickPhoto = (file) => {
      if (!file) return;
      if (!/^image\/(png|jpeg|webp)$/.test(file.type)) { setPhotoError("Pick a PNG, JPEG or WebP image."); return; }
      if (file.size > 2 * 1024 * 1024) { setPhotoError("That file is " + Math.round(file.size / 1024 / 102.4) / 10 + "MB. The limit is 2MB."); return; }
      const reader = new FileReader();
      reader.onload = () => { setPhotoError(null); setDraft((d) => Object.assign({}, d, { avatar: String(reader.result) })); };
      reader.readAsDataURL(file);
    };
    const errors = {};
    if (!draft.name.trim()) errors.name = "A name is what other people see on a shared thread.";
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draft.email.trim())) errors.email = "Enter a valid email address.";
    const [submitted, setSubmitted] = React.useState(false);
    const valid = Object.keys(errors).length === 0;
    const set = (k, v) => setDraft(Object.assign({}, draft, { [k]: v }));
    const mine = data.threads.filter((t) => t.ownerId === user.id);

    return (
      <div className="pl-page" style={{ maxWidth: "48rem" }}>
        <PageHead title="Account" note={"You own " + mine.length + " of the " + data.threads.length + " threads in " + WORKSPACE.name + "."} />
        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Who you are here</CardTitle>
            <CardDescription>Your name appears on every thread you share with the workspace.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="pl-fields">
              <Field>
                <FieldLabel>Photo</FieldLabel>
                <div className="pl-photo">
                  <Avatar size={64} src={draft.avatar || undefined} alt="" fallback={user.initials} />
                  <div className="pl-photo__acts">
                    <input ref={fileRef} type="file" accept="image/png,image/jpeg,image/webp" hidden onChange={(e) => { pickPhoto(e.target.files && e.target.files[0]); e.target.value = ""; }} />
                    <Button variant="outline" size="sm" onClick={() => fileRef.current && fileRef.current.click()}>{draft.avatar ? "Replace photo" : "Upload photo"}</Button>
                    {draft.avatar ? <Button variant="ghost" size="sm" onClick={() => { setPhotoError(null); setDraft(Object.assign({}, draft, { avatar: null })); }}>Remove</Button> : null}
                  </div>
                </div>
                {photoError ? <FieldError>{photoError}</FieldError> : <FieldDescription>PNG, JPEG or WebP, up to 2MB. Without one, your initials stand in.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="pl-name">Name</FieldLabel>
                <Input id="pl-name" value={draft.name} autoComplete="name" invalid={submitted && !!errors.name} onChange={(e) => set("name", e.target.value)} />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="pl-email">Email</FieldLabel>
                <Input id="pl-email" type="email" value={draft.email} autoComplete="email" invalid={submitted && !!errors.email} onChange={(e) => set("email", e.target.value)} />
                {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : <FieldDescription>Sign-in address. Changing it signs you out of other devices.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="pl-role">Role</FieldLabel>
                <Input id="pl-role" value={draft.role} onChange={(e) => set("role", e.target.value)} />
                <FieldDescription>Shown beside your name in the account menu and on the usage table.</FieldDescription>
              </Field>
            </div>
          </CardPanel>
        </Card>

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Sessions</CardTitle>
            <CardDescription>Signing out everywhere ends every session except this one.</CardDescription>
          </CardHeader>
          <CardFooter>
            <Button variant="destructive-outline" size="sm" onClick={onSignOutEverywhere}>Sign out everywhere</Button>
          </CardFooter>
        </Card>

        <FormBar
          dirty={dirty}
          note={dirty ? "Nothing is saved until you save it." : "No changes."}
          label="Save account"
          onCancel={() => { setDraft(blank()); setSubmitted(false); setPhotoError(null); }}
          onSave={() => { setSubmitted(true); if (valid) onSave(draft); }}
        />
      </div>
    );
  }

  /* ── Models and defaults (staged) ──────────────────────────────────── */

  function ModelsScreen({ settings, data, onSave }) {
    const [draft, setDraft] = React.useState(settings);
    React.useEffect(() => { setDraft(settings); }, [settings]);
    const dirty = draft.model !== settings.model || draft.autoAttach !== settings.autoAttach || draft.privateByDefault !== settings.privateByDefault;
    const set = (k, v) => setDraft(Object.assign({}, draft, { [k]: v }));
    const model = modelOf(draft.model);

    return (
      <div className="pl-page" style={{ maxWidth: "48rem" }}>
        <PageHead title="Models and defaults" note="What a new chat starts as. Threads that already exist keep whatever they were set to." />
        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>Default model</CardTitle>
            <CardDescription>Every thread can still be switched in its composer, and switching keeps the conversation.</CardDescription>
          </CardHeader>
          <CardPanel>
            <RadioGroup name="pl-default-model" value={draft.model} onValueChange={(v) => set("model", v)}
              items={MODELS.map((m) => ({
                value: m.value,
                label: m.label + " — " + formatTokens(m.contextTokens) + " window · " + formatRate(m.inRate) + " in, " + formatRate(m.outRate) + " out",
              }))} />
            <p className="pl-foot" style={{ paddingTop: "var(--space-3)" }}>{model.blurb}</p>
          </CardPanel>
        </Card>

        <Card className="pl-card-full">
          <CardHeader>
            <CardTitle>New chats</CardTitle>
            <CardDescription>Two defaults, both of them reversible on any single thread.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="pl-checks">
              <label className="pl-check">
                <Checkbox checked={draft.autoAttach} onCheckedChange={(v) => set("autoAttach", v)} />
                <span className="pl-check__text">
                  <span>Attach the project&rsquo;s files when a chat starts inside one</span>
                  <span className="pl-foot">Only files that indexed. The other {data.files.filter(FILE_FLAGS.needsAttention).length} are never attached to anything.</span>
                </span>
              </label>
              <label className="pl-check">
                <Checkbox checked={draft.privateByDefault} onCheckedChange={(v) => set("privateByDefault", v)} />
                <span className="pl-check__text">
                  <span>Start new chats private</span>
                  <span className="pl-foot">Off means every new thread is readable by all {WORKSPACE.seats} seats from its first turn.</span>
                </span>
              </label>
            </div>
          </CardPanel>
        </Card>

        <FormBar
          dirty={dirty}
          note={dirty ? "Applies to chats started after you save." : "No changes."}
          label="Save defaults"
          onCancel={() => setDraft(settings)}
          onSave={() => onSave(draft)}
        />
      </div>
    );
  }

  /* ── Auth ──────────────────────────────────────────────────────────── */

  function AuthShell({ title, description, children, foot }) {
    return (
      <div className="pl-auth">
        <div className="pl-auth__col">
          <div className="pl-auth__mark">
            <img className="pl-brand__mark pl-brand__mark--lg" src="../../assets/templates/logos/08-logo-demo.svg" alt="" width="28" height="28" />
            <span className="pl-brand__name" style={{ fontSize: "var(--text-base)" }}>Parley</span>
          </div>
          <Card>
            <CardHeader>
              <CardTitle>{title}</CardTitle>
              <CardDescription>{description}</CardDescription>
            </CardHeader>
            <CardPanel>{children}</CardPanel>
          </Card>
          {foot}
        </div>
      </div>
    );
  }

  const EMAIL = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;

  function SignInScreen({ user, onSignIn, onNavigate }) {
    const [values, setValues] = React.useState({ email: user.email, password: "" });
    const [submitted, setSubmitted] = React.useState(false);
    const [rejected, setRejected] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    const errors = {};
    if (!EMAIL.test(values.email.trim())) errors.email = "Enter a valid email address.";
    if (!values.password) errors.password = "Enter your password.";
    const set = (k, v) => { setValues(Object.assign({}, values, { [k]: v })); setRejected(false); };
    const submit = () => {
      setSubmitted(true);
      if (Object.keys(errors).length) return;
      /* One state at a time: a rejection clears the password and never renders
         beside a field error. */
      if (values.password.length < 8) { setRejected(true); setValues(Object.assign({}, values, { password: "" })); return; }
      setPending(true);
      window.setTimeout(() => { setPending(false); onSignIn(); }, 600);
    };
    return (
      <AuthShell
        title="Sign in"
        description={"Parley for " + WORKSPACE.name + "."}
        foot={
          <>
            <p className="pl-auth__switch">New here?<button type="button" className="pl-link" onClick={() => onNavigate("/signup")}>Create account</button></p>
            <p className="pl-auth__foot">Trouble getting in? Ask whoever administers {WORKSPACE.name}, or write to help@parley.app.</p>
          </>
        }
      >
        <div className="pl-fields">
          {rejected && !Object.keys(errors).length ? (
            <Alert variant="error">
              <AlertTitle>Email or password is incorrect</AlertTitle>
              <AlertDescription>Try again, or reset the password.</AlertDescription>
            </Alert>
          ) : null}
          <Field>
            <FieldLabel htmlFor="pl-in-email">Email</FieldLabel>
            <Input id="pl-in-email" type="email" autoComplete="email" value={values.email} invalid={submitted && !!errors.email} onChange={(e) => set("email", e.target.value)} />
            {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : null}
          </Field>
          <Field>
            <span className="pl-auth__label">
              <FieldLabel htmlFor="pl-in-pass">Password</FieldLabel>
              <button type="button" className="pl-link" style={{ fontSize: "var(--text-xs)" }} onClick={() => onNavigate("/forgot-password")}>Forgot password?</button>
            </span>
            <Input id="pl-in-pass" type="password" autoComplete="current-password" value={values.password} invalid={submitted && !!errors.password} onChange={(e) => set("password", e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
            {submitted && errors.password ? <FieldError>{errors.password}</FieldError> : null}
          </Field>
          <Button loading={pending} onClick={submit}>Sign in</Button>
        </div>
      </AuthShell>
    );
  }

  function SignUpScreen({ onSignIn, onNavigate }) {
    const [values, setValues] = React.useState({ name: "", email: "", password: "" });
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    /* One constant, read by the checklist and by validation alike. */
    const rules = [
      { id: "len", label: "At least 8 characters", met: values.password.length >= 8 },
      { id: "num", label: "One number", met: /\d/.test(values.password) },
      { id: "diff", label: "Not your email address", met: values.password.length > 0 && values.password.toLowerCase() !== values.email.toLowerCase() },
    ];
    const errors = {};
    if (!values.name.trim()) errors.name = "Enter the name your colleagues would recognise.";
    if (!EMAIL.test(values.email.trim())) errors.email = "Enter a valid email address.";
    if (rules.some((r) => !r.met)) errors.password = "The password does not meet all three rules yet.";
    const set = (k, v) => setValues(Object.assign({}, values, { [k]: v }));
    const submit = () => {
      setSubmitted(true);
      if (Object.keys(errors).length) return;
      setPending(true);
      window.setTimeout(() => { setPending(false); onSignIn(); }, 600);
    };
    return (
      <AuthShell
        title="Create account"
        description={"You have been invited to " + WORKSPACE.name + " on Parley."}
        foot={<p className="pl-auth__switch">Already have an account?<button type="button" className="pl-link" onClick={() => onNavigate("/signin")}>Sign in</button></p>}
      >
        <div className="pl-fields">
          <Field>
            <FieldLabel htmlFor="pl-up-name">Name</FieldLabel>
            <Input id="pl-up-name" autoComplete="name" placeholder="Nils Sørensen" value={values.name} invalid={submitted && !!errors.name} onChange={(e) => set("name", e.target.value)} />
            {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
          </Field>
          <Field>
            <FieldLabel htmlFor="pl-up-email">Work email</FieldLabel>
            <Input id="pl-up-email" type="email" autoComplete="email" placeholder="you@northgate.co" value={values.email} invalid={submitted && !!errors.email} onChange={(e) => set("email", e.target.value)} />
            {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : null}
          </Field>
          <Field>
            <FieldLabel htmlFor="pl-up-pass">Password</FieldLabel>
            <Input id="pl-up-pass" type="password" autoComplete="new-password" value={values.password} invalid={submitted && !!errors.password} onChange={(e) => set("password", e.target.value)} />
            <div className="pl-auth__checks">
              {rules.map((rule) => (
                <span className="pl-auth__check" key={rule.id} data-met={rule.met}>
                  <Icon name={rule.met ? "check" : "dot"} size={13} />{rule.label}
                </span>
              ))}
            </div>
          </Field>
          <Button loading={pending} onClick={submit}>Create account</Button>
          <p className="pl-auth__foot">By creating an account you agree to the <a href="#/signup">terms</a> and the <a href="#/signup">privacy notice</a>.</p>
        </div>
      </AuthShell>
    );
  }

  function ForgotPasswordScreen({ onSent, onNavigate }) {
    const [email, setEmail] = React.useState("");
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    const error = EMAIL.test(email.trim()) ? null : "Enter a valid email address.";
    const submit = () => {
      setSubmitted(true);
      if (error) return;
      setPending(true);
      window.setTimeout(() => { setPending(false); onSent(email.trim()); }, 600);
    };
    return (
      <AuthShell
        title="Reset password"
        description="We will send a link that works once and expires in an hour."
        foot={<p className="pl-auth__switch">Remembered it?<button type="button" className="pl-link" onClick={() => onNavigate("/signin")}>Sign in</button></p>}
      >
        <div className="pl-fields">
          <Field>
            <FieldLabel htmlFor="pl-fp-email">Email</FieldLabel>
            <Input id="pl-fp-email" type="email" autoComplete="email" value={email} invalid={submitted && !!error} onChange={(e) => setEmail(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") submit(); }} />
            {submitted && error ? <FieldError>{error}</FieldError> : null}
          </Field>
          <Button loading={pending} onClick={submit}>Send reset link</Button>
        </div>
      </AuthShell>
    );
  }

  /* The sent-confirmation is a screen, not a toast: it states the address, the
     expiry, and carries a resend with a real countdown. */
  function CheckEmailScreen({ email, onNavigate }) {
    const [left, setLeft] = React.useState(30);
    React.useEffect(() => {
      if (left <= 0) return undefined;
      const id = window.setTimeout(() => setLeft(left - 1), 1000);
      return () => window.clearTimeout(id);
    }, [left]);
    return (
      <AuthShell
        title="Check your email"
        description={"If an account exists for " + (email || "that address") + ", a reset link is on its way. It expires in an hour and works once."}
        foot={<p className="pl-auth__foot">Still nothing after a few minutes? Check the spam folder, or write to help@parley.app.</p>}
      >
        <div className="pl-fields">
          <Button variant="outline" disabled={left > 0} onClick={() => setLeft(30)}>
            {left > 0 ? "Resend in " + left + "s" : "Resend code"}
          </Button>
          <Button variant="ghost" onClick={() => onNavigate("/signin")}>Back to sign in</Button>
        </div>
      </AuthShell>
    );
  }

  function SignedOutScreen({ user, onNavigate }) {
    return (
      <AuthShell
        title="Signed out"
        description={"This device is signed out of " + WORKSPACE.name + ". Threads and files are untouched."}
        foot={<p className="pl-auth__foot">Signed in as {user.email} until a moment ago.</p>}
      >
        <div className="pl-fields">
          <Button onClick={() => onNavigate("/signin")}>Sign in</Button>
        </div>
      </AuthShell>
    );
  }

  Object.assign(window, { AccountScreen, ModelsScreen, SignInScreen, SignUpScreen, ForgotPasswordScreen, CheckEmailScreen, SignedOutScreen });
})();
