// Profile modal: name, avatar, settings, change-password, log-out-everywhere.
(function () {
  const { useState, useRef } = React;
  const S = window.KomonichiState;
  const Loader = window.KomonichiLoader;

  function ProfileButton({ onOpen }) {
    const [state] = S.useKomonichi();
    const avatar = state.profile && state.profile.avatar_url;
    const name = (state.profile && state.profile.display_name) || "you";
    return React.createElement("button", {
      className: "profile-chip",
      onClick: onOpen,
      title: "profile",
    },
      avatar
        ? React.createElement("img", { src: avatar, alt: "" })
        : React.createElement("span", { className: "profile-chip-letter" }, (name[0] || "·").toUpperCase()),
      React.createElement("span", { className: "label", style: { marginLeft: 8 } }, name)
    );
  }

  function ProfileModal({ open, onClose }) {
    const [state] = S.useKomonichi();
    const [tab, setTab] = useState("profile");
    const [busy, setBusy] = useState(false);
    const [err, setErr]   = useState(null);
    const [name, setName] = useState((state.profile && state.profile.display_name) || "");
    const [cropFile, setCropFile] = useState(null);
    const fileRef = useRef(null);

    const settings = state.settings;

    if (!open) return null;

    async function saveName() {
      setBusy(true); setErr(null);
      try { await S.actions.setDisplayName(name); }
      catch (e) { setErr(e.message); }
      finally { setBusy(false); }
    }
    function pickAvatar(e) {
      const f = e.target.files && e.target.files[0];
      if (f) setCropFile(f);
      if (fileRef.current) fileRef.current.value = "";
    }
    async function commitCrop(dataUri) {
      setCropFile(null);
      setBusy(true); setErr(null);
      try { await Loader.wrap(S.actions.uploadAvatarDataUri(dataUri), { label: "uploading" }); }
      catch (e) { setErr(e.message); }
      finally { setBusy(false); }
    }
    async function clearAvatar() {
      setBusy(true); setErr(null);
      try { await S.actions.clearAvatar(); }
      catch (e) { setErr(e.message); }
      finally { setBusy(false); }
    }
    async function saveSetting(key, value) {
      try { await S.actions.setSettings({ [key]: value }); } catch (e) { setErr(e.message); }
    }
    async function logoutEverywhere() {
      setBusy(true);
      try { await fetch("/api/auth/logout-everywhere", { method: "POST", credentials: "include", headers: { Authorization: "Bearer " + S.getAccess() } }); }
      finally { setBusy(false); doLogout(); }
    }
    async function doLogout() {
      try { await fetch("/api/auth/logout", { method: "POST", credentials: "include" }); } catch {}
      S.setAccess(null); location.hash = "#login"; location.reload();
    }

    return React.createElement("div", { className: "profile-overlay", onClick: onClose },
      React.createElement("div", { className: "profile-modal card", onClick: (e) => e.stopPropagation() },
        React.createElement("div", { className: "cap" },
          React.createElement("h3", { className: "title" }, "your ",
            React.createElement("span", { className: "em" }, "profile")),
          React.createElement("button", { className: "btn ghost tiny", onClick: onClose }, "close")
        ),
        React.createElement("nav", { className: "profile-tabs" },
          ["profile", "settings", "security"].map((k) =>
            React.createElement("button", {
              key: k, className: "tab" + (tab === k ? " active" : ""), onClick: () => setTab(k),
            }, k)
          )
        ),

        tab === "profile" && React.createElement("div", { className: "profile-body" },
          React.createElement("div", { className: "profile-row" },
            React.createElement("div", { className: "label" }, "display name"),
            React.createElement("input", { className: "f", value: name, onChange: (e) => setName(e.target.value) }),
            React.createElement("button", { className: "btn tiny", onClick: saveName, disabled: busy }, "save")
          ),
          React.createElement("div", { className: "profile-row" },
            React.createElement("div", { className: "label" }, "avatar"),
            React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
              React.createElement("input", { ref: fileRef, type: "file", accept: "image/*", onChange: pickAvatar, style: { display: "none" } }),
              React.createElement("button", { className: "btn ghost tiny", onClick: () => fileRef.current && fileRef.current.click() }, "choose image"),
              state.profile && state.profile.avatar_url
                ? React.createElement("button", { className: "btn ghost tiny", onClick: clearAvatar, disabled: busy }, "remove")
                : null
            ),
            state.profile && state.profile.avatar_url
              ? React.createElement("img", { src: state.profile.avatar_url, alt: "", className: "profile-avatar-preview" })
              : null
          )
        ),

        tab === "settings" && React.createElement("div", { className: "profile-body" },
          React.createElement(SliderRow, {
            label: "daily focus target",
            value: settings.daily_focus_target_min,
            min: 30, max: 480, step: 15, unit: "min",
            onChange: (v) => saveSetting("daily_focus_target_min", v),
          }),
          React.createElement(SliderRow, {
            label: "pomodoro length",
            value: settings.pomodoro_min,
            min: 5, max: 90, step: 5, unit: "min",
            onChange: (v) => saveSetting("pomodoro_min", v),
          }),
          React.createElement(SliderRow, {
            label: "break length",
            value: settings.break_min,
            min: 1, max: 30, step: 1, unit: "min",
            onChange: (v) => saveSetting("break_min", v),
          })
        ),

        tab === "security" && React.createElement(SecurityTab, { onLogout: doLogout, onLogoutEverywhere: logoutEverywhere }),

        err ? React.createElement("div", { className: "auth-err" }, err) : null,
        cropFile && window.AvatarCropper
          ? React.createElement(window.AvatarCropper, {
              file: cropFile,
              onCancel: () => setCropFile(null),
              onCommit: commitCrop,
            })
          : null
      )
    );
  }

  function SliderRow({ label, value, min, max, step, unit, onChange }) {
    const [v, setV] = useState(value);
    React.useEffect(() => setV(value), [value]);
    return React.createElement("div", { className: "profile-row" },
      React.createElement("div", { className: "label" }, label),
      React.createElement("input", {
        type: "range", min, max, step, value: v,
        onChange: (e) => setV(Number(e.target.value)),
        onMouseUp:   (e) => onChange(Number(e.target.value)),
        onTouchEnd:  (e) => onChange(Number(e.target.value)),
      }),
      React.createElement("span", { className: "num" }, v + " " + unit)
    );
  }

  function SecurityTab({ onLogout, onLogoutEverywhere }) {
    const [cur, setCur] = useState("");
    const [pw, setPw]   = useState("");
    const [msg, setMsg] = useState(null);
    const [busy, setBusy] = useState(false);
    const [delOpen, setDelOpen] = useState(false);
    const [delPw, setDelPw]     = useState("");
    const [delConfirm, setDelConfirm] = useState("");
    const [delErr, setDelErr]   = useState(null);

    async function deleteAccount(e) {
      e.preventDefault(); setDelErr(null); setBusy(true);
      try {
        await S.actions.deleteAccount({ password: delPw });
        location.hash = "#login"; location.reload();
      } catch (e) {
        setDelErr(e.message);
        setBusy(false);
      }
    }
    async function changePassword(e) {
      e.preventDefault(); setBusy(true); setMsg(null);
      try {
        const r = await fetch("/api/auth/change-password", {
          method: "POST", credentials: "include",
          headers: { "Content-Type": "application/json", Authorization: "Bearer " + window.KomonichiState.getAccess() },
          body: JSON.stringify({ current_password: cur, new_password: pw }),
        });
        if (!r.ok) { const b = await r.json().catch(() => ({})); throw new Error((b.error && b.error.message) || "failed"); }
        setMsg("password updated — you'll need to sign in again.");
        setTimeout(onLogout, 1500);
      } catch (e) { setMsg(e.message); } finally { setBusy(false); }
    }
    return React.createElement("div", { className: "profile-body" },
      React.createElement("form", { onSubmit: changePassword },
        React.createElement("div", { className: "profile-row" },
          React.createElement("div", { className: "label" }, "current password"),
          React.createElement("input", { className: "f", type: "password", value: cur, onChange: (e) => setCur(e.target.value) })
        ),
        React.createElement("div", { className: "profile-row" },
          React.createElement("div", { className: "label" }, "new password"),
          React.createElement("input", { className: "f", type: "password", value: pw, onChange: (e) => setPw(e.target.value) })
        ),
        React.createElement("div", { style: { marginTop: 10 } },
          React.createElement("button", { className: "btn warm", type: "submit", disabled: busy || pw.length < 8 }, "change password")
        )
      ),
      React.createElement("div", { className: "dashed", style: { marginTop: 22, paddingTop: 14 } },
        React.createElement("button", { className: "btn ghost", onClick: onLogout }, "sign out"),
        " ",
        React.createElement("button", { className: "btn", onClick: onLogoutEverywhere }, "sign out everywhere")
      ),
      msg ? React.createElement("div", { className: "auth-err" }, msg) : null,

      React.createElement("div", { className: "danger-zone" },
        React.createElement("div", { className: "label", style: { color: "var(--persimmon)" } }, "danger zone"),
        !delOpen
          ? React.createElement("button", {
              className: "btn warm", style: { marginTop: 10 },
              onClick: () => setDelOpen(true),
            }, "delete my account")
          : React.createElement("form", { onSubmit: deleteAccount, style: { marginTop: 12 } },
              React.createElement("p", { className: "haiku", style: { fontSize: 13 } },
                "This erases every task, objective, area, note, session, badge, and learn-progress row. There is no undo."),
              React.createElement("div", { className: "profile-row" },
                React.createElement("div", { className: "label" }, "password"),
                React.createElement("input", { className: "f", type: "password", value: delPw, onChange: (e) => setDelPw(e.target.value) })
              ),
              React.createElement("div", { className: "profile-row" },
                React.createElement("div", { className: "label" }, "type DELETE"),
                React.createElement("input", { className: "f", value: delConfirm, onChange: (e) => setDelConfirm(e.target.value) })
              ),
              delErr ? React.createElement("div", { className: "auth-err" }, delErr) : null,
              React.createElement("div", { style: { marginTop: 10, display: "flex", gap: 8 } },
                React.createElement("button", { type: "button", className: "btn ghost tiny", onClick: () => { setDelOpen(false); setDelPw(""); setDelConfirm(""); setDelErr(null); } }, "cancel"),
                React.createElement("button", {
                  type: "submit", className: "btn warm",
                  disabled: busy || delConfirm !== "DELETE",
                }, busy ? "…" : "delete forever")
              )
            )
      )
    );
  }

  window.KomonichiProfile = { ProfileButton, ProfileModal };
})();
