// app.jsx — root, routing, tweaks

const { useState: useStateA, useEffect: useEffectA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "prism",
  "heroAnim": "dispersion",
  "typeset": "editorial",
  "density": "regular"
}/*EDITMODE-END*/;

// palettes — each sets the prism accent colors
const PALETTES = {
  prism:     { cyan: "#00d4ff", blue: "#4a6cff", violet: "#8a4dff", magenta: "#ff2bd8", pink: "#ff5fa6", coral: "#ff7a4d", amber: "#ffb347", yellow: "#ffd84d" },
  cool:      { cyan: "#5ee9ff", blue: "#3a7bff", violet: "#7c3aed", magenta: "#3a7bff", pink: "#5ee9ff", coral: "#3a7bff", amber: "#7c3aed", yellow: "#5ee9ff" },
  sunset:    { cyan: "#ff8a3d", blue: "#ff4561", violet: "#ff2d6b", magenta: "#ff5757", pink: "#ffa66e", coral: "#ff6a4d", amber: "#ffd178", yellow: "#ffe17a" },
  mono:      { cyan: "#e8e6f0", blue: "#c0bdd0", violet: "#a09db0", magenta: "#e8e6f0", pink: "#e8e6f0", coral: "#a09db0", amber: "#e8e6f0", yellow: "#e8e6f0" },
};

const ROUTES = ["home","work","about","pricing","contact","order","confirmation","faq","blog"];

function routeFromPath(pathname) {
  const p = pathname.replace(/^\/+/, "").replace(/\/+$/, "");
  if (p === "") return "home";
  return ROUTES.includes(p) ? p : null;
}

function routeFromHash(hash) {
  const h = (hash || "").replace("#/", "");
  return ROUTES.includes(h) ? h : null;
}

const SITE_URL = "https://visimatic.net";

const SEO_META = {
  home: {
    title: "Visimatic - Custom Logo Animation Studio",
    description: "Bespoke logo animations hand-keyed in After Effects. No templates. A one-person motion studio turning static logos into animated brand assets in 2-5 days.",
  },
  work: {
    title: "Work - Logo Animation Portfolio | Visimatic",
    description: "Browse animated logo projects built from scratch in After Effects - minimal, kinetic, and cinematic styles for brands that want motion done right.",
  },
  about: {
    title: "About - Meet the Animator | Visimatic",
    description: "Visimatic is a solo motion designer specializing in custom logo animation. Every frame hand-keyed in After Effects - no templates, no presets.",
  },
  pricing: {
    title: "Pricing - Logo Animation Packages | Visimatic",
    description: "Logo animation packages from $150 to $300. Transparent pricing, fast delivery, and add-ons like sound effects, perfect loops, and rush turnaround.",
  },
  contact: {
    title: "Contact - Start Your Logo Animation | Visimatic",
    description: "Get in touch to discuss your logo animation project. Fast replies, custom quotes, and a straightforward process from brief to delivery.",
  },
  order: {
    title: "Order Your Logo Animation | Visimatic",
    description: "Start your custom logo animation order - pick a style, choose a package, and check out securely in minutes.",
  },
  confirmation: {
    title: "Order Confirmed | Visimatic",
    description: "Your logo animation order is confirmed. Upload your logo file to begin production.",
  },
  faq: {
    title: "FAQ - Logo Animation Questions Answered | Visimatic",
    description: "Answers to common questions about custom logo animation: pricing, delivery time, file formats, revisions, and the After Effects process.",
  },
  blog: {
    title: "Blog - Logo Animation Insights | Visimatic",
    description: "Notes on logo animation: file formats explained, what separates premium animated logos from cheap ones, and tips for YouTube intro animations.",
  },
};

function applySeoMeta(route) {
  const meta = SEO_META[route] || SEO_META.home;
  document.title = meta.title;

  let metaDesc = document.querySelector('meta[name="description"]');
  if (!metaDesc) {
    metaDesc = document.createElement("meta");
    metaDesc.setAttribute("name", "description");
    document.head.appendChild(metaDesc);
  }
  metaDesc.setAttribute("content", meta.description);

  let canonical = document.querySelector('link[rel="canonical"]');
  if (!canonical) {
    canonical = document.createElement("link");
    canonical.setAttribute("rel", "canonical");
    document.head.appendChild(canonical);
  }
  canonical.setAttribute("href", `${SITE_URL}${route === "home" ? "/" : "/" + route}`);
}

