// App shell, routing + tweaks integration

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "accent": "#6ba6cf",
  "density": "comfortable",
  "showVerse": true
}/*EDITMODE-END*/;

const ACCENT_OPTIONS = [
  '#6ba6cf', // light blue (default)
  '#4a90c8', // steel blue
  '#f4a526', // amber
  '#ff5b1f', // industrial rust
  '#7a8a3e', // olive
];

// Per-page <title> and meta description.
//
// MUST stay in sync with scripts/seo-content.mjs, which is the source of truth
// and bakes these same strings into the static HTML for each route. A crawler
// that renders JS sees the values below; one that doesn't sees the baked ones.
// If they disagree, that reads as cloaking, so change both together.
const SITE_TITLE = 'Chambliss Steel Buildings | Custom Steel Structures in FL';
const SITE_ORIGIN = 'https://chamblisssb.com';
const ROUTE_META = {
  home: {
    title: SITE_TITLE,
    desc: 'Custom steel buildings, barndominiums and hangars, engineered and erected in North Florida. Licensed CBC1267224, BBB accredited.',
  },
  services: {
    title: 'Services | Steel Building Kits, Erection & Design-Build | Chambliss Steel Buildings',
    desc: 'Steel building supply packages, CAD drafting, concrete, erection, and turnkey design-build in North Florida — residential, commercial, agricultural, and specialty.',
  },
  specs: {
    title: 'Building Specs | Roof Lines, Frames, Panels & Colors | Chambliss Steel Buildings',
    desc: 'Roof lines, frame types, wind and load ratings, trim, wainscot, siding colors, Janus doors, insulation, and what comes standard on a Chambliss steel building.',
  },
  configurator: {
    title: '3D Steel Building Configurator | Chambliss Steel Buildings',
    desc: 'Design your steel building in 3D. Set span, length, height, roof pitch, and bays, see it update live, then send the configuration straight to us for a quote.',
  },
  portfolio: {
    title: 'Portfolio | Completed Steel Buildings | Chambliss Steel Buildings',
    desc: 'Completed steel buildings from Chambliss Steel Buildings — barndominiums, workshops, hangars, barns, and commercial projects across North Florida.',
  },
  store: {
    title: 'Store | Chambliss Steel Buildings',
    desc: 'Chambliss Steel Buildings apparel and gear. Shirts, hats, and merch from the Live Oak, Florida steel building contractor.',
  },
  about: {
    title: 'About | Family-Owned Steel Building Contractor in Live Oak, FL',
    desc: 'Chambliss Steel Buildings is a family-owned steel building contractor in Live Oak, Florida. FL Certified Building Contractor CBC1267224, BBB accredited, A+ rated.',
  },
  subcontractor: {
    title: 'Subcontractor Application | Chambliss Steel Buildings',
    desc: 'Apply to subcontract with Chambliss Steel Buildings — erection crews, concrete, and trades working steel building projects in North Florida.',
  },
  quote: {
    title: 'Get a Quote | Custom Steel Building Pricing | Chambliss Steel Buildings',
    desc: 'Get a quote on a custom steel building. Tell us the size, use, and site, or upload your own plans, and Chambliss Steel Buildings will price it.',
  },
};

// Point an existing <meta>/<link> at a new value, creating the tag if the
// static page didn't ship one. `attr` is 'name' for meta description/twitter,
// 'property' for Open Graph, 'rel' for the canonical link.
const setTag = (tag, attr, key, value) => {
  let el = document.head.querySelector(`${tag}[${attr}="${key}"]`);
  if (!el) {
    el = document.createElement(tag);
    el.setAttribute(attr, key);
    document.head.appendChild(el);
  }
  el.setAttribute(tag === 'link' ? 'href' : 'content', value);
};

