// Main App shell — async data load, theme, bottom nav, screen routing,
// favorites + dataSaver + darkMode persistence. Defaults are baked: editorial
// font pair, comfy density, film grain on, dark mode by default.

const { useState, useEffect } = React;

const FONT_PAIR = {
  display: "'Fraunces', 'Times New Roman', serif",
  ui: "'Inter Tight', system-ui, sans-serif",
  mono: "'JetBrains Mono', monospace",
};

const DENSITY = "comfy"; // "airy" | "comfy" | "cozy"
const GRAIN = true;
// Accent is keyed off the theme: punchy red on OLED-true black, slightly
// deeper crimson on warm cream so it reads as "ink" rather than "neon".
const ACCENT_DARK = "#DD1717";
const ACCENT_LIGHT = "#B11518";

const FAVS_KEY = "wallpeppers:favorites";
const SAVER_KEY = "wallpeppers:datasaver";
const DARK_KEY = "wallpeppers:darkmode";

function App() {
  const [tab, setTab] = useState("home");
  const [openId, setOpenId] = useState(null);
  const [favorites, setFavorites] = useState(() => {
    try {
      const v = localStorage.getItem(FAVS_KEY);
      return v ? JSON.parse(v) : [];
    } catch (e) {
      return [];
    }
  });
  const [dataSaver, setDataSaver] = useState(() => {
    try {
      return localStorage.getItem(SAVER_KEY) === "1";
    } catch (e) {
      return false;
    }
  });
  const [darkMode, setDarkMode] = useState(() => {
    try {
      const v = localStorage.getItem(DARK_KEY);
      return v === null ? true : v === "1";
    } catch (e) {
      return true;
    }
  });

  const [data, setData] = useState({ items: null, categories: [], moods: [] });
  const [loadError, setLoadError] = useState(null);

  useEffect(() => {
    let mounted = true;
    loadWallpapers()
      .then((d) => {
        if (!mounted) return;
        setData(d);
        const boot = document.getElementById("boot");
        if (boot) {
          boot.dataset.done = "1";
          setTimeout(() => boot.remove(), 400);
        }
      })
      .catch((err) => {
        if (!mounted) return;
        setLoadError(err.message || "Failed to load wallpapers");
      });
    return () => {
      mounted = false;
    };
  }, []);

  useEffect(() => {
    try {
      localStorage.setItem(FAVS_KEY, JSON.stringify(favorites));
    } catch (e) {}
  }, [favorites]);

  useEffect(() => {
    try {
      localStorage.setItem(SAVER_KEY, dataSaver ? "1" : "0");
    } catch (e) {}
  }, [dataSaver]);

  useEffect(() => {
    try {
      localStorage.setItem(DARK_KEY, darkMode ? "1" : "0");
    } catch (e) {}
  }, [darkMode]);

  const dark = darkMode;
  const accent = dark ? ACCENT_DARK : ACCENT_LIGHT;

  const toggleFavorite = (id) =>
    setFavorites((f) => (f.includes(id) ? f.filter((x) => x !== id) : [...f, id]));

  const wallpapers = data.items || [];
  const open = wallpapers.find((w) => w.id === openId);

  const themeVars = dark
    ? {
        "--bg": "#0a0a0a",
        "--fg": "#f4f1ec",
        "--muted": "#8a857d",
        "--surface": "#141413",
        "--line": "rgba(244, 241, 236, 0.12)",
      }
    : {
        "--bg": "#f7f5f0",
        "--fg": "#16140f",
        "--muted": "#807a70",
        "--surface": "#ffffff",
        "--line": "rgba(22, 20, 15, 0.12)",
      };

  // Mirror theme vars onto <html> so portal-rendered subtrees (e.g. the Vaul
  // drawer mounted on document.body) inherit the same values.
  useEffect(() => {
    const root = document.documentElement;
    const all = {
      ...themeVars,
      "--accent": accent,
      "--font-display": FONT_PAIR.display,
      "--font-ui": FONT_PAIR.ui,
      "--font-mono": FONT_PAIR.mono,
    };
    for (const [k, v] of Object.entries(all)) root.style.setProperty(k, v);
  }, [dark, accent]);

  return (
    <div
      data-screen-label={tab}
      style={{
        ...themeVars,
        "--accent": accent,
        "--font-display": FONT_PAIR.display,
        "--font-ui": FONT_PAIR.ui,
        "--font-mono": FONT_PAIR.mono,
        position: "fixed",
        inset: 0,
        background: "var(--bg)",
        color: "var(--fg)",
        fontFamily: "var(--font-ui)",
        overflow: "hidden",
        display: "flex",
        justifyContent: "center",
      }}
    >
      <style>{`
        @keyframes fadeIn { 0% { opacity: 0 } 100% { opacity: 1 } }
        @keyframes fadeUp { 0% { opacity: 0; transform: translateY(8px) } 100% { opacity: 1; transform: none } }
        @keyframes riseIn { 0% { opacity: 0; transform: translateY(14px) } 100% { opacity: 1; transform: none } }
        @keyframes spin { to { transform: rotate(360deg) } }
        button.ghost-btn {
          appearance: none; background: transparent; border: 1px solid var(--line);
          color: var(--fg); width: 38px; height: 38px; border-radius: 999px;
          display: inline-flex; align-items: center; justify-content: center;
          cursor: pointer; transition: all 160ms ease;
        }
        button.ghost-btn:hover { border-color: var(--fg); }
        button.solid-btn {
          appearance: none; background: var(--fg); color: var(--bg); border: none;
          padding: 12px 22px; border-radius: 999px; font-family: var(--font-ui);
          font-size: 13px; font-weight: 500; letter-spacing: -0.005em;
          display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
          transition: transform 160ms ease, opacity 160ms ease;
        }
        button.solid-btn:hover { transform: translateY(-1px); }
        button.solid-btn:disabled { opacity: 0.6; cursor: wait; }
        button.float-btn {
          appearance: none; background: rgba(0,0,0,0.4);
          backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
          border: 1px solid rgba(255,255,255,0.14); color: white;
          width: 38px; height: 38px; border-radius: 999px;
          display: inline-flex; align-items: center; justify-content: center;
          cursor: pointer; transition: all 160ms ease;
        }
        button.float-btn:hover { background: rgba(0,0,0,0.55); }
        button.icon-btn {
          appearance: none; background: transparent; border: none; color: var(--fg);
          width: 32px; height: 32px; border-radius: 8px;
          display: inline-flex; align-items: center; justify-content: center;
          cursor: pointer; transition: background 160ms ease;
        }
        button.icon-btn:hover, button.icon-btn.active { background: var(--surface); }
        @keyframes phoneIn { from { opacity: 0; transform: translateY(20px) scale(0.96) } to { opacity: 1; transform: none } }
        ::selection { background: var(--accent); color: white; }
      `}</style>

      <div
        style={{
          position: "relative",
          width: "100%",
          maxWidth: 980,
          height: "100%",
          background: "var(--bg)",
          overflow: "hidden",
        }}
      >
        {!data.items && !loadError && <LoadingPane />}
        {loadError && <ErrorPane message={loadError} />}

        {data.items && (
          <React.Fragment>
            <div style={{ position: "absolute", inset: 0, paddingBottom: 84 }}>
              <div
                style={{
                  position: "absolute",
                  inset: 0,
                  opacity: tab === "home" ? 1 : 0,
                  pointerEvents: tab === "home" ? "auto" : "none",
                  transition: "opacity 220ms ease",
                }}
              >
                <HomeScreen
                  density={DENSITY}
                  onOpen={setOpenId}
                  favorites={favorites}
                  toggleFavorite={toggleFavorite}
                  dataSaver={dataSaver}
                  wallpapers={wallpapers}
                  categories={data.categories}
                  moods={data.moods}
                />
              </div>
              <div
                style={{
                  position: "absolute",
                  inset: 0,
                  opacity: tab === "search" ? 1 : 0,
                  pointerEvents: tab === "search" ? "auto" : "none",
                  transition: "opacity 220ms ease",
                }}
              >
                {tab === "search" && (
                  <SearchScreen onOpen={setOpenId} dataSaver={dataSaver} wallpapers={wallpapers} />
                )}
              </div>
              <div
                style={{
                  position: "absolute",
                  inset: 0,
                  opacity: tab === "settings" ? 1 : 0,
                  pointerEvents: tab === "settings" ? "auto" : "none",
                  transition: "opacity 220ms ease",
                }}
              >
                {tab === "settings" && (
                  <SettingsScreen
                    darkMode={dark}
                    setDarkMode={setDarkMode}
                    dataSaver={dataSaver}
                    setDataSaver={setDataSaver}
                    favorites={favorites}
                    wallpapers={wallpapers}
                  />
                )}
              </div>
            </div>

            {open && (
              <DetailView
                wallpaper={open}
                onClose={() => setOpenId(null)}
                onOpen={setOpenId}
                favorites={favorites}
                toggleFavorite={toggleFavorite}
                wallpapers={wallpapers}
                dataSaver={dataSaver}
              />
            )}

            <BottomNav tab={tab} setTab={setTab} hidden={!!open} />
          </React.Fragment>
        )}

        {GRAIN && <Grain opacity={dark ? 0.06 : 0.04} />}
      </div>
    </div>
  );
}

