// PHYSIO SAMOS — settings for the single account, activity and blog information.
(() => {
  const { useState } = React;
  const PSA = window.PSA;
  const { Icon, api, toast, errorText, Field, fmtDate, fmtRelative } = PSA;

  const PasswordField = ({ id, label, value, onChange, autoComplete, hint }) => {
    const [show, setShow] = useState(false);
    return (
      <Field label={label} htmlFor={id} hint={hint} error={value && value.length < 10 ? "Τουλάχιστον 10 χαρακτήρες." : null}>
        <div className="input-group">
          <input id={id} className={`input${show ? " mono" : ""}`} type={show ? "text" : "password"} autoComplete={autoComplete} value={value} onChange={(e) => onChange(e.target.value)} />
          <button type="button" className="btn btn--quiet btn--icon" aria-label={show ? "Απόκρυψη" : "Εμφάνιση"} aria-pressed={show} onClick={() => setShow(!show)}><Icon name={show ? "lock" : "eye"} size="sm" /></button>
        </div>
      </Field>
    );
  };

  const AccountSection = () => {
    const session = PSA.useSession();
    const [name, setName] = useState(session.user.name);
    const [pw, setPw] = useState({ current: "", next: "", again: "" });
    const [busy, setBusy] = useState(null);
    const saveName = async (e) => {
      e.preventDefault();
      setBusy("name");
      try { session.setUser((await api("/api/account", { method: "PATCH", body: { name } })).user); toast("Το όνομα αποθηκεύτηκε."); }
      catch (err) { toast(errorText(err), { kind: "error" }); }
      finally { setBusy(null); }
    };
    const savePassword = async (e) => {
      e.preventDefault();
      setBusy("pw");
      try {
        await api("/api/account/password", { method: "POST", body: { current: pw.current, next: pw.next } });
        setPw({ current: "", next: "", again: "" });
        toast("Ο κωδικός άλλαξε. Αποσυνδεθήκατε από κάθε άλλη συσκευή.");
      } catch (err) { toast(errorText(err), { kind: "error" }); }
      finally { setBusy(null); }
    };
    const mismatch = pw.again && pw.next !== pw.again;
    return (
      <section className="section" aria-labelledby="acc-title">
        <h2 id="acc-title">Ο λογαριασμός σας</h2>
        <div className="sheet sheet__pad account-grid">
          <form onSubmit={saveName} className="account-grid__col">
            <Field label="Όνομα" htmlFor="acc-name" hint="Εμφανίζεται μόνο μέσα στη διαχείριση. Τα άρθρα υπογράφονται από προφίλ συντακτών.">
              <input id="acc-name" className="input" value={name} onChange={(e) => setName(e.target.value)} maxLength={80} />
            </Field>
            <p className="hint">{session.user.email}</p>
            <div><button type="submit" className="btn btn--sm" disabled={busy === "name" || !name.trim() || name === session.user.name}>Αποθήκευση ονόματος</button></div>
          </form>
          <form onSubmit={savePassword} className="account-grid__col account-grid__col--rule">
            <h3 style={{ fontSize: 15 }}>Αλλαγή κωδικού</h3>
            <PasswordField id="pw-current" label="Τρέχων κωδικός" autoComplete="current-password" value={pw.current} onChange={(v) => setPw({ ...pw, current: v })} />
            <PasswordField id="pw-next" label="Νέος κωδικός" autoComplete="new-password" value={pw.next} onChange={(v) => setPw({ ...pw, next: v })} hint="Τουλάχιστον 10 χαρακτήρες. Μια φράση με λίγες λέξεις είναι και ασφαλής και εύκολη." />
            <Field label="Ξανά ο νέος κωδικός" htmlFor="pw-again" error={mismatch ? "Οι δύο κωδικοί δεν ταιριάζουν." : null}>
              <input id="pw-again" className="input" type="password" autoComplete="new-password" value={pw.again} onChange={(e) => setPw({ ...pw, again: e.target.value })} />
            </Field>
            <div><button type="submit" className="btn btn--sm" disabled={busy === "pw" || !pw.current || pw.next.length < 10 || pw.next !== pw.again}>Αλλαγή κωδικού</button></div>
          </form>
        </div>
      </section>
    );
  };

  const ActivitySection = () => {
    const act = PSA.useAsync(() => api("/api/activity?limit=100"), []);
    return (
      <section className="section" aria-labelledby="act-title">
        <h2 id="act-title">Δραστηριότητα</h2>
        <div className="sheet sheet__pad" style={{ paddingTop: 8, paddingBottom: 8 }}>
          {act.loading && !act.data && <PSA.Spinner />}
          {act.error && !act.data && <PSA.ErrorNotice error={act.error} onRetry={act.reload} />}
          {act.data && (act.data.activity.length ? <PSA.ActivityList items={act.data.activity} /> : <p className="muted" style={{ padding: "10px 0" }}>Τίποτα ακόμη.</p>)}
        </div>
      </section>
    );
  };

  const AboutSection = () => {
    const session = PSA.useSession();
    return (
      <section className="section" aria-labelledby="about-title">
        <h2 id="about-title">Πώς λειτουργεί το blog</h2>
        <div className="sheet sheet__pad">
          <div className="publish-state">
            <dl>
              <dt>Ορατότητα</dt><dd>Το blog ανοίγει και κρύβεται από την Αρχική. Τώρα είναι {session.settings.blogEnabled ? "δημόσιο" : "κρυφό"}.</dd>
              <dt>Συντάκτες</dt><dd>Κάθε άρθρο υπογράφεται από ένα προφίλ συντάκτη με όνομα και φωτογραφία. Τα προφίλ δεν είναι λογαριασμοί· τα διαχειρίζεστε από τη σελίδα <PSA.Link to="/writers">Συντάκτες</PSA.Link>.</dd>
              <dt>Αναζήτηση Google</dt><dd>Εμφανίζεται μόνο η σελίδα /blog. Τα μεμονωμένα άρθρα και αυτή η διαχείριση δεν εμφανίζονται ποτέ.</dd>
              <dt>Γλώσσες</dt><dd>Κάθε μετάφραση εμφανίζεται μόνο αφού εγκριθεί. Η αυτόματη μετάφραση γίνεται με το μοντέλο GLM-5.3 Flash της Z.ai, μέσα στο δωρεάν ημερήσιο όριο.</dd>
              <dt>Εικόνες</dt><dd>Μικραίνουν και χάνουν τα στοιχεία τοποθεσίας πριν ανέβουν, και φιλοξενούνται μόνο στον ιστότοπο.</dd>
              <dt>Ασφάλεια</dt><dd>Η σύνδεση γίνεται με Better Auth και λήγει μετά από 12 ώρες αδράνειας. Πέντε λάθος κωδικοί για το ίδιο email το κλειδώνουν για 15 λεπτά. Κάθε κωδικός που δίνει κάποιος άλλος αλλάζει υποχρεωτικά στην πρώτη σύνδεση.</dd>
            </dl>
          </div>
        </div>
      </section>
    );
  };

  // The Google aggregate the Worker refreshes on the first of each month (worker/lib/reviews.js).
  // Shown here because it is the one number on the site that changes without anyone editing the
  // site, and because a failed refresh has to be visible: the page keeps the last good pair, so
  // nothing on the site itself would ever look wrong.
  const ReviewsSection = () => {
    const [state, setState] = useState(null);
    const [busy, setBusy] = useState(false);
    const load = PSA.useAsync(() => api("/api/settings"), []);
    const data = state || load.data;
    const refresh = async () => {
      setBusy(true);
      try {
        const r = await api("/api/settings/reviews/refresh", { method: "POST", body: {} });
        setState(r.settings);
        if (r.reviews.status === "kept") toast(`Δεν ανανεώθηκε: ${r.reviews.reason}`, { kind: "error" });
        else toast(r.reviews.status === "updated" ? "Οι αριθμοί ανανεώθηκαν." : "Οι αριθμοί είναι ήδη ενημερωμένοι.");
      } catch (err) { toast(errorText(err), { kind: "error" }); }
      setBusy(false);
    };
    const r = data && data.reviews;
    return (
      <section className="section" aria-labelledby="reviews-title">
        <h2 id="reviews-title">Κριτικές Google</h2>
        <div className="sheet sheet__pad">
          <div className="publish-state">
            <dl>
              <dt>Βαθμολογία</dt><dd>{r ? `${r.score.toFixed(1).replace(".", ",")} · ${r.count} κριτικές` : "Δεν έχει γίνει ακόμη ανανέωση· ο ιστότοπος δείχνει τους αριθμούς με τους οποίους χτίστηκε."}</dd>
              <dt>Τελευταία ανανέωση</dt><dd>{r && r.at ? fmtDate(r.at) : "—"}</dd>
              {r && r.error ? <><dt>Τελευταίο σφάλμα</dt><dd className="muted">{r.error}</dd></> : null}
            </dl>
          </div>
          <p className="hint" style={{ marginTop: 14 }}>
            Ανανεώνονται αυτόματα την 1η κάθε μήνα από το Google. Αν αποτύχει, ο ιστότοπος κρατά τους
            τελευταίους σωστούς αριθμούς και το σφάλμα καταγράφεται στη Δραστηριότητα.
          </p>
          <div style={{ marginTop: 12 }}>
            <button type="button" className="btn btn--sm" disabled={busy} onClick={refresh}>
              {busy ? <><Icon name="loader" size="sm" className="spin" />Ανανέωση…</> : "Ανανέωση τώρα"}
            </button>
          </div>
        </div>
      </section>
    );
  };

  // The console's version: keep it in step with "version" in package.json.
  const PLATFORM_VERSION = "1.2.0";
  const PlatformInfo = () => (
    <footer className="platform-info" aria-label="Πληροφορίες πλατφόρμας">
      <img className="platform-info__logo" src="/admin/lm12-logo.png" width="960" height="95" alt="LM12 Development" draggable="false" />
      <dl className="platform-info__meta">
        <div><dt>Έκδοση</dt><dd className="mono">{PLATFORM_VERSION}</dd></div>
        <div><dt>Ανάπτυξη</dt><dd>LM12 Development</dd></div>
      </dl>
    </footer>
  );

  PSA.SettingsPage = () => {
    const session = PSA.useSession();
    return (
      <div className="page page--settings">
        <div className="page-head">
          <div>
            <h1>Ρυθμίσεις</h1>
            <p>Ο μοναδικός λογαριασμός διαχείρισης και το ιστορικό των αλλαγών.</p>
          </div>
        </div>
        <AccountSection />
        <ReviewsSection />
        <AboutSection />
        <ActivitySection />
        <PlatformInfo />
      </div>
    );
  };
})();
