// PHYSIO SAMOS — admin console: the shell. Session, routes, the rail, and the mount.
(() => {
  const { useState, useEffect, useCallback } = React;
  const PSA = window.PSA;
  const { Icon, api, Link } = PSA;

  const NAV = [
    { to: "/", label: "Αρχική", icon: "dashboard", match: (p) => p === "/" },
    { to: "/posts", label: "Άρθρα", icon: "posts", match: (p) => p.startsWith("/posts") },
    { to: "/writers", label: "Συντάκτες", icon: "userRound", match: (p) => p.startsWith("/writers") },
    { to: "/media", label: "Εικόνες", icon: "media", match: (p) => p.startsWith("/media") },
    { to: "/settings", label: "Ρυθμίσεις", icon: "settings", match: (p) => p.startsWith("/settings") },
  ];

  // `fill` drops the fixed height, so the logo takes its container's width (the sign-in page).
  const Logo = ({ height = 34, fill = false }) => {
    return <img src="/uploads/full-logo-lightmode.png" alt="ATZEMIAN PHYSIO SAMOS" style={fill ? { width: "100%", height: "auto" } : { height, width: "auto" }} draggable="false" />;
  };
  PSA.Logo = Logo;

  const Rail = ({ path, open, onClose, onSignOut }) => {
    const session = PSA.useSession();
    const on = session.settings.blogEnabled;
    return (
      <>
        {open && <div className="rail-scrim" onClick={onClose} />}
        <nav className={`rail${open ? " is-open" : ""}`} aria-label="Κύρια πλοήγηση">
          <Link to="/" className="rail__brand" onClick={onClose}><Logo height={68} /></Link>
          <div className="rail__nav">
            {NAV.map((n) => (
              <Link key={n.to} to={n.to} className="rail__link" aria-current={n.match(path) ? "page" : undefined} onClick={onClose}>
                <Icon name={n.icon} />{n.label}
              </Link>
            ))}
          </div>
          <div className="rail__site">
            <span className={`state ${on ? "state--published" : "state--draft"}`}>{on ? "Blog δημόσιο" : "Blog κρυφό"}</span>
            <a href={on ? `${session.publicOrigin}/blog` : session.publicOrigin} target="_blank" rel="noopener">
              {on ? "Άνοιγμα του /blog" : "Άνοιγμα του ιστότοπου"} <Icon name="external" size="sm" />
            </a>
          </div>
          <div className="rail__foot">
            <div className="rail__user">
              <span className="avatar" aria-hidden="true">{PSA.initials(session.user.name)}</span>
              <span className="who">
                <strong>{session.user.name}</strong>
                <span title={session.user.email}>{session.user.email}</span>
              </span>
              <button type="button" className="btn btn--quiet btn--icon rail__signout" onClick={onSignOut} aria-label="Αποσύνδεση" title="Αποσύνδεση">
                <Icon name="logout" size="sm" />
              </button>
            </div>
          </div>
        </nav>
      </>
    );
  };

  const NotFound = () => (
    <div className="page">
      <div className="empty">
        <Icon name="help" size="lg" />
        <h3>Αυτή η σελίδα δεν υπάρχει</h3>
        <p>Ίσως ο σύνδεσμος είναι παλιός.</p>
        <Link to="/" className="btn">Επιστροφή στην αρχική</Link>
      </div>
    </div>
  );

  const TITLES = { "/": "Αρχική", "/posts": "Άρθρα", "/writers": "Συντάκτες", "/media": "Εικόνες", "/settings": "Ρυθμίσεις" };

  const App = () => {
    const [session, setSession] = useState({ status: "loading" });
    const [railOpen, setRailOpen] = useState(false);
    const path = PSA.usePath();
    const pathname = path.split("?")[0];

    const load = useCallback(async () => {
      try {
        const s = await api("/api/session");
        if (!s.user) { setSession({ status: "out" }); return; }
        setSession({ status: "in", user: s.user, settings: s.settings, publicOrigin: s.publicOrigin });
      } catch (err) {
        setSession(err.status === 401 ? { status: "out" } : { status: "error", error: err });
      }
    }, []);

    useEffect(() => {
      load();
      const expired = () => setSession((s) => (s.status === "in" ? { status: "out", expired: true } : s));
      window.addEventListener("psa:signed-out", expired);
      return () => window.removeEventListener("psa:signed-out", expired);
    }, [load]);

    useEffect(() => {
      const base = /^\/posts\/\d+/.test(pathname) ? "Επεξεργασία" : TITLES[pathname] || "Διαχείριση";
      document.title = `${base} · Διαχείριση Physio Samos`;
    }, [pathname]);

    const signOut = async () => {
      if (PSA.leaveGuard && !PSA.leaveGuard()) return;
      try { await api("/api/auth/sign-out", { method: "POST", body: {} }); } catch (e) {}
      PSA.leaveGuard = null;
      setSession({ status: "out" });
    };

    if (session.status === "loading") {
      return <div className="boot" role="status"><img src="/uploads/favicon.png" alt="" width="40" height="40" /><PSA.Spinner /></div>;
    }
    if (session.status === "error") {
      return <div className="boot"><PSA.ErrorNotice error={session.error} onRetry={load} /></div>;
    }
    if (session.status === "out") {
      return <><PSA.SignIn expired={session.expired} onSignedIn={load} /><PSA.Toasts /></>;
    }
    // A seeded, newly created or reset account: nothing else until its owner picks a password. The API
    // enforces the same rule (worker/admin.js), this only saves them a screen of errors.
    if (session.user.mustChangePassword) {
      return <><PSA.FirstPassword user={session.user} onDone={load} onSignOut={signOut} /><PSA.Toasts /></>;
    }

    const ctx = {
      user: session.user,
      settings: session.settings,
      publicOrigin: session.publicOrigin,
      refresh: load,
      setSettings: (settings) => setSession((s) => ({ ...s, settings })),
      setUser: (user) => setSession((s) => ({ ...s, user })),
    };

    let page;
    const editor = /^\/posts\/(\d+)$/.exec(pathname);
    if (pathname === "/") page = <PSA.Dashboard />;
    else if (pathname === "/posts") page = <PSA.PostsPage />;
    else if (editor) page = <PSA.Editor key={editor[1]} id={Number(editor[1])} />;
    else if (pathname === "/writers") page = <PSA.WritersPage />;
    else if (pathname === "/media") page = <PSA.MediaPage />;
    else if (pathname === "/settings") page = <PSA.SettingsPage />;
    else page = <NotFound />;

    return (
      <PSA.SessionContext.Provider value={ctx}>
        <a className="sr-only" href="#main">Μετάβαση στο περιεχόμενο</a>
        <div className="app">
          <Rail path={pathname} open={railOpen} onClose={() => setRailOpen(false)} onSignOut={signOut} />
          <main className="main" id="main">
            <div className="topbar">
              <button type="button" className="btn btn--quiet btn--icon" aria-label="Μενού" onClick={() => setRailOpen(true)}><Icon name="menu" /></button>
              <Logo height={28} />
            </div>
            {page}
          </main>
        </div>
        <PSA.Toasts />
        <PSA.ConfirmHost />
      </PSA.SessionContext.Provider>
    );
  };

  // Keep the console mounted across resizes so unsaved writing is preserved.
  const DesktopConsole = () => {
    const query = "(min-width: 1200px) and (min-height: 700px)";
    const [fits, setFits] = useState(() => window.matchMedia(query).matches);
    useEffect(() => {
      const media = window.matchMedia(query);
      const update = () => setFits(media.matches);
      media.addEventListener("change", update);
      update();
      return () => media.removeEventListener("change", update);
    }, []);
    return <>
      <div style={{ display: fits ? undefined : "none" }} aria-hidden={fits ? undefined : true}><App /></div>
      {!fits && <main className="viewport-notice" role="alert">
        <div className="viewport-notice__card">
          <Logo height={64} />
          <h1>Χρειάζεται μεγαλύτερο παράθυρο</h1>
          <p>Η κονσόλα του blog χρειάζεται τουλάχιστον 1200 × 700 pixels διαθέσιμου χώρου, ώστε όλα τα εργαλεία να εμφανίζονται σωστά.</p>
          <p>Ανοίξτε τη σε υπολογιστή και μεγαλώστε το παράθυρο ή χρησιμοποιήστε πλήρη οθόνη. Αν χρησιμοποιείτε tablet, δοκιμάστε οριζόντιο προσανατολισμό.</p>
          <div className="notice notice--info">Η κονσόλα θα εμφανιστεί αυτόματα μόλις υπάρχει αρκετός χώρος. Η εργασία σας παραμένει ανοιχτή.</div>
        </div>
      </main>}
    </>;
  };
  ReactDOM.createRoot(document.getElementById("admin-root")).render(<DesktopConsole />);
})();
