/* bloo.app — region-aware SPA shell. Same-region page changes use pushState;
   region changes always perform a full navigation so static metadata matches. */
(function () {
  const {
    PRODUCT,
    SITE_CONFIG,
    REGION,
    SiteNav,
    SiteFooter,
    equivalentRegionHref,
    trackEvent,
  } = window.Site;
  const { LocaleProvider } = window.I18n;

  function upsertMeta({ property, name, content }) {
    const selector = property ? `meta[property="${property}"]` : `meta[name="${name}"]`;
    let element = document.head.querySelector(selector);
    if (!element) {
      element = document.createElement('meta');
      if (property) element.setAttribute('property', property);
      else element.setAttribute('name', name);
      document.head.appendChild(element);
    }
    element.setAttribute('content', content);
  }

  function upsertLink(rel, href, attributes = {}) {
    const attributeSelector = Object.entries(attributes).map(([key, value]) => `[${key}="${value}"]`).join('');
    let element = document.head.querySelector(`link[rel="${rel}"]${attributeSelector}`);
    if (!element) {
      element = document.createElement('link');
      element.setAttribute('rel', rel);
      Object.entries(attributes).forEach(([key, value]) => element.setAttribute(key, value));
      document.head.appendChild(element);
    }
    element.setAttribute('href', href);
  }

  function syncPageMeta(routeKey) {
    const route = SITE_CONFIG.routes[routeKey] || SITE_CONFIG.routes.home;
    const title = route.title[REGION.locale];
    const description = route.description[REGION.locale];
    const url = SITE_CONFIG.urlForRoute(routeKey, REGION.key);
    const intlUrl = SITE_CONFIG.urlForRoute(routeKey, 'intl');
    const brUrl = SITE_CONFIG.urlForRoute(routeKey, 'br');
    const otherRegion = REGION.key === 'br' ? SITE_CONFIG.regions.intl : SITE_CONFIG.regions.br;

    document.title = title;
    document.documentElement.lang = REGION.locale;
    document.documentElement.dataset.region = REGION.key;
    upsertMeta({ name: 'description', content: description });
    upsertLink('canonical', url);
    upsertLink('alternate', intlUrl, { hreflang: 'en' });
    upsertLink('alternate', brUrl, { hreflang: 'pt-BR' });
    upsertLink('alternate', intlUrl, { hreflang: 'x-default' });
    upsertMeta({ property: 'og:title', content: title });
    upsertMeta({ property: 'og:description', content: description });
    upsertMeta({ property: 'og:url', content: url });
    upsertMeta({ property: 'og:site_name', content: 'bloo.app' });
    upsertMeta({ property: 'og:type', content: 'website' });
    upsertMeta({ property: 'og:image', content: SITE_CONFIG.ogImage });
    upsertMeta({ property: 'og:locale', content: REGION.ogLocale });
    upsertMeta({ property: 'og:locale:alternate', content: otherRegion.ogLocale });
    upsertMeta({ name: 'twitter:card', content: 'summary' });
    upsertMeta({ name: 'twitter:title', content: title });
    upsertMeta({ name: 'twitter:description', content: description });
    upsertMeta({ name: 'twitter:image', content: SITE_CONFIG.ogImage });

    let productSchema = document.getElementById('bloo-product-schema');
    if (route.schema !== 'product') {
      if (productSchema) productSchema.remove();
      return;
    }
    if (!productSchema) {
      productSchema = document.createElement('script');
      productSchema.type = 'application/ld+json';
      productSchema.id = 'bloo-product-schema';
      document.head.appendChild(productSchema);
    }
    const schema = {
      '@context': 'https://schema.org',
      '@type': 'SoftwareApplication',
      name: PRODUCT.name,
      softwareVersion: PRODUCT.version,
      applicationCategory: 'DeveloperApplication',
      operatingSystem: 'Claude Code, Cursor, GitHub Copilot',
      inLanguage: REGION.locale,
      description,
      url,
      brand: { '@type': 'Brand', name: 'bloo.app' },
      releaseNotes: SITE_CONFIG.urlForRoute('changelog', REGION.key),
    };
    if (PRODUCT.stage === 'stable' && PRODUCT.publicOffer === 'standard' && PRODUCT.productionValidated) {
      schema.offers = {
        '@type': 'Offer',
        price: String(PRODUCT.standardPriceUsd),
        priceCurrency: 'USD',
        availability: 'https://schema.org/InStock',
        url,
      };
    }
    productSchema.textContent = JSON.stringify(schema);
  }

  function publicRouteFromUrl(url) {
    if (url.origin !== window.location.origin) return null;
    const regionKey = SITE_CONFIG.regionKeyFromPath(url.pathname);
    const routeKey = SITE_CONFIG.routeKeyFromPath(url.pathname);
    const expected = SITE_CONFIG.pathForRoute(routeKey, regionKey);
    const acceptedHomeAlias = routeKey === 'home' && (url.pathname === '/index.html' || url.pathname === '/br/index.html');
    if (url.pathname !== expected && !acceptedHomeAlias) return null;
    return { regionKey, routeKey };
  }

  function RegionSuggestion() {
    const storageKey = 'bloo_region_suggestion_br_dismissed_v1';
    const [visible, setVisible] = React.useState(false);

    React.useEffect(() => {
      let dismissed = false;
      try { dismissed = localStorage.getItem(storageKey) === '1'; } catch (_) {}
      const languages = (navigator.languages && navigator.languages.length)
        ? navigator.languages
        : [navigator.language || ''];
      if (SITE_CONFIG.shouldSuggestBrazilRegion(REGION.key, languages, dismissed)) setVisible(true);
    }, []);

    function dismiss() {
      try { localStorage.setItem(storageKey, '1'); } catch (_) {}
      setVisible(false);
      trackEvent('dismiss_region_suggestion', { suggested_region: 'br' });
    }

    if (!visible) return null;
    return (
      <aside className="region-suggestion" aria-label="Sugestão de região">
        <div className="site-container region-suggestion__inner" style={{ maxWidth: 1120, margin: '0 auto', padding: '0 var(--space-8)' }}>
          <span>Você está no Brasil? Veja o site em português com preços em reais.</span>
          <a className="region-suggestion__link" href={equivalentRegionHref('br')} onClick={() => trackEvent('accept_region_suggestion', { suggested_region: 'br' })}>
            Brasil · Português · BRL
          </a>
          <button className="region-suggestion__dismiss" type="button" onClick={dismiss}>Agora não</button>
        </div>
      </aside>
    );
  }

  const reduceMotion = !!(window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches);
  if ('scrollRestoration' in history) history.scrollRestoration = 'manual';

  function App() {
    const [routeKey, setRouteKey] = React.useState(() => SITE_CONFIG.routeKeyFromPath(window.location.pathname));
    const [visible, setVisible] = React.useState(true);
    const pending = React.useRef(null);

    React.useEffect(() => {
      syncPageMeta(routeKey);
      if (typeof window.va === 'function') window.va('pageview');
    }, [routeKey]);

    React.useEffect(() => {
      window.requestAnimationFrame(() => {
        if (window.location.hash) {
          const id = decodeURIComponent(window.location.hash.slice(1));
          document.getElementById(id)?.scrollIntoView();
        } else {
          window.scrollTo({ top: 0, left: 0, behavior: 'instant' });
        }
      });
    }, [routeKey]);

    React.useEffect(() => {
      function go(key, href) {
        if (pending.current) window.clearTimeout(pending.current);
        const complete = () => {
          window.history.pushState({}, '', href);
          setRouteKey(key);
          setVisible(true);
          pending.current = null;
        };
        if (reduceMotion) return complete();
        setVisible(false);
        pending.current = window.setTimeout(complete, 160);
      }

      function onClick(event) {
        if (event.defaultPrevented || event.button !== 0) return;
        if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
        const anchor = event.target.closest ? event.target.closest('a') : null;
        if (!anchor || anchor.target === '_blank' || anchor.hasAttribute('download')) return;
        const url = new URL(anchor.href, window.location.href);
        const target = publicRouteFromUrl(url);
        if (!target || target.regionKey !== REGION.key) return;
        if (target.routeKey === routeKey) return;
        event.preventDefault();
        go(target.routeKey, `${url.pathname}${url.search}${url.hash}`);
      }

      function onPop() {
        setRouteKey(SITE_CONFIG.routeKeyFromPath(window.location.pathname));
        setVisible(true);
      }

      document.addEventListener('click', onClick);
      window.addEventListener('popstate', onPop);
      return () => {
        document.removeEventListener('click', onClick);
        window.removeEventListener('popstate', onPop);
        if (pending.current) window.clearTimeout(pending.current);
      };
    }, [routeKey]);

    const page = window.Pages[routeKey] || window.Pages.home;
    React.useEffect(() => {
      if (page) return;
      const guardKey = '__bloo_reload_guard';
      if (sessionStorage.getItem(guardKey)) return;
      sessionStorage.setItem(guardKey, '1');
      window.location.reload();
    }, [page]);

    if (!page) return null;
    const Content = page.Content;
    return (
      <>
        <RegionSuggestion />
        <SiteNav active={routeKey} />
        <div
          data-screen-label={page.label}
          style={{
            opacity: visible ? 1 : 0,
            transform: visible ? 'translateY(0)' : 'translateY(var(--space-2))',
            transition: reduceMotion ? 'none' : 'opacity 200ms var(--ease-standard, ease), transform 200ms var(--ease-standard, ease)',
          }}
        >
          <Content />
        </div>
        <SiteFooter />
      </>
    );
  }

  ReactDOM.createRoot(document.getElementById('root')).render(<LocaleProvider><App /></LocaleProvider>);
})();
