// hydor-app.jsx — main shell: sidebar nav, topbar, notifications, quick-add, routing, 5-tier roles.
const ROLE_INFO = Hydor.ROLE_INFO;

// page id -> capability required to see it (null = any signed-in user)
const PAGE_CAP = {
  dashboard: "seeMoney", analytics: "seeMoney", products: null, transactions: null,
  costs: "seeFinance", money: "seeFinance", contacts: "manageContacts", hr: null, followups: null,
  finder: "findCustomers", callcenter: "callCenter", reports: "seeReports", activity: "seeAudit", settings: "seeSettings",
  notifications: "seeNotifications", attendance: "seeAttendance",
};
// department-aware page gating: pass the signed-in user so Call Center dept caps resolve
const roleCan = (role, pageId, user) => {
  const cap = PAGE_CAP[pageId];
  if (cap == null) return true;
  if (user) return Hydor.canU(user, cap);
  return Hydor.can(role, cap);
};
const roleHome = (role) => (role === "owner" || role === "cofounder" ? "dashboard" : role === "manager" ? "hr" : role === "accountant" ? "costs" : "transactions");

const NAV = [
  { sec: "Overview" },
  { id: "dashboard", label: "Dashboard", icon: "dashboard" },
  { id: "analytics", label: "Analytics", icon: "chart" },
  { sec: "Operations" },
  { id: "products", label: "Products & Inventory", icon: "box" },
  { id: "transactions", label: "Transactions", icon: "ledger" },
  { id: "costs", label: "Company Costs", icon: "cost" },
  { id: "money", label: "Receivables / Payables", icon: "money" },
  { sec: "People" },
  { id: "attendance", label: "Attendance", icon: "clock" },
  { id: "hr", label: "Human Resources", icon: "briefcase" },
  { id: "followups", label: "Customer Success", icon: "phone" },
  { id: "callcenter", label: "Call Center", icon: "phone" },
  { sec: "Growth" },
  { id: "finder", label: "Customer Finder", icon: "compass" },
  { id: "contacts", label: "Customers & Suppliers", icon: "people" },
  { sec: "Records" },
  { id: "reports", label: "Reports", icon: "report" },
  { id: "activity", label: "Activity Log", icon: "activity" },
  { id: "notifications", label: "Notification Centre", icon: "bell" },
  { id: "settings", label: "Settings", icon: "settings" },
];
const TITLES = {
  dashboard: ["Performance Dashboard", "Live view of sales, profit and team performance"],
  analytics: ["Analytics", "Interrogate your data from every angle"],
  products: ["Products & Inventory", "Stock, FIFO cost, recommended price and profit per system"],
  transactions: ["Transactions", "Sales, purchases, installments and stock adjustments"],
  costs: ["Company Costs", "Categorised overhead, salaries and recurring costs"],
  contacts: ["Customers & Suppliers", "Your trading relationships and follow-ups"],
  money: ["Receivables & Payables", "Who owes you, and who you owe"],
  hr: ["Human Resources", "Team, targets, KPIs, leave and performance"],
  attendance: ["Attendance & Visits", "Check in / out and log customer visits with photo, time & location"],
  callcenter: ["Call Center", "Visit queue, appointment dispatch and the visit-completion ranking"],
  followups: ["Customer Success", "Follow-ups, call outcomes, KPIs and incentives"],
  finder: ["Customer Finder", "Prospect, qualify and convert new customers"],
  reports: ["Reports", "Department performance, P&L, tax and cost analysis"],
  activity: ["Activity Log", "Full audit trail of every change"],
  notifications: ["Notification Centre", "Sales to review, approvals and flags — owner only"],
  settings: ["Settings", "Business profile, access, recurring costs and data"],
};

