/* Account — the screens behind the account menu. The auth screens live in
   AuthScreens.jsx, because they share a shell with each other and nothing with
   these. Originally: the screens behind the account menu, plus the two auth
   screens that menu leads to.

   Commit model: STAGED, on all three 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 rather than on first paint.

   Auth shell (AGENTS §7.1): its own shell, no navigation owner — no sidebar, no
   toolbar, no account menu. One layout variant for the product: centred card,
   the product 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, and signed-out. Rate limiting, lockout, MFA
   and the four password-reset screens are out of scope for this template, so
   nothing links to them. */
(() => {
  const {
    Card, CardHeader, CardTitle, CardDescription, CardPanel, CardFooter,
    Field, FieldLabel, FieldDescription, FieldError, Input, InputGroup, InputGroupAddon, InputGroupInput, RadioGroup, Checkbox, Button, Separator, Badge, Avatar,
  } = window.OriginDesignSystem_7c998b;

  const MAX_PHOTO_BYTES = 2 * 1024 * 1024;

  /* The photo is a form field like any other: picking one stages a data URL on
     the draft and nothing reaches the member record until Save, so Cancel puts
     the old face back. Drop or click — one control, two ways in, and the file
     input stays the real, accessible one rather than being replaced by a div. */
  function PhotoField({ name, value, initial, onChange, error }) {
    const input = React.useRef(null);
    const [over, setOver] = React.useState(false);
    const take = (file) => { if (file) onChange(file); };
    const initials = name.trim().split(/\s+/).map((w) => w[0]).slice(0, 2).join("") || "?";
    return (
      <div
        className={"fd-photo" + (over ? " fd-photo--over" : "")}
        onDragOver={(e) => { e.preventDefault(); setOver(true); }}
        onDragLeave={() => setOver(false)}
        onDrop={(e) => { e.preventDefault(); setOver(false); take(e.dataTransfer.files && e.dataTransfer.files[0]); }}
      >
        <Avatar size={64} src={value} alt="" fallback={initials} />
        <div className="fd-photo__body">
          <span className="fd-photo__note">
            {value === initial
              ? (value ? "The photo on your account." : "No photo yet — your initials stand in wherever a face appears.")
              : (value ? "New photo staged. It is not on your account until you save." : "Your photo will be removed when you save.")}
          </span>
          <span className="fd-photo__actions">
            <Button variant="outline" size="sm" onClick={() => input.current && input.current.click()}>
              <Icon name="upload" size={14} />{value ? "Replace" : "Upload a photo"}
            </Button>
            {value ? <Button variant="ghost" size="sm" onClick={() => onChange(null)}>Remove</Button> : null}
            {value !== initial ? <Button variant="ghost" size="sm" onClick={() => onChange(initial)}>Undo</Button> : null}
          </span>
          {error
            ? <FieldError>{error}</FieldError>
            : <span className="fd-footnote">Drop an image here, or pick one. JPG, PNG or WebP; square reads best; up to 2 MB.</span>}
        </div>
        <input ref={input} className="fd-photo__input" type="file" accept="image/png,image/jpeg,image/webp"
          aria-label="Choose a profile photo"
          onChange={(e) => { take(e.target.files && e.target.files[0]); e.target.value = ""; }} />
      </div>
    );
  }

  /* ── Settings ─────────────────────────────────────────────────────────── */

  function ProfileScreen({ profile, onSave }) {
    const initial = React.useMemo(() => ({ name: profile.name, role: profile.role, email: profile.email, avatar: profile.avatar || null }), [profile]);
    const [draft, setDraft] = React.useState(initial);
    const [submitted, setSubmitted] = React.useState(false);
    const [photoError, setPhotoError] = React.useState(null);
    React.useEffect(() => { setDraft(initial); setSubmitted(false); setPhotoError(null); }, [initial]);
    const set = (fields) => setDraft((d) => Object.assign({}, d, fields));
    const dirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const errors = {};
    if (!draft.name.trim()) errors.name = "Enter the name your team will see.";
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draft.email)) errors.email = "Enter a valid email address.";
    const valid = Object.keys(errors).length === 0;

    /* A File is read into a data URL so the preview is the real image rather
       than a stand-in — and rejected here, not on save, because the person is
       looking at the control at the moment they choose. */
    const takePhoto = (file) => {
      if (file === null || typeof file === "string") { setPhotoError(null); set({ avatar: file }); return; }
      if (!/^image\/(png|jpe?g|webp)$/.test(file.type)) { setPhotoError("That is a " + (file.type || "file") + ". Use a JPG, PNG or WebP."); return; }
      if (file.size > MAX_PHOTO_BYTES) { setPhotoError("That image is " + (file.size / 1048576).toFixed(1) + " MB. The limit is 2 MB."); return; }
      const reader = new FileReader();
      reader.onload = () => { setPhotoError(null); set({ avatar: reader.result }); };
      reader.onerror = () => setPhotoError("That file could not be read. Try another.");
      reader.readAsDataURL(file);
    };

    return (
      <div className="fd-page">
        <PageHeader path="/settings/profile" title="Your profile" />
        <Card>
          <CardHeader>
            <CardTitle>How you appear in {MERIDIAN_WORKSPACE.name}</CardTitle>
            <CardDescription>Your name and role sit on every approval and rejection you make.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="fd-fields">
              <Field>
                <FieldLabel>Photo</FieldLabel>
                <PhotoField name={draft.name} value={draft.avatar} initial={initial.avatar} onChange={takePhoto} error={photoError} />
              </Field>
              <Field>
                <FieldLabel htmlFor="fd-name">Name</FieldLabel>
                <Input id="fd-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="fd-role">Role</FieldLabel>
                <Input id="fd-role" value={draft.role} onChange={(e) => set({ role: e.target.value })} />
                <FieldDescription>Shown under your name in the account menu.</FieldDescription>
              </Field>
              <Field>
                <FieldLabel htmlFor="fd-email">Email</FieldLabel>
                <Input id="fd-email" type="email" autoComplete="email" value={draft.email} invalid={submitted && !!errors.email} onChange={(e) => set({ email: e.target.value })} />
                {submitted && errors.email ? <FieldError>{errors.email}</FieldError> : <FieldDescription>Where exports and alerts 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 WorkspaceSettingsScreen({ workspace, payouts, onSave }) {
    const initial = React.useMemo(() => ({ name: workspace.name, descriptor: workspace.descriptor, schedule: workspace.schedule }), [workspace]);
    const [draft, setDraft] = React.useState(initial);
    const [submitted, setSubmitted] = React.useState(false);
    React.useEffect(() => { setDraft(initial); setSubmitted(false); }, [initial]);
    const set = (fields) => setDraft((d) => Object.assign({}, d, fields));
    const dirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const errors = {};
    if (!draft.name.trim()) errors.name = "Enter the workspace name.";
    if (draft.descriptor.trim().length < 5 || draft.descriptor.length > 22) errors.descriptor = "Between 5 and 22 characters — it has to fit on a card statement.";
    const valid = Object.keys(errors).length === 0;
    const waiting = awaitingApprovalPayouts(payouts);

    return (
      <div className="fd-page">
        <PageHeader path="/settings" title="Workspace settings" />
        <Card>
          <CardHeader>
            <CardTitle>{workspace.name}</CardTitle>
            <CardDescription>On the {workspace.plan} plan. These settings apply to everybody in the workspace.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="fd-fields">
              <Field>
                <FieldLabel htmlFor="fd-ws-name">Workspace name</FieldLabel>
                <Input id="fd-ws-name" value={draft.name} invalid={submitted && !!errors.name} onChange={(e) => set({ name: e.target.value })} />
                {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : null}
              </Field>
              <Field>
                <FieldLabel htmlFor="fd-ws-desc">Statement descriptor</FieldLabel>
                <Input id="fd-ws-desc" value={draft.descriptor} invalid={submitted && !!errors.descriptor} onChange={(e) => set({ descriptor: e.target.value.toUpperCase() })} />
                {submitted && errors.descriptor
                  ? <FieldError>{errors.descriptor}</FieldError>
                  : <FieldDescription>What customers see on their statement. {22 - draft.descriptor.length} characters left.</FieldDescription>}
              </Field>
              <Field>
                <FieldLabel>Payout schedule</FieldLabel>
                <RadioGroup name="fd-ws-schedule" items={PAYOUT_SCHEDULES} value={draft.schedule} onValueChange={(schedule) => set({ schedule: schedule })} />
                <FieldDescription>
                  {(PAYOUT_SCHEDULES.find((s) => s.value === draft.schedule) || {}).note}
                  {draft.schedule !== initial.schedule && waiting.length
                    ? " The " + waiting.length + " payouts already waiting on approval keep the old schedule."
                    : ""}
                </FieldDescription>
              </Field>
            </div>
          </CardPanel>
        </Card>
        <FormBar
          dirty={dirty}
          note={dirty ? "Unsaved changes to " + initial.name + "." : "Everything here is as it was last saved."}
          onCancel={() => { setDraft(initial); setSubmitted(false); setPhotoError(null); }}
          onSave={() => { setSubmitted(true); if (valid) onSave(draft); }}
          label="Save workspace"
        />
      </div>
    );
  }

  function NotificationsScreen({ profile, data, onSave }) {
    const initial = React.useMemo(() => ({ notify: profile.notify.slice() }), [profile]);
    const [draft, setDraft] = React.useState(initial);
    React.useEffect(() => { setDraft(initial); }, [initial]);
    const dirty = JSON.stringify(draft) !== JSON.stringify(initial);
    const toggle = (value) => setDraft((d) => ({ notify: d.notify.indexOf(value) > -1 ? d.notify.filter((v) => v !== value) : d.notify.concat([value]) }));
    /* What each preference would have told you, from the real arrays. */
    const counts = {
      payout_approval: approvablePayouts(data.payouts, data.approver).length + " payouts are waiting on you now",
      dispute_evidence: disputesNeedingEvidence(data.disputes).length + " disputes need evidence now",
      payment_failed: failedPayments(data.payments).length + " payments have failed in the fixture",
      balance_low: "The balance is " + formatMoney(data.balance.availableCents) + ", well above the floor",
    };

    return (
      <div className="fd-page">
        <PageHeader path="/settings/notifications" title="Notification preferences" />
        <Card>
          <CardHeader>
            <CardTitle>What we email {profile.name.split(" ")[0]}</CardTitle>
            <CardDescription>Checkboxes, because they are saved with the rest of the form rather than one at a time.</CardDescription>
          </CardHeader>
          <CardPanel>
            <div className="fd-checks">
              {NOTIFICATION_KINDS.map((kind) => (
                <label className="fd-check" key={kind.value}>
                  <Checkbox checked={draft.notify.indexOf(kind.value) > -1} onCheckedChange={() => toggle(kind.value)} />
                  <span className="fd-check__text">
                    <span>{kind.label}</span>
                    <span className="fd-footnote">{counts[kind.value]}.</span>
                  </span>
                </label>
              ))}
            </div>
          </CardPanel>
          <CardFooter className="fd-card-footer">
            <span className="fd-footnote">{draft.notify.length} of {NOTIFICATION_KINDS.length} selected. Nothing is sent for the rest.</span>
          </CardFooter>
        </Card>
        <FormBar
          dirty={dirty}
          note={dirty ? "Unsaved changes to your notifications." : "Everything here is as it was last saved."}
          onCancel={() => setDraft(initial)}
          onSave={() => onSave(draft)}
          label="Save notification preferences"
        />
      </div>
    );
  }

  Object.assign(window, { ProfileScreen, WorkspaceSettingsScreen, NotificationsScreen });
})();
