/* The Handify — app shell: routing, cart, tweaks, page switch. */

// ── URL ↔ route helpers ─────────────────────────────────────────────────────
function routeToUrl(r) {
  if (r.name === "home")      return "/";
  if (r.name === "directory") return "/artists";
  if (r.name === "news")      return "/news";
  if (r.name === "shop")      return "/shop";
  if (r.name === "about")     return "/about";
  if (r.name === "profile")   return "/artist/" + r.slug;
  if (r.name === "artwork")   return "/artwork/" + r.id;
  return "/";
}

function urlToRoute(pathname) {
  if (!pathname || pathname === "/") return { name: "home" };
  if (pathname === "/artists")       return { name: "directory" };
  if (pathname === "/news")          return { name: "news" };
  if (pathname === "/shop")          return { name: "shop" };
  if (pathname === "/about")         return { name: "about" };
  const m = pathname.match(/^\/artist\/(.+)$/);
  if (m) return { name: "profile", slug: m[1] };
  const a = pathname.match(/^\/artwork\/(.+)$/);
  if (a) return { name: "artwork", id: a[1] };
  return { name: "home" };
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "paper",
  "accentColor": "#8670ef",
  "displayFont": "Syne",
  "homeLayout": "editorial",
  "directoryLayout": "grid",
  "profileLayout": "classic"
}/*EDITMODE-END*/;

const FONT_STACK = {
  Syne: "'Syne', sans-serif",
  Mulish: "'Mulish', sans-serif",
  "Space Mono": "'Space Mono', monospace",
};

function AboutPage({ navigate }) {
  return (
    <div className="about">
      <div className="about-masthead">
        <Eyebrow>About</Eyebrow>
        <h1 className="about-title">
          A LIVING INDEX<br />OF ARTISTS,<br />EVERYWHERE.
        </h1>
      </div>
      <div className="about-grid">
        <p className="about-lede">
          The Handify is a global directory and shop for working artists. We bring together painters,
          sculptors, photographers, ceramicists and digital makers from every corner of the world into
          one searchable index.
        </p>
        <div className="about-cols">
          <div className="about-col">
            <Eyebrow>Discover</Eyebrow>
            <p>Browse by field, location, style or name. Every artist has a public profile with their story, location and work.</p>
          </div>
          <div className="about-col">
            <Eyebrow>Read</Eyebrow>
            <p>Spotlights, studio visits and interviews keep you close to what artists are making right now.</p>
          </div>
          <div className="about-col">
            <Eyebrow>Collect</Eyebrow>
            <p>Buy original work and limited editions directly, with proceeds supporting the artists.</p>
          </div>
        </div>
        <button className="btn-primary" onClick={() => navigate({ name: "directory" })}>
          Explore the index →
        </button>
      </div>
    </div>
  );
}

class PageErrorBoundary extends React.Component {
  constructor(p) { super(p); this.state = { err: null }; }
  static getDerivedStateFromError(e) { return { err: e }; }
  render() {
    if (this.state.err) return (
      <div style={{padding:"32px",fontFamily:"monospace",fontSize:"13px",color:"#c00",background:"#fff3f3",margin:"24px",border:"1px solid #c00",whiteSpace:"pre-wrap",zIndex:9999,position:"relative"}}>
        <b>Render error — paste this to the developer:</b>{"\n\n"}{String(this.state.err)}{"\n"}{this.state.err && this.state.err.stack}
      </div>
    );
    return this.props.children;
  }
}

