/* Your profile — the one screen that is about you rather than the hospital.
   Commit model: STAGED. The photograph, the name and the extension are all form
   fields; nothing is written until Save, so a picture dropped here is a preview
   until then. A staged screen may not hold an instant control, which is why
   "remove photograph" clears the field rather than saving anything. */
(() => {
  const {
    Button, Badge, Avatar, Input, Field, FieldLabel, FieldDescription, FieldError,
  } = window.OriginDesignSystem_7c998b;

  /* Four photographs already in the badge system, offered as the alternative to
     uploading one. */
  const PHOTO_CHOICES = [
    "../../assets/img/avatar-f-5.jpg",
    "../../assets/img/avatar-f-9.jpg",
    "../../assets/img/avatar-f-13.jpg",
    "../../assets/img/avatar-f-17.jpg",
  ];

  const MAX_PHOTO_KB = 2048;

  /* The upload control: one real file input, a drop zone that is also its label
     so the keyboard reaches it, and a preview. It validates type and size and
     says what it found; it never writes anything itself. */
  function PhotoUpload({ value, name, fileName, onPick, onClear, error, onError }) {
    const [over, setOver] = React.useState(false);
    const inputRef = React.useRef(null);

    const take = (file) => {
      if (!file) return;
      if (file.type.indexOf("image/") !== 0) {
        onError("That is a " + (file.type || "file with no type") + ". Use a JPEG or a PNG.");
        return;
      }
      if (file.size / 1024 > MAX_PHOTO_KB) {
        onError("That photograph is " + Math.round(file.size / 1024 / 1024 * 10) / 10 + " MB. The limit is 2 MB — the badge system rescales anything larger.");
        return;
      }
      const reader = new FileReader();
      reader.onload = () => { onError(null); onPick(String(reader.result), file.name); };
      reader.onerror = () => onError("That file could not be read. Try saving it again and re-uploading.");
      reader.readAsDataURL(file);
    };

    return (
      <div className="hd-upload">
        <span className="hd-preview">
          <Avatar size={72} src={value || undefined} alt={value ? "Your photograph" : ""} fallback={initialsOf(name)} />
          <span className="hd-footnote">{value ? (fileName || "On the badge system") : "No photograph"}</span>
        </span>
        <label className="hd-drop" data-over={over ? "true" : "false"} data-invalid={error ? "true" : "false"}
          onDragOver={(e) => { e.preventDefault(); setOver(true); }}
          onDragLeave={() => setOver(false)}
          onDrop={(e) => { e.preventDefault(); setOver(false); take(e.dataTransfer.files && e.dataTransfer.files[0]); }}>
          <Icon name="image-up" size={20} />
          <span className="hd-drop__title">Drop a photograph here, or choose a file</span>
          <span className="hd-footnote">JPEG or PNG, up to 2 MB. It is stored on the badge system and shown beside everything you write.</span>
          <input ref={inputRef} type="file" accept="image/jpeg,image/png" aria-label="Upload a photograph"
            onChange={(e) => { take(e.target.files && e.target.files[0]); e.target.value = ""; }} />
          <span className="hd-actions__row" style={{ marginTop: "var(--space-1)" }}>
            <Button size="sm" variant="outline" onClick={(e) => { e.preventDefault(); inputRef.current && inputRef.current.click(); }}>Choose a file</Button>
            {value ? <Button size="sm" variant="ghost" onClick={(e) => { e.preventDefault(); onError(null); onClear(); }}>Remove photograph</Button> : null}
          </span>
        </label>
      </div>
    );
  }

  function MyProfileScreen({ data, now, viewer, onSave, onNavigate }) {
    const initial = { name: viewer.name, jobTitle: viewer.jobTitle, phone: viewer.phone, avatar: viewer.avatar || null };
    const [values, setValues] = React.useState(initial);
    const [fileName, setFileName] = React.useState(null);
    const [photoError, setPhotoError] = React.useState(null);
    const [submitted, setSubmitted] = React.useState(false);
    React.useEffect(() => {
      setValues({ name: viewer.name, jobTitle: viewer.jobTitle, phone: viewer.phone, avatar: viewer.avatar || null });
      setFileName(null); setPhotoError(null); setSubmitted(false);
    }, [viewer]);
    const set = (id, value) => setValues((v) => Object.assign({}, v, { [id]: value }));
    const dirty = Object.keys(initial).some((key) => values[key] !== initial[key]);

    const errors = {};
    if (!values.name.trim() || values.name.trim().split(/\s+/).length < 2) errors.name = "Enter the name colleagues will see beside your notes.";
    if (!values.jobTitle.trim()) errors.jobTitle = "Your job title appears beside every note you write.";
    if (!/^ext \d{3,5}$/.test(values.phone.trim())) errors.phone = "Use the form ext 4380.";
    const valid = Object.keys(errors).length === 0;
    const written = commentsByAuthor(data.comments, viewer.id);

    return (
      <>
        <PageHeader path="/me/profile" title="Your profile"
          sub={"What colleagues see beside the " + written.length + (written.length === 1 ? " note you have written" : " notes you have written") + ". Your role, your ward and your access are set by a coordinator on Employees."}
          actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/settings")}>Hospital settings</Button>} />

        <Band title="Photograph" note="Shown on every note, every row and every record you touch — and on your badge.">
          <PhotoUpload
            value={values.avatar}
            name={values.name}
            fileName={fileName}
            error={photoError}
            onError={setPhotoError}
            onPick={(dataUrl, name) => { set("avatar", dataUrl); setFileName(name); }}
            onClear={() => { set("avatar", null); setFileName(null); }}
          />
          {photoError ? <p className="hd-footnote hd-danger" style={{ marginTop: "var(--space-3)" }}>{photoError}</p> : null}
          <div className="hd-photos" style={{ marginTop: "var(--space-4)" }}>
            <span className="hd-footnote" style={{ width: "100%" }}>Or use one already on the badge system:</span>
            {PHOTO_CHOICES.map((src) => {
              const on = values.avatar === src;
              return (
                <button type="button" key={src} className="hd-photo" aria-pressed={on}
                  aria-label={on ? "Badge photograph, selected" : "Use this badge photograph"}
                  onClick={() => { setPhotoError(null); set("avatar", src); setFileName(null); }}>
                  <Avatar size={46} src={src} alt="" fallback={initialsOf(values.name)} />
                </button>
              );
            })}
          </div>
        </Band>

        <Band title="What colleagues see">
          <div className="hd-fields">
            <Field>
              <FieldLabel htmlFor="hd-me-name">Name</FieldLabel>
              <Input id="hd-me-name" value={values.name} invalid={submitted && !!errors.name} onChange={(e) => set("name", e.target.value)} />
              {submitted && errors.name ? <FieldError>{errors.name}</FieldError> : <FieldDescription>Saving rewrites your name beside every note you have already written.</FieldDescription>}
            </Field>
            <Field>
              <FieldLabel htmlFor="hd-me-title">Job title</FieldLabel>
              <Input id="hd-me-title" value={values.jobTitle} invalid={submitted && !!errors.jobTitle} onChange={(e) => set("jobTitle", e.target.value)} />
              {submitted && errors.jobTitle ? <FieldError>{errors.jobTitle}</FieldError> : null}
            </Field>
            <Field>
              <FieldLabel htmlFor="hd-me-phone">Extension</FieldLabel>
              <Input id="hd-me-phone" value={values.phone} placeholder="ext 4380" invalid={submitted && !!errors.phone} onChange={(e) => set("phone", e.target.value)} />
              {submitted && errors.phone ? <FieldError>{errors.phone}</FieldError> : <FieldDescription>Reachable from any ward phone.</FieldDescription>}
            </Field>
          </div>
        </Band>

        <Band tint title="Set by somebody else" note="These decide what you can do in Ward Desk; a coordinator changes them on Employees, and the rules themselves live in Settings.">
          <Pairs items={[
            { label: "Email", value: viewer.email },
            { label: "What you may do", value: labelOf(STAFF_ROLES, viewer.staffRole) },
            { label: "Job family", value: labelOf(JOB_FAMILIES, viewer.family) },
            { label: "Base ward", value: viewer.ward ? wardName(viewer.ward) : "No base ward" },
            { label: "Employment", value: <StatusBadge values={STAFF_STATUS} value={viewer.status} /> },
            { label: "Your record", value: <button type="button" className="hd-linkbtn" onClick={() => onNavigate("/employees/" + viewer.id)}>Open it on Employees</button> },
          ]} />
        </Band>

        <FormBar dirty={dirty} label="Save profile"
          note={values.avatar && values.avatar.indexOf("data:") === 0 ? "The photograph you dropped is a preview until you save." : "Saving rewrites your name and picture beside every note you have written."}
          onCancel={() => { setValues(initial); setFileName(null); setPhotoError(null); setSubmitted(false); }}
          onSave={() => { setSubmitted(true); if (valid) onSave(values); }} />
      </>
    );
  }

  Object.assign(window, { MyProfileScreen, PhotoUpload, PHOTO_CHOICES, MAX_PHOTO_KB });
})();