function App() {
  const s = useHydor();
  const d = useDerive();
  const authOn = !!(s.meta.auth && s.meta.auth.enabled);
  const sessionUser = Hydor.currentUser();
  const role = authOn ? (sessionUser ? sessionUser.role : null) : (ROLE_INFO[s.meta.role] ? s.meta.role : "owner");
  const [page, setPage] = React.useState(roleHome(role || "owner"));
  const [drill, setDrill] = React.useState(null);
  const [txFilter, setTxFilter] = React.useState(null);
  const [bellOpen, setBellOpen] = React.useState(false);
  const [addOpen, setAddOpen] = React.useState(false);
  const [roleOpen, setRoleOpen] = React.useState(false);
  const [quickForm, setQuickForm] = React.useState(null);
  const fs = useFS();
  const [bannerDismissed, setBannerDismissed] = React.useState(() => { try { return sessionStorage.getItem("hydor.fsbanner") === "1"; } catch (e) { return false; } });
  const dismissBanner = () => { setBannerDismissed(true); try { sessionStorage.setItem("hydor.fsbanner", "1"); } catch (e) {} };

  const goTo = (p, filter) => { setPage(p); setTxFilter(filter || null); setDrill(null); window.scrollTo(0, 0); };
  const onDrill = (dr) => { setDrill(dr); };

  // if the active role can't see the current page, bounce to its home
  React.useEffect(() => { if (role && !roleCan(role, page, sessionUser)) goTo(roleHome(role)); }, [role, page]);
  // expose an HR jump for notification deep-links (must run every render — keep above any early return)
  React.useEffect(() => { window.__hydorGoHR = () => { setBellOpen(false); goTo("hr"); }; window.__hydorGoPage = (p) => { setBellOpen(false); goTo(p); }; return () => { delete window.__hydorGoHR; delete window.__hydorGoPage; }; }, []);

  const switchRole = (next) => { Hydor.setMeta({ role: next }); setRoleOpen(false); if (!roleCan(next, page, null)) goTo(roleHome(next)); };
  const signOut = () => { setRoleOpen(false); Hydor.logout(); };

  const saleEmpDefault = sessionUser && Hydor.can(sessionUser.role, "manageContacts") && sessionUser.code ? sessionUser.code : (sessionUser ? sessionUser.code : "");
  const isOwner = Hydor.can(role, "seeNotifications");
  const myNotifs = isOwner ? s.notifications : Hydor.notifsForUser(sessionUser);
  const notifs = myNotifs;
  const openNotifs = notifs.filter((n) => !n.resolved);
  const visibleNav = NAV.filter((n, i) => {
    if (n.sec) {
      const rest = NAV.slice(i + 1);
      for (const item of rest) { if (item.sec) break; if (roleCan(role, item.id, sessionUser)) return true; }
      return false;
    }
    return roleCan(role, n.id, sessionUser);
  });
  const canCost = roleCan(role, "costs", sessionUser);
  const canProduct = Hydor.can(role, "manageProducts");
  const canRequestApproval = !Hydor.can(role, "sellBelowFloor");
  const openTx = (txId) => { setBellOpen(false); goTo("transactions", { highlight: txId }); };
  const navNotif = (n) => {
    Hydor.markNotifRead(n.id);
    setBellOpen(false);
    if (n.txId) { goTo("transactions", { highlight: n.txId }); return; }
    if (n.type === "late" || n.type === "attendance_exception" || n.type === "leave") { goTo("hr"); return; }
    if (n.type === "approval") { goTo("transactions"); return; }
    if (n.type === "visit_rejected") {
      if (roleCan(role, "callcenter", sessionUser)) goTo("callcenter");
      else goTo("hr");
      return;
    }
    if (n.type === "contract_visit_reminder" || n.type === "maintenance_visit") { goTo("followups"); return; }
    if (n.type === "visit_end" || n.type === "appointment" || n.type === "appointment_override") {
      if (roleCan(role, "callcenter", sessionUser)) goTo("callcenter");
      else goTo("hr");
      return;
    }
    if (isOwner) goTo("notifications");
  };

  // gate: show login when required and not signed in (after all hooks above)
  if (authOn && !role) {
    return <LoginScreen onAuthed={(u) => setPage(roleHome(u.role))} />;
  }

  const pageEl = {
    dashboard: <DashboardPage onDrill={onDrill} goTo={goTo} />,
    analytics: <AnalyticsPage onDrill={onDrill} />,
    products: <ProductsPage onDrill={onDrill} />,
    transactions: <TransactionsPage initialFilter={txFilter} onDrill={onDrill} key={JSON.stringify(txFilter)} />,
    costs: <CostsPage />,
    contacts: <ContactsPage onDrill={onDrill} />,
    money: <MoneyPage />,
    hr: <HRPage onDrill={onDrill} />,
    attendance: <AttendancePage />,
    followups: <FollowupsPage onDrill={onDrill} goToTx={openTx} />,
    callcenter: <CallCenterPage />,
    finder: <FinderPage />,
    reports: <ReportsPage />,
    activity: <ActivityPage />,
    notifications: <NotificationsPage goToTx={openTx} />,
    settings: <SettingsPage />,
  }[page];

  const [pTitle, pSub] = TITLES[page] || ["", ""];

  return (
    <div className="app">
      {/* ---- sidebar ---- */}
      <aside className="side">
        <div className="side-brand">
          <div className="side-logo">
            <svg viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 2.5C12 2.5 5 9 5 14.5a7 7 0 0014 0C19 9 12 2.5 12 2.5z" />
            </svg>
          </div>
          <div><div className="side-name">HYDOR</div><div className="side-tag">Water Treatment</div></div>
        </div>

        {visibleNav.map((n, i) => n.sec
          ? <div className="side-sec" key={"s" + i}>{n.sec}</div>
          : (
            <button key={n.id} className={"nav-item" + (page === n.id ? " on" : "")} onClick={() => goTo(n.id)}>
              <Icon name={n.icon} />{n.label}
              {n.id === "notifications" && openNotifs.length > 0 && <span className="nav-badge">{openNotifs.length}</span>}
              {n.id === "hr" && Hydor.can(role, "approveLeave") && d.pendingLeave > 0 && <span className="nav-badge">{d.pendingLeave}</span>}
              {n.id === "followups" && d.followupBuckets.overdue > 0 && <span className="nav-badge">{d.followupBuckets.overdue}</span>}
              {n.id === "money" && Hydor.can(role, "seeFinance") && (d.totals.receivable + d.totals.payable > 0) && <span className="nav-badge muted">{Math.round((d.totals.receivable + d.totals.payable) / 1000)}k</span>}
            </button>
          )
        )}

        <div style={{ marginTop: "auto", paddingTop: 16 }}>
          {Hydor.can(role, "manageProducts") && (
            <div style={{ fontSize: 11, color: "var(--text-3)", padding: "0 10px 8px", lineHeight: 1.5 }}>
              Inventory value<br /><span className="hx-num" style={{ color: "var(--text)", fontSize: 15, fontWeight: 600 }}>{Hydor.fmtMoney0(d.totals.invValue)} JOD</span>
            </div>
          )}
        </div>
      </aside>

      {/* ---- main ---- */}
      <div className="main">
        <header className="topbar">
          <div><h1>{pTitle}</h1><div className="top-sub">{pSub}</div></div>
          <div className="topbar-spacer" />

          <SaveChip fs={fs} />
          <CloudChip />
          <InstallChip />

          {/* quick add */}
          <div style={{ position: "relative" }}>
            <Btn variant="primary" icon="plus" onClick={() => setAddOpen((x) => !x)}>Quick add</Btn>
            <Popover open={addOpen} onClose={() => setAddOpen(false)} style={{ minWidth: 190 }}>
              <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "tx", type: "sale" }); }}><Icon name="zap" />New sale</button>
              <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "tx", type: "maintenance_contract" }); }}><Icon name="award" />New maintenance contract</button>
              {canRequestApproval && <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "approval" }); }}><Icon name="unlock" />Request price approval</button>}
              {Hydor.can(role, "postPurchases") && <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "tx", type: "purchase" }); }}><Icon name="box" />New purchase</button>}
              {canCost && <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "cost" }); }}><Icon name="cost" />Record cost</button>}
              {canProduct && <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "product" }); }}><Icon name="tag" />New product</button>}
              {Hydor.canU(sessionUser, "findCustomers") && <button className="pop-item" onClick={() => { setAddOpen(false); setQuickForm({ kind: "prospect" }); }}><Icon name="compass" />New prospect</button>}
            </Popover>
          </div>

          {/* print / pdf */}
          {Hydor.can(role, "canPrint") && <Btn variant="ghost" icon="print" onClick={() => window.print()} title="Print or save this page as a PDF report" />}

          <LangToggle />

          {/* notification bell — owner sees the full centre; others see notifications addressed to them */}
          {(isOwner || myNotifs.length > 0) && (
            <div className="bell-wrap" style={{ position: "relative" }}>
              <Btn variant="ghost" icon="bell" onClick={() => setBellOpen((x) => !x)} />
              {openNotifs.length > 0 && <span className="bell-dot" />}
              <Popover open={bellOpen} onClose={() => setBellOpen(false)} style={{ width: 380, maxHeight: 440, overflowY: "auto" }}>
                <div style={{ padding: "12px 14px", borderBottom: "1px solid var(--border)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                  <span style={{ fontWeight: 600, fontSize: 13.5 }}>Notifications</span>
                  <span style={{ display: "flex", gap: 8, alignItems: "center" }}>
                    <Badge color={openNotifs.length ? "red" : "green"}>{openNotifs.length || "all clear"}</Badge>
                    {isOwner && notifs.some((n) => !n.read) && <span className="linkish" style={{ fontSize: 11 }} onClick={() => Hydor.markAllNotifsRead()}>mark read</span>}
                  </span>
                </div>
                {notifs.length === 0 ? (
                  <div style={{ padding: "26px 16px", textAlign: "center", color: "var(--text-3)", fontSize: 13 }}>Nothing needs your attention.</div>
                ) : notifs.slice(0, 30).map((n) => {
                  return (
                  <div key={n.id} className="pop-item" style={{ alignItems: "flex-start", cursor: "pointer", opacity: n.resolved ? 0.5 : 1, background: !n.read ? "var(--accent-soft)" : undefined }}
                    onClick={() => navNotif(n)}>
                    <Icon name={n.type === "belowfloor" ? "warn" : n.type === "leave" ? "calendar" : n.type === "late" || n.type === "attendance_exception" ? "clock" : n.type === "visit_end" ? "pin" : n.type === "appointment" || n.type === "appointment_override" ? "calendar" : n.type === "approval" ? "unlock" : "alert"} size={15}
                      style={{ marginTop: 2, color: n.sev === "high" ? "var(--neg)" : n.sev === "med" ? "var(--warn)" : "var(--text-3)", flex: "none" }} />
                    <span style={{ display: "flex", flexDirection: "column", gap: 2 }}>
                      <span style={{ fontSize: 12.5, fontWeight: 600 }}>{n.title}<span style={{ color: "var(--accent-2)", fontWeight: 500, marginLeft: 6, fontSize: 11 }}>view →</span></span>
                      <span style={{ fontSize: 12, lineHeight: 1.45, color: "var(--text-2)" }}>{n.body}</span>
                    </span>
                  </div>
                  );
                })}
                {isOwner && notifs.length > 0 && <button className="pop-item" style={{ justifyContent: "center", color: "var(--accent-2)", fontSize: 12.5 }} onClick={() => { setBellOpen(false); goTo("notifications"); }}>Open notification centre</button>}
              </Popover>
            </div>
          )}

          {/* role / account switch */}
          <div style={{ position: "relative" }}>
            <button className="nav-item" style={{ width: "auto", padding: "6px 10px", borderRadius: 9, background: "var(--surface)", border: "1px solid var(--border)" }} onClick={() => setRoleOpen((x) => !x)}>
              <span className="hx-emp-badge" style={{ width: 24, height: 24 }}>{authOn && sessionUser ? sessionUser.name.slice(0, 1).toUpperCase() : ROLE_INFO[role].badge}</span>
              <span style={{ fontSize: 13 }}>{authOn && sessionUser ? sessionUser.name : ROLE_INFO[role].short}</span>
              <Icon name="arrow" size={13} style={{ transform: "rotate(90deg)", opacity: .5, marginLeft: 2 }} />
            </button>
            <Popover open={roleOpen} onClose={() => setRoleOpen(false)} style={{ minWidth: 268 }}>
              {authOn ? (
                <>
                  <div style={{ padding: "12px 14px 6px", display: "flex", alignItems: "center", gap: 10 }}>
                    <span className="hx-emp-badge" style={{ width: 30, height: 30 }}>{sessionUser ? sessionUser.name.slice(0, 1).toUpperCase() : ROLE_INFO[role].badge}</span>
                    <span style={{ display: "flex", flexDirection: "column" }}>
                      <span style={{ fontSize: 13, fontWeight: 600 }}>{sessionUser ? sessionUser.name : ROLE_INFO[role].label}</span>
                      <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>{ROLE_INFO[role].label}{sessionUser && sessionUser.department ? " · " + sessionUser.department : ""}</span>
                    </span>
                  </div>
                  <div style={{ borderTop: "1px solid var(--border)", margin: "8px 0" }} />
                  <button className="pop-item" onClick={signOut}><Icon name="lock" />Sign out</button>
                </>
              ) : (
                <>
                  <div style={{ padding: "10px 14px", fontSize: 11, color: "var(--text-3)", textTransform: "uppercase", letterSpacing: ".05em" }}>Preview as role</div>
                  {Hydor.ROLE_KEYS.map((rk) => (
                    <button key={rk} className="pop-item" style={{ alignItems: "flex-start", background: role === rk ? "var(--accent-soft)" : undefined }} onClick={() => switchRole(rk)}>
                      <span className="hx-emp-badge" style={{ width: 26, height: 26, flex: "none" }}>{ROLE_INFO[rk].badge}</span>
                      <span style={{ display: "flex", flexDirection: "column", gap: 2 }}>
                        <span style={{ fontSize: 13, fontWeight: 600, color: role === rk ? "var(--accent-2)" : "var(--text)" }}>{ROLE_INFO[rk].label}{role === rk && <Badge color="blue">active</Badge>}</span>
                        <span style={{ fontSize: 11.5, color: "var(--text-3)", lineHeight: 1.4, whiteSpace: "normal" }}>{ROLE_INFO[rk].desc}</span>
                      </span>
                    </button>
                  ))}
                </>
              )}
            </Popover>
          </div>
        </header>

        <div className="content">
          {fs.supported && !fs.connected && !bannerDismissed && Hydor.can(role, "seeSettings") && (
            <div className="fs-banner no-print">
              <Icon name="database" size={20} style={{ color: "var(--accent-2)", flex: "none" }} />
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13.5, fontWeight: 600 }}>{fs.remembered ? "Reconnect your data file" : "Turn on automatic saving to a file"}</div>
                <div style={{ fontSize: 12, color: "var(--text-2)", marginTop: 2 }}>
                  {fs.remembered
                    ? "HYDOR remembers your data file. Click reconnect to load it and resume auto-saving."
                    : "Save your books to a file on this computer so nothing is ever lost when you close HYDOR. One click to set it up."}
                </div>
              </div>
              {fs.remembered
                ? <Btn variant="primary" sm icon="refresh" onClick={() => window.HydorFS.reconnect()}>Reconnect</Btn>
                : <Btn variant="primary" sm icon="save" onClick={() => window.HydorFS.connect().catch(() => {})}>Set up auto-save</Btn>}
              <Btn variant="ghost" sm icon="x" onClick={dismissBanner} />
            </div>
          )}
          <div className="print-only print-report-head">
            <div className="prh-top">
              <div>
                <div className="prh-brand">HYDOR<span>Water Treatment ERP</span></div>
                <div className="prh-title">{pTitle}</div>
              </div>
              <div className="prh-meta">
                {s.meta.company}<br />
                {ROLE_INFO[role].label} view<br />
                Generated {new Date().toLocaleDateString("en-GB", { day: "2-digit", month: "long", year: "numeric" })}
              </div>
            </div>
          </div>
          {pageEl}
        </div>
      </div>

      <DrillPanel drill={drill} onClose={() => setDrill(null)} onNav={onDrill} />

      {/* quick-add forms */}
      {quickForm && quickForm.kind === "tx" && <TxForm presetType={quickForm.type} defaultEmployee={quickForm.type === "sale" ? saleEmpDefault : ""} onClose={() => setQuickForm(null)} />}
      {quickForm && quickForm.kind === "cost" && <CostForm onClose={() => setQuickForm(null)} />}
      {quickForm && quickForm.kind === "product" && <ProductForm onClose={() => setQuickForm(null)} />}
      {quickForm && quickForm.kind === "prospect" && <ProspectForm onClose={() => setQuickForm(null)} />}
      {quickForm && quickForm.kind === "approval" && <ApprovalRequestForm onClose={() => setQuickForm(null)} />}
    </div>
  );
}