const LoadingPane = () => (
  <div
    style={{
      position: "absolute",
      inset: 0,
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 14,
      color: "var(--muted)",
      fontFamily: "var(--font-ui)",
      fontSize: 13,
    }}
  >
    <div
      style={{
        width: 22,
        height: 22,
        borderRadius: "50%",
        border: "2px solid var(--line)",
        borderTopColor: "var(--accent)",
        animation: "spin 700ms linear infinite",
      }}
    />
    Loading wallpapers…
  </div>
);

const ErrorPane = ({ message }) => (
  <div
    style={{
      position: "absolute",
      inset: 0,
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 12,
      color: "var(--fg)",
      fontFamily: "var(--font-ui)",
      padding: 24,
      textAlign: "center",
    }}
  >
    <div style={{ fontSize: 18, fontWeight: 600 }}>Couldn't load wallpapers</div>
    <div style={{ color: "var(--muted)", fontSize: 13, maxWidth: 320 }}>{message}</div>
    <div style={{ color: "var(--muted)", fontSize: 12, marginTop: 8 }}>
      Tip: open this page through a local server (e.g. <code>yarn dev</code>), not <code>file://</code>.
    </div>
  </div>
);

const BottomNav = ({ tab, setTab, hidden }) => {
  const items = [
    { id: "home", icon: "home", label: "Gallery" },
    { id: "search", icon: "search", label: "Search" },
    { id: "settings", icon: "user", label: "Profile" },
  ];
  return (
    <nav
      style={{
        position: "absolute",
        left: "50%",
        bottom: 22,
        transform: `translateX(-50%) translateY(${hidden ? 120 : 0}px)`,
        zIndex: 50,
        display: "flex",
        gap: 4,
        padding: 6,
        background: "color-mix(in oklab, var(--bg) 80%, transparent)",
        backdropFilter: "blur(20px) saturate(140%)",
        WebkitBackdropFilter: "blur(20px) saturate(140%)",
        border: "1px solid var(--line)",
        borderRadius: 999,
        boxShadow: "0 14px 40px -10px rgba(0,0,0,0.4)",
        transition: "transform 320ms cubic-bezier(0.2, 0.7, 0.2, 1)",
      }}
    >
      {items.map((it) => {
        const active = tab === it.id;
        return (
          <button
            key={it.id}
            onClick={() => setTab(it.id)}
            style={{
              appearance: "none",
              border: "none",
              background: active ? "var(--fg)" : "transparent",
              color: active ? "var(--bg)" : "var(--fg)",
              padding: "10px 18px",
              borderRadius: 999,
              fontFamily: "var(--font-ui)",
              fontSize: 12,
              fontWeight: 500,
              letterSpacing: "-0.005em",
              display: "flex",
              alignItems: "center",
              gap: 8,
              cursor: "pointer",
              transition: "all 220ms ease",
            }}
          >
            <Icon name={it.icon} size={16} />
            {it.label}
          </button>
        );
      })}
    </nav>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