function App() {
  const [route, setRoute] = useStateA(() => {
    const fromPath = routeFromPath(window.location.pathname);
    const fromHash = routeFromHash(window.location.hash);
    // honor an old-style shared hash link even when pathname is just "/"
    if (fromHash && (window.location.pathname === "/" || window.location.pathname === "")) return fromHash;
    if (fromPath) return fromPath;
    if (fromHash) return fromHash;
    return "home";
  });
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // sync URL path for refresh-stable, indexable nav + per-route SEO metadata
  useEffectA(() => {
    const targetPath = route === "home" ? "/" : `/${route}`;
    if (window.location.pathname !== targetPath) {
      window.history.pushState(null, "", targetPath + window.location.search);
    }
    window.scrollTo({ top: 0, behavior: "instant" });
    applySeoMeta(route);
  }, [route]);

  // browser back/forward — pushState alone doesn't trigger React re-renders
  useEffectA(() => {
    const onPopState = () => {
      const fromPath = routeFromPath(window.location.pathname);
      setRoute(fromPath || "home");
    };
    window.addEventListener("popstate", onPopState);
    return () => window.removeEventListener("popstate", onPopState);
  }, []);

  // apply tweaks → CSS vars
  useEffectA(() => {
    const p = PALETTES[t.palette] || PALETTES.prism;
    const r = document.documentElement;
    r.style.setProperty("--p-cyan",    p.cyan);
    r.style.setProperty("--p-blue",    p.blue);
    r.style.setProperty("--p-violet",  p.violet);
    r.style.setProperty("--p-magenta", p.magenta);
    r.style.setProperty("--p-pink",    p.pink);
    r.style.setProperty("--p-coral",   p.coral);
    r.style.setProperty("--p-amber",   p.amber);
    r.style.setProperty("--p-yellow",  p.yellow);
    r.setAttribute("data-density", t.density);
    r.setAttribute("data-typeset", t.typeset);
  }, [t.palette, t.density, t.typeset]);

  return (
    <>
      <Nav route={route} setRoute={setRoute} />

      <div
        key={route} /* re-mount on route change for page-in animation */
        style={{ animation: "pageIn 600ms cubic-bezier(.2,.7,.2,1) both" }}
      >
        {route === "home"         && <Home         setRoute={setRoute} tweaks={t} />}
        {route === "work"         && <Work         setRoute={setRoute} />}
        {route === "about"        && <About        setRoute={setRoute} />}
        {route === "pricing"      && <Pricing      setRoute={setRoute} />}
        {route === "contact"      && <Contact      setRoute={setRoute} />}
        {route === "order"        && <Order        setRoute={setRoute} />}
        {route === "confirmation" && <Confirmation setRoute={setRoute} />}
        {route === "faq"          && <FAQ          setRoute={setRoute} />}
        {route === "blog"         && <Blog         setRoute={setRoute} />}

        <Footer setRoute={setRoute} />
      </div>

      <style>{`
        @keyframes pageIn {
          from { opacity: 0; transform: translateY(12px); filter: blur(8px); }
          to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
        }
      `}</style>

      <TweaksPanel>
        <TweakSection label="Palette" />
        <TweakRadio
          label="Spectrum"
          value={t.palette}
          options={["prism", "cool", "sunset", "mono"]}
          onChange={v => setTweak("palette", v)}
        />

        <TweakSection label="Hero animation" />
        <TweakRadio
          label="Prism motion"
          value={t.heroAnim}
          options={["dispersion", "spin", "tilt", "pulse"]}
          onChange={v => setTweak("heroAnim", v)}
        />

        <TweakSection label="Typography" />
        <TweakRadio
          label="Pairing"
          value={t.typeset}
          options={["editorial", "grotesk", "mono"]}
          onChange={v => setTweak("typeset", v)}
        />

        <TweakSection label="Layout" />
        <TweakRadio
          label="Density"
          value={t.density}
          options={["compact", "regular", "spacious"]}
          onChange={v => setTweak("density", v)}
        />
      </TweaksPanel>
    </>
  );
}

// Overlay server-managed content over the built-in fallback data. Every page
// component reads these VM_* globals inside its render function body (not at
// module-eval time), so reassigning them before the first render is enough —
// no page component needs to change.
function applyRemoteContent(data) {
  if (!data) return;
  if (data.showreel) window.VM_SHOWREEL = data.showreel;
  if (data.portfolio) window.VM_PORTFOLIO = data.portfolio;
  if (data.styles) window.VM_STYLES = data.styles;
  if (data.packages) window.VM_PACKAGES = data.packages;
  if (data.addons) window.VM_ADDONS = data.addons;
  if (data.reviews) window.VM_REVIEWS = data.reviews;
  if (data.posts) window.VM_POSTS = data.posts;
}

(async function bootVisimatic() {
  await window.__VM_CONTENT_READY__;
  applyRemoteContent(window.__VM_REMOTE_CONTENT__);
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
})();