function SaveChip({ fs }) {
  const [open, setOpen] = React.useState(false);
  const push = useToast();
  if (!fs.supported) {
    return (
      <div style={{ position: "relative" }}>
        <button className="save-chip warn" onClick={() => setOpen((x) => !x)} title="This browser can't auto-save to a file">
          <Icon name="database" size={14} /><span>Backup manually</span>
        </button>
        <Popover open={open} onClose={() => setOpen(false)} style={{ width: 280, padding: 14 }}>
          <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.55 }}>
            This browser can’t save directly to a file. Your data is kept in this browser — to be safe, use <b style={{ color: "var(--text)" }}>Settings → Saving &amp; devices → Export backup</b> regularly, or open HYDOR in Chrome or Edge for automatic file saving.
          </div>
        </Popover>
      </div>
    );
  }
  const state = fs.connected ? (fs.saving ? "saving" : "saved") : "off";
  const label = fs.connected ? (fs.saving ? "Saving…" : "Saved to file") : "Not saving";
  return (
    <div style={{ position: "relative" }}>
      <button className={"save-chip " + state} onClick={() => setOpen((x) => !x)}>
        <Icon name={fs.connected ? (fs.saving ? "refresh" : "check") : "save"} size={14} />
        <span>{label}</span>
      </button>
      <Popover open={open} onClose={() => setOpen(false)} style={{ width: 300, padding: 16 }}>
        {fs.connected ? (
          <>
            <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 8 }}>
              <Icon name="database" size={16} style={{ color: "var(--pos)" }} />
              <span style={{ fontSize: 13.5, fontWeight: 600 }}>Auto-saving is on</span>
            </div>
            <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.55, marginBottom: 12 }}>
              Every change is written automatically to<br /><b className="hx-num" style={{ color: "var(--text)" }}>{fs.fileName || "your data file"}</b>
              {fs.lastSaved && <><br /><span style={{ color: "var(--text-3)" }}>Last saved {fs.lastSaved.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit", second: "2-digit" })}</span></>}
            </div>
            {fs.error && <div style={{ fontSize: 12, color: "var(--neg)", marginBottom: 10 }}>{fs.error}</div>}
            <div style={{ display: "flex", gap: 8 }}>
              <Btn sm icon="download" onClick={() => { window.HydorFS.writeNow(); push("Saved."); setOpen(false); }}>Save now</Btn>
              <Btn sm variant="ghost" onClick={() => { window.HydorFS.disconnect(); setOpen(false); }}>Disconnect</Btn>
            </div>
          </>
        ) : (
          <>
            <div style={{ fontSize: 13.5, fontWeight: 600, marginBottom: 6 }}>Save your data to a file</div>
            <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.55, marginBottom: 12 }}>
              Bind HYDOR to a file on this computer so your books are saved automatically and never lost when you close the app.
            </div>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
              <Btn sm variant="primary" icon="save" onClick={() => { window.HydorFS.connect().then(() => push("Auto-save on.")).catch(() => {}); setOpen(false); }}>New data file</Btn>
              <Btn sm icon="upload" onClick={() => { window.HydorFS.openExisting().then(() => push("Data file loaded.")).catch(() => {}); setOpen(false); }}>Open existing</Btn>
            </div>
          </>
        )}
      </Popover>
    </div>
  );
}

