/* bloo.app — SPA shell: mounts SiteNav + SiteFooter ONCE (they never remount,
   so the header stays static across navigation) and swaps only the routed
   page's content, intercepting clicks on our own .html links so navigation
   is client-side (real pushState, real URLs, browser back/forward all work)
   instead of a full document reload. A calm fade+lift replaces the old
   full-screen white-flash. Falls back to instant swap under
   prefers-reduced-motion. Must load AFTER shared.jsx and every page script
   (each page registers itself on window.Pages). */
(function () {
  const { SiteNav, SiteFooter } = window.Site;
  const { LocaleProvider, useLocale } = window.I18n;

  const FILES = {
    home: 'index.html',
    services: 'services.html',
    'case-studies': 'case-studies.html',
    products: 'products.html',
    'ai-code-review': 'product-ai-code-review.html',
    'ai-code-review-inside': 'product-ai-code-review-inside.html',
    about: 'about.html',
    contact: 'contact.html',
  };
  const KEY_FOR_FILE = { '': 'home' };
  Object.keys(FILES).forEach((k) => { KEY_FOR_FILE[FILES[k]] = k; });

  const SITE_ORIGIN = 'https://bloo.app';
  const OG_IMAGE = `${SITE_ORIGIN}/uploads/square-mark.png`;

  const PAGE_TITLES = {
    home: { en: 'bloo.app — move faster with AI, without the guesswork', pt: 'bloo.app — avance mais rápido com IA, sem tentativa e erro' },
    services: { en: 'Services — bloo.app', pt: 'Serviços — bloo.app' },
    'case-studies': { en: 'Case studies — bloo.app', pt: 'Estudos de caso — bloo.app' },
    products: { en: 'Products — bloo.app', pt: 'Produtos — bloo.app' },
    'ai-code-review': { en: 'AI Code Review Skill Pack — bloo.app', pt: 'Pacote de skills de revisão de código com IA — bloo.app' },
    'ai-code-review-inside': { en: "What's inside — AI Code Review Skill Pack — bloo.app", pt: 'O que tem dentro — Pacote de skills de revisão de código com IA — bloo.app' },
    about: { en: 'About — bloo.app', pt: 'Sobre — bloo.app' },
    contact: { en: 'Contact — bloo.app', pt: 'Contato — bloo.app' },
  };

  const PAGE_DESCRIPTIONS = {
    home: {
      en: 'bloo helps teams adopt AI on solid ground: Flutter and UX front-end work, AI-augmented dev workflows, and guided AI rollouts for non-technical teams.',
      pt: 'A bloo ajuda times a adotar IA com segurança: front-end em Flutter e UX, fluxos de desenvolvimento com IA e implantações guiadas para quem não escreve código.',
    },
    services: {
      en: 'Flutter and UX front-end builds, AI-augmented dev workflows, and guided AI rollouts for teams — production-grade work from someone who has shipped real products.',
      pt: 'Desenvolvimento front-end em Flutter e UX, fluxos de dev com IA e implantações guiadas de IA para times — trabalho em nível de produção de quem já lançou produtos reais.',
    },
    'case-studies': {
      en: 'Real results from bloo client work: faster code review, AI adoption for non-technical teams, and routine automation — with metrics, not marketing fluff.',
      pt: 'Resultados reais de projetos com clientes bloo: revisão de código mais rápida, adoção de IA em times não técnicos e automação de rotinas — com métricas, não enrolação.',
    },
    products: {
      en: 'Ready-made AI skill packs and Flutter templates from real client engagements — code review skills, automation configs, and production-grade UI starters.',
      pt: 'Pacotes de skills de IA e templates Flutter prontos, direto de projetos reais — skills de revisão de código, automação e starters de UI em nível de produção.',
    },
    'ai-code-review': {
      en: '40+ ready-to-use files that turn Claude, Cursor, or GitHub Copilot into a consistent, high-signal code reviewer: auto-installer, 10 review prompts, integrations, checklists, and team rollout docs.',
      pt: 'Mais de 40 arquivos prontos que transformam Claude, Cursor ou GitHub Copilot em um revisor de código consistente e de alto sinal: instalador automático, 10 prompts, integrações, checklists e docs de adoção.',
    },
    'ai-code-review-inside': {
      en: 'A file-by-file deep-dive into the AI Code Review Skill Pack: ten specialized review passes, five slash commands, and a live explorer of exactly what installs into your repo.',
      pt: 'Um mergulho arquivo a arquivo no Pacote de skills de revisão de código com IA: dez passes especializados, cinco comandos slash e um explorador ao vivo do que instala no seu repositório.',
    },
    about: {
      en: 'bloo is Bruno Luigi — a solo practitioner helping teams move faster with AI through Flutter front-end work, dev workflows, and practical rollouts.',
      pt: 'bloo é Bruno Luigi — profissional solo que ajuda times a avançar com IA via front-end Flutter, fluxos de dev e implantações práticas.',
    },
    contact: {
      en: 'Book a 30-minute call or send a message to bloo — contato@bloo.app. Start a conversation about Flutter, AI workflows, or team adoption.',
      pt: 'Agende uma call de 30 minutos ou envie uma mensagem para a bloo — contato@bloo.app. Converse sobre Flutter, fluxos de IA ou adoção em equipe.',
    },
  };

  const PAGE_URLS = {
    home: `${SITE_ORIGIN}/`,
    services: `${SITE_ORIGIN}/services.html`,
    'case-studies': `${SITE_ORIGIN}/case-studies.html`,
    products: `${SITE_ORIGIN}/products.html`,
    'ai-code-review': `${SITE_ORIGIN}/product-ai-code-review.html`,
    'ai-code-review-inside': `${SITE_ORIGIN}/product-ai-code-review-inside.html`,
    about: `${SITE_ORIGIN}/about.html`,
    contact: `${SITE_ORIGIN}/contact.html`,
  };

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

  function upsertLink(rel, href) {
    let el = document.head.querySelector(`link[rel="${rel}"]`);
    if (!el) {
      el = document.createElement('link');
      el.setAttribute('rel', rel);
      document.head.appendChild(el);
    }
    el.setAttribute('href', href);
  }

  function syncPageMeta(routeKey, locale) {
    const lang = locale === 'pt' ? 'pt' : 'en';
    const title = PAGE_TITLES[routeKey]?.[lang];
    const description = PAGE_DESCRIPTIONS[routeKey]?.[lang];
    const url = PAGE_URLS[routeKey];
    if (title) document.title = title;
    if (description) upsertMeta({ name: 'description', content: description });
    if (url) upsertLink('canonical', url);
    if (title) {
      upsertMeta({ property: 'og:title', content: title });
      upsertMeta({ name: 'twitter:title', content: title });
    }
    if (description) {
      upsertMeta({ property: 'og:description', content: description });
      upsertMeta({ name: 'twitter:description', content: description });
    }
    if (url) 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: OG_IMAGE });
    upsertMeta({ property: 'og:locale', content: lang === 'pt' ? 'pt_BR' : 'en_US' });
    upsertMeta({ name: 'twitter:card', content: 'summary' });
    upsertMeta({ name: 'twitter:image', content: OG_IMAGE });
    document.documentElement.lang = lang;
  }

  function keyFromPath(pathname) {
    return KEY_FOR_FILE[pathname.split('/').pop()] || 'home';
  }

  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(() => keyFromPath(window.location.pathname));
    const [visible, setVisible] = React.useState(true);
    const pending = React.useRef(null);
    const [locale] = useLocale();

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

    React.useEffect(() => {
      window.scrollTo({ top: 0, left: 0, behavior: 'instant' });
    }, [routeKey]);

    React.useEffect(() => {
      function go(key, href) {
        if (key === routeKey) return;
        if (pending.current) window.clearTimeout(pending.current);
        if (reduceMotion) {
          window.history.pushState({}, '', href);
          setRouteKey(key);
          return;
        }
        setVisible(false);
        pending.current = window.setTimeout(() => {
          window.history.pushState({}, '', href);
          setRouteKey(key);
          setVisible(true);
          pending.current = null;
        }, 160);
      }
      function onClick(e) {
        if (e.defaultPrevented || e.button !== 0) return;
        if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
        const a = e.target.closest ? e.target.closest('a') : null;
        if (!a || a.target === '_blank' || a.hasAttribute('download')) return;
        const key = KEY_FOR_FILE[a.getAttribute('href') || ''];
        if (!key) return; // not one of our pages — let mailto/external/etc behave normally
        e.preventDefault();
        go(key, a.getAttribute('href'));
      }
      function onPop() {
        setRouteKey(keyFromPath(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;

    // Defense against a transient network hiccup dropping one of the page
    // scripts (each page registers itself on window.Pages when its own
    // <script> tag loads — see the head comment above). Rather than crash
    // on `undefined.Content`, do ONE reload to recover. One-shot flag (not
    // a time window) so this can never loop no matter how slow the reload
    // itself is — if the reload didn't fix it, we just show blank instead
    // of retrying again.
    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 (
      <>
        <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>);
})();
