/* Account and auth — the two screens the account menu points at, and the two
   auth screens it leads to.

   Commit model: STAGED on both settings screens. Every control is a form field,
   nothing applies until Save, Save and Cancel are disabled until the form is
   dirty, Cancel appears only once it is, and errors render on validation.

   Auth shell (AGENTS §7.1): its own shell, no navigation owner — no top bar, no
   destinations, no account menu. One layout variant: centred card, the agency
   mark above the form as the only navigation. One credential strategy:
   password. No providers, because this project ships no `assets/providers/`
   marks and §7.4 forbids drawing them. Designed states: idle, field-invalid,
   submitting, credentials-rejected with the attempts left, locked, signed-out.
   The four password-reset screens and the lockout screen live in
   MarqueResetScreens.jsx and are reached from here — nothing is registered that
   the flow cannot get to, and nothing rendered here leads nowhere. MFA and SSO
   remain out of scope, so no screen offers them. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Field, FieldLabel, FieldDescription, FieldError, Input, Button, Badge, Alert, AlertTitle, AlertDescription, Avatar,
  } = window.OriginDesignSystem_7c998b;

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

  function FormBar({ dirty, note, onCancel, onSave, label }) {
    return (
      <div className="mq-formbar">
        <span className="mq-formbar__note">{note}</span>
        {dirty ? <Button variant="outline" onClick={onCancel}>Cancel</Button> : null}
        <Button disabled={!dirty} onClick={onSave}>{label}</Button>
      </div>
    );
  }

  function ProfileScreen({ user, data, now, onNavigate, onSave }) {
    const initial = React.useMemo(() => ({ name: user.name, role: user.role, email: user.email, avatar: user.avatar || null }), [user]);
    const [draft, setDraft] = React.useState(initial);
    const [submitted, setSubmitted] = React.useState(false);
    const [photoError, setPhotoError] = React.useState(null);
    const fileRef = React.useRef(null);
    React.useEffect(() => { setDraft(initial); setSubmitted(false); setPhotoError(null); }, [initial]);
    /* Staged like every other field on this screen: the picked file is read into
       the draft and only reaches the account menu on save, so cancel and the undo
       toast both put the old photo back. */
    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 initialsOf = (name) => name.trim().split(/\s+/).map((w) => w[0]).slice(0, 2).join("").toUpperCase();
    const dirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const errors = {};
    if (!draft.name.trim()) errors.name = "Enter the name brands and creators see.";
    if (!EMAIL.test(draft.email)) errors.email = "Enter a valid email address.";
    const valid = Object.keys(errors).length === 0;
    const mine = data.briefs.filter(BRIEF_FLAGS.isOpen);

    return (
      <div className="mq-page">
        <PageHead path="/account/profile" title="Manager profile" lede={"Your name goes on every pitch that leaves this desk \u2014 " + mine.length + " briefs are open under it right now."} />
        <Card>
          <CardHeader>
            <CardTitle>How you appear</CardTitle>
            <CardDescription>On pitches, contracts and the emails that carry them.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel>Photo</FieldLabel>
                <div className="mq-photo">
                  <Avatar size={64} src={draft.avatar || undefined} alt="" fallback={initialsOf(draft.name || user.name)} />
                  <div className="mq-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="mq-p-name">Name</FieldLabel>
                <Input id="mq-p-name" autoComplete="name" value={draft.name} invalid={submitted && !!errors.name} onChange={(e) => setDraft(Object.assign({}, draft, { name: e.target.value }))} />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-p-role">Title</FieldLabel>
                <Input id="mq-p-role" value={draft.role} onChange={(e) => setDraft(Object.assign({}, draft, { role: e.target.value }))} />
                <FieldDescription>Shown under your name in the account menu and on outgoing pitches.</FieldDescription>
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-p-email">Email</FieldLabel>
                <Input id="mq-p-email" type="email" autoComplete="email" value={draft.email} invalid={submitted && !!errors.email} onChange={(e) => setDraft(Object.assign({}, draft, { email: e.target.value }))} />
                {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : <FieldDescription>Where exports and brand replies are sent.</FieldDescription>}
              </Field>
            </div>
          </CardPanel>
        </Card>
        <FormBar
          dirty={dirty}
          note={dirty ? "Unsaved changes to your profile." : "Everything here is as it was last saved."}
          onCancel={() => { setDraft(initial); setSubmitted(false); setPhotoError(null); }}
          onSave={() => { setSubmitted(true); if (valid) onSave(draft); }}
          label="Save profile"
        />
      </div>
    );
  }

  function AgencyScreen({ agency, data, now, onNavigate, onSave }) {
    const initial = React.useMemo(() => ({ name: agency.name, book: agency.book, billingEmail: agency.billingEmail }), [agency]);
    const [draft, setDraft] = React.useState(initial);
    const [submitted, setSubmitted] = React.useState(false);
    React.useEffect(() => { setDraft(initial); setSubmitted(false); }, [initial]);
    const dirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const errors = {};
    if (!draft.name.trim()) errors.name = "Enter the agency name.";
    if (!draft.book.trim()) errors.book = "Name the cities this book covers.";
    if (!EMAIL.test(draft.billingEmail)) errors.billingEmail = "Enter a valid email address.";
    const valid = Object.keys(errors).length === 0;
    /* Commission is not edited here: every deal stores the rate it was signed
       at, and the ledger reads that. What this screen can honestly show is how
       far the book has drifted from the standard. */
    const standard = AGENCY_POLICY.standardCommissionRate;
    const below = data.deals.filter((deal) => deal.commissionRate < standard);

    return (
      <div className="mq-page">
        <PageHead path="/account/agency" title="Agency and commission" lede={data.deals.length + " deals are on the book, " + data.creators.length + " creators signed to it."} />
        <Card>
          <CardHeader>
            <CardTitle>The agency</CardTitle>
            <CardDescription>What brands see on a pitch and an invoice.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="mq-fields">
              <Field>
                <FieldLabel htmlFor="mq-a-name">Agency name</FieldLabel>
                <Input id="mq-a-name" value={draft.name} invalid={submitted && !!errors.name} onChange={(e) => setDraft(Object.assign({}, draft, { name: e.target.value }))} />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-a-book">The book</FieldLabel>
                <Input id="mq-a-book" value={draft.book} invalid={submitted && !!errors.book} onChange={(e) => setDraft(Object.assign({}, draft, { book: e.target.value }))} />
                {submitted && errors.book ? <FieldError>{errors.book}</FieldError> : <FieldDescription>The cities this roster is sold in. Shown above the roster.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel htmlFor="mq-a-billing">Billing email</FieldLabel>
                <Input id="mq-a-billing" type="email" value={draft.billingEmail} invalid={submitted && !!errors.billingEmail} onChange={(e) => setDraft(Object.assign({}, draft, { billingEmail: e.target.value }))} />
                {submitted && errors.billingEmail ? <FieldError>{errors.billingEmail}</FieldError> : <FieldDescription>Where brands are told to send remittances. Net {AGENCY_POLICY.paymentTermsDays} from issue.</FieldDescription>}
              </Field>
            </div>
          </CardPanel>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Commission</CardTitle>
            <CardDescription>The standard rate is {Math.round(standard * 100)}%. It is not edited here: every deal stores the rate it was signed at, and the money ledgers read that rate rather than this one.</CardDescription>
          </CardHeader>
          <CardPanel>
            <dl className="mq-kv">
              <div><dt>Standard rate</dt><dd>{Math.round(standard * 100)}%</dd></div>
              <div><dt>Deals signed below it</dt><dd>{below.length} of {data.deals.length}</dd></div>
              {below.map((deal) => (
                <div key={deal.id}><dt>{deal.brand} · {deal.id}</dt><dd>{Math.round(deal.commissionRate * 100)}%</dd></div>
              ))}
            </dl>
          </CardPanel>
          <CardFooter className="mq-card-footer">
            <span className="mq-note">Changing a rate means renegotiating a deal, which happens on the deal sheet.</span>
            <Button variant="outline" size="sm" onClick={() => onNavigate("/money")}>Open the ledgers</Button>
          </CardFooter>
        </Card>

        <FormBar
          dirty={dirty}
          note={dirty ? "Unsaved changes to " + initial.name + "." : "Everything here is as it was last saved."}
          onCancel={() => { setDraft(initial); setSubmitted(false); }}
          onSave={() => { setSubmitted(true); if (valid) onSave(draft); }}
          label="Save agency"
        />
      </div>
    );
  }

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

  function AuthShell({ agency, children, footer }) {
    return (
      <div className="mq-auth">
        <div className="mq-auth__col">
          <div className="mq-auth__mark">
            <img className="mq-auth__logo" src="../../assets/templates/logos/27-logo-demo.svg" alt="" width="40" height="40" />
            <span className="mq-auth__words">
              <span className="mq-brand__name">{agency.name}</span>
              <span className="mq-brand__desk">{agency.desk}</span>
            </span>
          </div>
          {children}
          {footer ? <p className="mq-auth__foot">{footer}</p> : null}
        </div>
      </div>
    );
  }

  function SignInScreen({ agency, user, onSignIn, onNavigate }) {
    const [values, setValues] = React.useState({ email: "", password: "" });
    const [submitted, setSubmitted] = React.useState(false);
    const [pending, setPending] = React.useState(false);
    /* Rejections are counted, not just reported: the copy names how many tries
       are left and the last one lands on /account-locked (AGENTS §7.3.6). The
       demo desk accepts the signed-in manager's own address. */
    const [rejected, setRejected] = React.useState(0);
    const errors = {};
    if (!EMAIL.test(values.email)) errors.email = "Enter a valid email address.";
    if (values.password.length < 8) errors.password = "Your password is at least 8 characters.";
    const valid = Object.keys(errors).length === 0;
    const dirty = values.email !== "" || values.password !== "";
    const left = AGENCY_POLICY.signInAttempts - rejected;
    const submit = () => {
      setSubmitted(true);
      if (!valid) return;
      setPending(true);
      window.setTimeout(() => {
        setPending(false);
        if (values.email.trim().toLowerCase() === user.email.toLowerCase()) { onSignIn(); return; }
        const used = rejected + 1;
        setRejected(used);
        setValues({ email: values.email, password: "" });
        setSubmitted(false);
        if (used >= AGENCY_POLICY.signInAttempts) onNavigate("/account-locked");
      }, 600);
    };
    return (
      <AuthShell agency={agency} footer="The desk, the book and the money in one place.">
        <Card>
          <CardHeader>
            <CardTitle>Sign in</CardTitle>
            <CardDescription>To the {agency.desk.toLowerCase()} at {agency.name}.</CardDescription>
          </CardHeader>
          <CardPanel>
            {/* One state at a time: a rejection replaces the field errors rather
                than stacking with them (§7.3.3), which is why submitted resets
                on a rejection. */}
            {rejected > 0 && !submitted ? (
              <Alert variant="error" style={{ marginBottom: "var(--space-5)" }}>
                <AlertTitle>Email or password is incorrect</AlertTitle>
                <AlertDescription>{left} {left === 1 ? "attempt" : "attempts"} left before the account locks for fifteen minutes.</AlertDescription>
              </Alert>
            ) : null}
            <form className="mq-fields" onSubmit={(e) => { e.preventDefault(); submit(); }}>
              <Field>
                <FieldLabel htmlFor="mq-signin-email">Email</FieldLabel>
                <Input id="mq-signin-email" type="email" autoComplete="email" placeholder={user.email} value={values.email}
                  invalid={submitted && !!errors.email} onChange={(e) => setValues(Object.assign({}, values, { email: e.target.value }))} />
                {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : null}
              </Field>
              <Field>
                <div className="mq-fieldrow">
                  <FieldLabel htmlFor="mq-signin-password">Password</FieldLabel>
                  <button type="button" className="mq-link" onClick={() => onNavigate("/forgot-password")}>Forgot password?</button>
                </div>
                <Input id="mq-signin-password" type="password" autoComplete="current-password" value={values.password}
                  invalid={submitted && !!errors.password} onChange={(e) => setValues(Object.assign({}, values, { password: e.target.value }))} />
                {submitted && errors.password ? <FieldError>{errors.password}</FieldError> : null}
              </Field>
              <Button type="submit" loading={pending} disabled={!dirty || pending}>Sign in</Button>
            </form>
          </CardPanel>
        </Card>
      </AuthShell>
    );
  }

  function SignedOutScreen({ agency, user, onSignIn }) {
    return (
      <AuthShell agency={agency} footer="Pitches already sent stay sent; nothing on the desk changed.">
        <Card>
          <CardHeader>
            <CardTitle>You are signed out</CardTitle>
            <CardDescription>{user.name} was signed out of the {agency.name} {agency.desk.toLowerCase()}.</CardDescription>
          </CardHeader>
          <CardPanel>
            <Button onClick={onSignIn}>Sign in</Button>
          </CardPanel>
        </Card>
      </AuthShell>
    );
  }

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