const App = () => {
  // Initial screen comes from the URL, so deep links (/services, /store, …) land
  // on the right page.
  const [route, setRouteState] = React.useState(() => window.pathToRoute(window.location.pathname));
  const tweaks = window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : { t: TWEAK_DEFAULTS, setTweak: () => {} };
  const t = tweaks.t || TWEAK_DEFAULTS;

  // Navigate + reflect the screen in a real URL via history.pushState. This is
  // passed to every screen as `setRoute`, so all in-app navigation (nav links,
  // buttons, footer) updates the address bar.
  const setRoute = React.useCallback((r) => {
    setRouteState(r);
    const path = window.routeToPath(r);
    try {
      if (window.location.pathname !== path) {
        window.history.pushState({ route: r }, '', path);
      }
    } catch (e) { /* pushState can be blocked in some sandboxes; nav still works */ }
  }, []);

  // Apply theme + accent to :root
  React.useEffect(() => {
    document.documentElement.dataset.theme = t.theme === 'paper' ? 'paper' : '';
    document.documentElement.style.setProperty('--accent', t.accent);
  }, [t.theme, t.accent]);

  // Back / forward buttons: sync the route from the URL without pushing a new
  // history entry.
  React.useEffect(() => {
    const onPop = () => setRouteState(window.pathToRoute(window.location.pathname));
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  // Listen for nav events from inside components (footer/quote)
  React.useEffect(() => {
    const handler = (e) => setRoute(e.detail);
    window.addEventListener('nav', handler);
    return () => window.removeEventListener('nav', handler);
  }, [setRoute]);

  // Bridge from the FabTrk configurator iframe: when the visitor clicks
  // "Get this quoted", the embed postMessages its configuration up here. Stash it
  // (so the quote form can prefill / reference it) and route to the quote page.
  // Origin-gated: only same-origin or a known FabTrk embed origin is trusted ,
  // a third-party frame can't drive navigation or inject a spec.
  React.useEffect(() => {
    const fabtrkOrigins = () => {
      const set = new Set(['http://localhost:5173', 'http://127.0.0.1:5173']);
      // Only origins that actually host an embedded iframe belong here. The
      // REST API origin is deliberately not trusted, it never posts messages.
      ['FABTRK_DESIGNER_URL'].forEach((k) => {
        try { if (window[k]) set.add(new URL(window[k]).origin); } catch (e) {}
      });
      return set;
    };
    const onMessage = (e) => {
      const d = e.data;
      if (!d || d.type !== 'fabtrk:configurator:quote') return;
      if (e.origin !== window.location.origin && !fabtrkOrigins().has(e.origin)) return; // ignore unknown senders
      window.__configuratorSpec = d.config;
      window.dispatchEvent(new CustomEvent('configurator-spec', { detail: d.config }));
      setRoute('quote');
    };
    window.addEventListener('message', onMessage);
    return () => window.removeEventListener('message', onMessage);
  }, []);

  // Keep the document title, description, canonical and Open Graph tags in sync
  // with the current page. Client-side routing changes no document, so without
  // this every route would keep whichever page's tags happened to load first —
  // and a link shared from /quote would unfurl as the homepage.
  React.useEffect(() => {
    const meta = ROUTE_META[route] || ROUTE_META.home;
    const url = SITE_ORIGIN + window.routeToPath(route);
    document.title = meta.title;
    setTag('meta', 'name', 'description', meta.desc);
    setTag('link', 'rel', 'canonical', url);
    setTag('meta', 'property', 'og:url', url);
    setTag('meta', 'property', 'og:title', meta.title);
    setTag('meta', 'property', 'og:description', meta.desc);
    setTag('meta', 'name', 'twitter:title', meta.title);
    setTag('meta', 'name', 'twitter:description', meta.desc);
  }, [route]);

  // GA4 page_view on every route change. gtag is configured with
  // send_page_view:false in index.html, because client-side routing fires no
  // navigation, so without this only the first load would ever be counted.
  React.useEffect(() => {
    if (!window.GA_ENABLED || typeof window.gtag !== 'function') return;
    window.gtag('event', 'page_view', {
      page_title: (ROUTE_META[route] || ROUTE_META.home).title,
      page_location: window.location.origin + window.routeToPath(route),
      page_path: window.routeToPath(route),
    });
  }, [route]);

  // Scroll to top on route change
  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'instant' });
  }, [route]);

  return (
    <>
      <Nav route={route} setRoute={setRoute} />
      <main id="main" tabIndex={-1} key={route} data-screen-label={`${{home:'01 Home',services:'02 Services',specs:'02.A Specs',configurator:'03 Configurator',portfolio:'04 Portfolio',store:'05 Store',about:'06 About',subcontractor:'07 Subcontractor',quote:'08 Quote'}[route]}`}>
        {route === 'home' && <Home setRoute={setRoute} />}
        {route === 'services' && <Services setRoute={setRoute} />}
        {route === 'specs' && <Specs setRoute={setRoute} />}
        {route === 'configurator' && <ConfiguratorPage setRoute={setRoute} />}
        {route === 'portfolio' && <Portfolio setRoute={setRoute} />}
        {route === 'store' && <Store setRoute={setRoute} />}
        {route === 'about' && <About showVerse={t.showVerse} />}
        {route === 'subcontractor' && <Subcontractor />}
        {route === 'quote' && <Quote setRoute={setRoute} />}
      </main>
      <Footer setRoute={setRoute} />

      {/* Tweaks Panel */}
      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection label="Theme">
            <window.TweakRadio
              label="Mode"
              value={t.theme}
              onChange={(v) => tweaks.setTweak('theme', v)}
              options={[
                { value: 'dark', label: 'Dark' },
                { value: 'paper', label: 'Paper' },
              ]}
            />
            <window.TweakColor
              label="Accent"
              value={t.accent}
              onChange={(v) => tweaks.setTweak('accent', v)}
              options={ACCENT_OPTIONS}
            />
          </window.TweakSection>
          <window.TweakSection label="Content">
            <window.TweakToggle
              label="Show John 3:16 section"
              value={t.showVerse}
              onChange={(v) => tweaks.setTweak('showVerse', v)}
            />
          </window.TweakSection>
        </window.TweaksPanel>
      )}
    </>
  );
};

// scripts/build-seo.mjs bakes a plain-HTML summary of each page into every
// route, for crawlers that don't execute JavaScript. It lives inside a
// <noscript>, so this file has nothing to clean up: a browser running React
// never renders it in the first place. (It used to sit in the live DOM and be
// removed here, but Babel takes seconds to transpile this site, so visitors
// watched the text version get replaced.)
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
