/* Saints Calendar — App root */

const { useState, useEffect, useCallback } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "density": "spacious",
  "viewport": "desktop",
  "showInstallToast": false
}/*EDITMODE-END*/;

const App = () => {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useState("home"); // home | calendar | saint | search | patronage | orders | timeline | map | about
  const [saintId, setSaintId] = useState(null);
  const [drawerKey, setDrawerKey] = useState(null);
  const _now = new Date();
  const [calY, setCalY] = useState(_now.getFullYear());
  const [calM, setCalM] = useState(_now.getMonth() + 1);
  const [query, setQuery] = useState("");
  const [history, setHistory] = useState([]);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [pwaToastVisible, setPwaToastVisible] = useState(false);

  // Auto-show install toast after 30s of mobile browsing (once per session, unless dismissed)
  useEffect(() => {
    if (tweaks.viewport !== "mobile") { setPwaToastVisible(false); return; }
    if (typeof isStandalone === "function" && isStandalone()) return;
    const dismissed = localStorage.getItem("sc.pwa.dismissed");
    if (dismissed) {
      // Re-show after 7 days
      const age = Date.now() - Number(dismissed);
      if (age < 7 * 24 * 60 * 60 * 1000) return;
    }
    const t = setTimeout(() => setPwaToastVisible(true), 30000);
    return () => clearTimeout(t);
  }, [tweaks.viewport]);

  // Manual trigger from Tweaks panel
  useEffect(() => {
    if (tweaks.showInstallToast) {
      setPwaToastVisible(true);
    }
  }, [tweaks.showInstallToast]);

  // Apply theme + density + viewport to root
  useEffect(() => {
    document.documentElement.dataset.theme = tweaks.theme;
    document.documentElement.dataset.density = tweaks.density;
    document.documentElement.dataset.viewport = tweaks.viewport;
  }, [tweaks.theme, tweaks.density, tweaks.viewport]);

  const navigate = useCallback((v) => {
    setHistory(h => [...h, view]);
    setView(v);
    setDrawerKey(null);
    setMobileMenuOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, [view]);

  const openSaint = useCallback((id) => {
    setHistory(h => [...h, view]);
    setSaintId(id);
    setView("saint");
    setDrawerKey(null);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, [view]);

  const goBack = useCallback(() => {
    setHistory(h => {
      if (h.length === 0) { setView("home"); return []; }
      const prev = h[h.length - 1];
      setView(prev);
      window.scrollTo({ top: 0, behavior: "smooth" });
      return h.slice(0, -1);
    });
  }, []);

  const onSearch = (q) => {
    setQuery(q);
    if (view !== "search") navigate("search");
  };

  // Keyboard nav
  useEffect(() => {
    const onKey = (e) => {
      // Ignore if typing
      // Cmd+K / Ctrl+K opens palette from anywhere
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setPaletteOpen(o => !o);
        return;
      }
      if (e.target.matches("input, textarea")) {
        if (e.key === "Escape") e.target.blur();
        return;
      }
      if (e.key === "/") {
        e.preventDefault();
        setPaletteOpen(true);
      } else if (e.key === "Escape") {
        if (drawerKey) setDrawerKey(null);
        else if (view !== "home") goBack();
      } else if (view === "calendar") {
        if (e.key === "ArrowLeft") {
          if (drawerKey) {
            const [m, d] = drawerKey.split("-").map(Number);
            const prev = new Date(calY, m - 1, d - 1);
            setDrawerKey(`${prev.getMonth()+1}-${prev.getDate()}`);
            setCalM(prev.getMonth()+1); setCalY(prev.getFullYear());
          } else {
            setCalM(m => m === 1 ? 12 : m - 1);
            if (calM === 1) setCalY(y => y - 1);
          }
        } else if (e.key === "ArrowRight") {
          if (drawerKey) {
            const [m, d] = drawerKey.split("-").map(Number);
            const next = new Date(calY, m - 1, d + 1);
            setDrawerKey(`${next.getMonth()+1}-${next.getDate()}`);
            setCalM(next.getMonth()+1); setCalY(next.getFullYear());
          } else {
            setCalM(m => m === 12 ? 1 : m + 1);
            if (calM === 12) setCalY(y => y + 1);
          }
        }
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [view, drawerKey, calM, calY, goBack, navigate]);

  const setYearMonth = (y, m) => { setCalY(y); setCalM(m); };

  const navItems = [
    { id: "home", label: "Today" },
    { id: "calendar", label: "Calendar" },
    { id: "timeline", label: "Timeline" },
    { id: "research", label: "Research" },
    { id: "saved", label: "Library" },
  ];

  const isMobile = tweaks.viewport === "mobile";

  const shell = (
    <AuthProvider>
    <SavedProvider>
    <WorkspaceProvider onOpenSaint={openSaint}>
    <div className="app-shell">
      <header className="topbar">
        <div className="container topbar-inner">
          <button className="brand" onClick={() => { setHistory([]); setView("home"); setMobileMenuOpen(false); }} data-screen-label="Brand">
            <span className="brand-mark"><SaintMark size={28} /></span>
            <span className="brand-word">Saints Calendar</span>
          </button>
          <nav className="nav nav-desktop">
            {navItems.map(n => (
              <button key={n.id}
                className={view === n.id ? "active" : ""}
                onClick={() => navigate(n.id)}
              >{n.label}</button>
            ))}
            <span className="nav-divider"></span>
            <button onClick={() => setPaletteOpen(true)} title="Global search (⌘K or /)" className="nav-search-btn">
              <IconSearch size={14} />
              <span className="nav-search-hint"><span className="kbd">⌘</span><span className="kbd">K</span></span>
            </button>
            <AccountChip onNavigate={navigate} />
          </nav>
          <button
            className={"nav-burger" + (mobileMenuOpen ? " is-open" : "")}
            onClick={() => setMobileMenuOpen(o => !o)}
            aria-label="Open menu"
            aria-expanded={mobileMenuOpen}
          >
            <span></span><span></span><span></span>
          </button>
        </div>
      </header>

      <TodayTicker onOpenSaint={openSaint} />

      <MobileMenu
        open={mobileMenuOpen}
        navItems={navItems}
        view={view}
        onNavigate={navigate}
        onSearch={() => { setMobileMenuOpen(false); setPaletteOpen(true); }}
      />

      <main style={{ flex: 1 }}>
        {view === "home" && <HomeView onOpenSaint={openSaint} onNavigate={navigate} onSearch={onSearch} query={query} setQuery={setQuery} />}
        {view === "calendar" && <CalendarView year={calY} month={calM} setYearMonth={setYearMonth} onSelectDay={(m, d) => setDrawerKey(`${m}-${d}`)} selectedKey={drawerKey} />}
        {view === "saint" && <SaintDetail saintId={saintId} onBack={goBack} onOpenSaint={openSaint} />}
        {view === "search" && <SearchView query={query} setQuery={setQuery} onOpenSaint={openSaint} onSearch={onSearch} />}
        {view === "timeline" && <TimelineView onOpenSaint={openSaint} />}
        {view === "research" && <ResearchView onOpenSaint={openSaint} />}
        {view === "saved" && <SavedView onOpenSaint={openSaint} onNavigate={navigate} />}
        {view === "login" && <LoginView onNavigate={navigate} />}
      </main>

      <footer className="footer">
        <div className="container footer-inner">
          <div className="t-meta">Saints Calendar · MMXXVI</div>
          <div className="t-meta">
            © <a href="https://creativecatholic.org" target="_blank" rel="noopener noreferrer" className="footer-cc-link">Creative Catholic</a>
          </div>
          <div className="t-meta footer-keys">
            Press <span className="kbd">/</span> search · <span className="kbd">←</span> <span className="kbd">→</span> navigate · <span className="kbd">esc</span> close
          </div>
        </div>
      </footer>

      {drawerKey && view === "calendar" && (
        <SaintDrawer dayKey={drawerKey} onClose={() => setDrawerKey(null)} onOpenSaint={openSaint} />
      )}

      <TweaksPanel title="Tweaks">
        <TweakSection label="Viewport" />
        <TweakRadio
          label="Device"
          value={tweaks.viewport}
          onChange={(v) => setTweak("viewport", v)}
          options={["desktop", "mobile"]}
        />
        <TweakSection label="Theme" />
        <TweakRadio
          label="Mode"
          value={tweaks.theme}
          onChange={(v) => setTweak("theme", v)}
          options={["light", "dark"]}
        />
        <TweakSection label="Density" />
        <TweakRadio
          label="Layout"
          value={tweaks.density}
          onChange={(v) => setTweak("density", v)}
          options={["spacious", "compact"]}
        />
        <TweakSection label="PWA" />
        <TweakButton
          label="Show install prompt"
          onClick={() => { localStorage.removeItem("sc.pwa.dismissed"); setPwaToastVisible(true); }}
        />
      </TweaksPanel>

      {tweaks.viewport === "mobile" && (
        <PwaInstallToast
          visible={pwaToastVisible}
          onClose={() => { setPwaToastVisible(false); setTweak("showInstallToast", false); }}
        />
      )}

      <WorkspaceRail />

      <CommandPalette
        open={paletteOpen}
        onClose={() => setPaletteOpen(false)}
        onNavigate={navigate}
        onOpenSaint={openSaint}
        onSearch={onSearch}
      />
    </div>
    </WorkspaceProvider>
    </SavedProvider>
    </AuthProvider>
  );

  if (isMobile) {
    return (
      <div className="vp-stage">
        <div className="vp-stage-bg">
          <div className="vp-stage-label">Mobile preview · 390 × 844</div>
        </div>
        <div className="vp-frame">
          <div className="vp-notch"></div>
          <div className="vp-screen">{shell}</div>
          <div className="vp-home"></div>
        </div>
      </div>
    );
  }
  return shell;
};

const MobileMenu = ({ open, navItems, view, onNavigate, onSearch }) => {
  const auth = useAuth();
  return (
    <div className={"mobile-menu" + (open ? " is-open" : "")} aria-hidden={!open}>
      <div className="mobile-menu-inner">
        <button className="mm-search" onClick={onSearch}>
          <IconSearch size={16} />
          <span>Search saints, feasts, places…</span>
        </button>
        <ul className="mm-list">
          {navItems.map(n => (
            <li key={n.id}>
              <button
                className={"mm-link" + (view === n.id ? " active" : "")}
                onClick={() => onNavigate(n.id)}
              >
                <span>{n.label}</span>
                <span className="mm-chev">›</span>
              </button>
            </li>
          ))}
        </ul>
        <div className="mm-divider"></div>
        <button className="mm-link mm-account" onClick={() => onNavigate("login")}>
          <span>{auth.user ? (auth.user.name || auth.user.email) : "Sign in"}</span>
          <span className="mm-chev">›</span>
        </button>
      </div>
    </div>
  );
};

const AccountChip = ({ onNavigate }) => {
  const auth = useAuth();
  if (!auth.user) {
    return <button onClick={() => onNavigate("login")} title="Sign in" className="nav-account">Sign in</button>;
  }
  const initials = (auth.user.name || auth.user.email).split(/\s+/).map(s => s[0]).slice(0, 2).join("").toUpperCase();
  return (
    <button onClick={() => onNavigate("login")} title={auth.user.email} className="nav-avatar">
      <span>{initials}</span>
    </button>
  );
};

// Wait for saints data, then mount. DATA_READY is set by data/saints-bridge.js.
(window.DATA_READY || Promise.resolve()).then(() => {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
}).catch(() => {
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
});