function App() {
  const data = window.HANDIFY_DATA;
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  const [route, setRoute] = React.useState(() => urlToRoute(window.location.pathname));
  const [cart, setCart] = React.useState(() => {
    try { return JSON.parse(localStorage.getItem("handify_cart") || "[]"); } catch (e) { return []; }
  });
  const [cartOpen, setCartOpen] = React.useState(false);
  const [globalSearch, setGlobalSearch] = React.useState("");

  React.useEffect(() => { localStorage.setItem("handify_cart", JSON.stringify(cart)); }, [cart]);

  React.useEffect(() => {
    const onPop = (e) => setRoute(e.state || urlToRoute(window.location.pathname));
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  const navigate = (r) => {
    setRoute(r);
    const url = routeToUrl(r);
    if (window.location.pathname !== url) history.pushState(r, "", url);
    window.scrollTo({ top: 0, behavior: "instant" in document.documentElement.style ? "instant" : "auto" });
  };
  const addToCart = (id) => {
    setCart((c) => {
      const ex = c.find((x) => x.id === id);
      if (ex) return c.map((x) => (x.id === id ? { ...x, qty: x.qty + 1 } : x));
      return [...c, { id, qty: 1 }];
    });
    setCartOpen(true);
  };
  const removeFromCart = (id) => setCart((c) => c.filter((x) => x.id !== id));
  const cartCount = cart.reduce((s, x) => s + x.qty, 0);

  const dark = t.palette === "night";
  const tickerItems = data.news.slice(0, 5).map((n) => `${n.kind}: ${n.title}`);

  let page;
  if (route.name === "home")
    page = <HomePage data={data} navigate={navigate} addToCart={addToCart} cart={cart} dark={dark} homeLayout={t.homeLayout} />;
  else if (route.name === "directory")
    page = <DirectoryPage data={data} navigate={navigate} dark={dark} route={route} globalSearch={globalSearch} directoryLayout={t.directoryLayout} />;
  else if (route.name === "profile") {
    const artist = data.artists.find((a) => a.slug === route.slug);
    page = <PageErrorBoundary key={route.slug}><ProfilePage artist={artist} data={data} navigate={navigate} addToCart={addToCart} cart={cart} dark={dark} profileLayout={t.profileLayout} /></PageErrorBoundary>;
  } else if (route.name === "artwork") {
    const work = data.allWorks.find((w) => w.id === route.id);
    page = <ArtworkPage work={work} data={data} navigate={navigate} addToCart={addToCart} cart={cart} dark={dark} />;
  } else if (route.name === "news")
    page = <NewsPage data={data} navigate={navigate} dark={dark} route={route} />;
  else if (route.name === "shop")
    page = <ShopPage data={data} navigate={navigate} addToCart={addToCart} cart={cart} dark={dark} route={route} />;
  else if (route.name === "about")
    page = <AboutPage navigate={navigate} />;
  else page = <HomePage data={data} navigate={navigate} addToCart={addToCart} cart={cart} dark={dark} homeLayout={t.homeLayout} />;

  return (
    <div
      className="handify-root"
      data-pal={t.palette}
      style={{ "--accent": t.accentColor, "--display": FONT_STACK[t.displayFont] || FONT_STACK.Anton }}
    >
      <Ticker items={tickerItems} />
      <Header
        route={route}
        navigate={navigate}
        cartCount={cartCount}
        onCartOpen={() => setCartOpen(true)}
        onSearch={(v) => { setGlobalSearch(v); }}
        searchValue={globalSearch}
      />
      <main className="site-main">{page}</main>
      <Footer navigate={navigate} />

      <CartDrawer
        open={cartOpen}
        onClose={() => setCartOpen(false)}
        cart={cart}
        works={data.allWorks}
        removeFromCart={removeFromCart}
        navigate={navigate}
        dark={dark}
      />

      <TweaksPanel>
        <TweakSection label="Look" />
        <TweakRadio
          label="Palette" value={t.palette}
          options={[{ label: "Paper", value: "paper" }, { label: "Mono", value: "mono" }, { label: "Night", value: "night" }]}
          onChange={(v) => setTweak("palette", v)}
        />
        <TweakColor
          label="Accent" value={t.accentColor}
          options={["#8670ef", "#fad764", "#ef7086", "#70efbc"]}
          onChange={(v) => setTweak("accentColor", v)}
        />
        <TweakRadio
          label="Display font" value={t.displayFont}
          options={[{ label: "Syne", value: "Syne" }, { label: "Mulish", value: "Mulish" }, { label: "Space Mono", value: "Space Mono" }]}
          onChange={(v) => setTweak("displayFont", v)}
        />
        <TweakSection label="Home layout" />
        <TweakRadio
          label="Hero" value={t.homeLayout}
          options={[{ label: "Editorial", value: "editorial" }, { label: "Grid", value: "grid" }, { label: "Poster", value: "poster" }]}
          onChange={(v) => { setTweak("homeLayout", v); if (route.name !== "home") navigate({ name: "home" }); }}
        />
        <TweakSection label="Directory layout" />
        <TweakRadio
          label="View" value={t.directoryLayout}
          options={[{ label: "Gallery", value: "grid" }, { label: "Index", value: "index" }]}
          onChange={(v) => { setTweak("directoryLayout", v); if (route.name !== "directory") navigate({ name: "directory" }); }}
        />
        <TweakSection label="Profile layout" />
        <TweakRadio
          label="Style" value={t.profileLayout}
          options={[{ label: "Classic", value: "classic" }, { label: "Split", value: "split" }, { label: "Magazine", value: "magazine" }]}
          onChange={(v) => {
            setTweak("profileLayout", v);
            if (route.name !== "profile") navigate({ name: "profile", slug: data.artists.find((a) => a.featured).slug });
          }}
        />
      </TweaksPanel>
    </div>
  );
}

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