function CloudChip() {
  const [st, setSt] = React.useState(() => window.HydorCloud && window.HydorCloud.getStatus ? window.HydorCloud.getStatus() : null);
  React.useEffect(() => window.HydorCloud && window.HydorCloud.onStatus ? window.HydorCloud.onStatus((s) => setSt({ ...s })) : undefined, []);
  if (!st || (!st.configured && !st.connected)) return null; // hidden until cloud is set up
  const cls = st.connected ? "saved" : st.connecting ? "" : "warn";
  const label = st.connected ? (st.syncing ? "Syncing…" : "Cloud live") : st.connecting ? "Connecting…" : "Cloud offline";
  return (
    <span className={"save-chip " + cls} title={st.workspaceId ? "Workspace: " + st.workspaceId : "Cloud sync"} style={{ cursor: "default" }}>
      <Icon name={st.connected ? (st.syncing ? "refresh" : "database") : "alert"} size={14} /><span>{label}</span>
    </span>
  );
}

function InstallChip() {
  const [deferred, setDeferred] = React.useState(null);
  const [open, setOpen] = React.useState(false);
  const [installed, setInstalled] = React.useState(false);
  React.useEffect(() => {
    const standalone = window.matchMedia && window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true;
    if (standalone) { setInstalled(true); return; }
    const onPrompt = (e) => { e.preventDefault(); setDeferred(e); };
    const onInstalled = () => { setInstalled(true); setDeferred(null); setOpen(false); };
    window.addEventListener("beforeinstallprompt", onPrompt);
    window.addEventListener("appinstalled", onInstalled);
    return () => { window.removeEventListener("beforeinstallprompt", onPrompt); window.removeEventListener("appinstalled", onInstalled); };
  }, []);
  if (installed) return null;
  const ua = navigator.userAgent || "";
  const isIOS = /iphone|ipad|ipod/i.test(ua) || (/* iPadOS */ navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);
  // only surface the chip where install is actually possible (Android prompt or iOS Safari)
  if (!deferred && !isIOS) return null;
  const doInstall = async () => {
    if (deferred) { deferred.prompt(); try { await deferred.userChoice; } catch (e) {} setDeferred(null); }
    else setOpen((x) => !x);
  };
  return (
    <div style={{ position: "relative" }}>
      <button className="save-chip" onClick={doInstall} title="Install HYDOR on this device">
        <Icon name="download" size={14} /><span>Install app</span>
      </button>
      <Popover open={open} onClose={() => setOpen(false)} style={{ width: 280, padding: 16 }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, marginBottom: 8 }}>Add HYDOR to your Home Screen</div>
        <div style={{ fontSize: 12.5, color: "var(--text-2)", lineHeight: 1.6 }}>
          In Safari, tap the <b style={{ color: "var(--text)" }}>Share</b> button <span style={{ fontSize: 14 }}>⬆️</span>, then choose <b style={{ color: "var(--text)" }}>“Add to Home Screen.”</b> HYDOR will open full-screen like an installed app, with camera and offline support.
        </div>
      </Popover>
    </div>
  );
}

function Root() { return <ToastHost><App /></ToastHost>; }
ReactDOM.createRoot(document.getElementById("root")).render(<Root />);
