/* Klipzy.lv — app shell, router, tweaks */
// Pin a fixed <base> at the initial document directory so relative asset URLs
// (assets/…, styles.css) keep resolving after clean-path pushState navigation.
// Skipped when the host (WordPress theme) already provides a <base>.
(function () {
  try {
    if (document.querySelector('base')) return;
    const dir = location.href.split('#')[0].split('?')[0].replace(/[^/]*$/, '');
    const b = document.createElement('base');
    b.href = dir;
    document.head.insertBefore(b, document.head.firstChild);
  } catch (_) {}
})();
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2563EB",
  "radius": 10,
  "density": "regular",
  "font": "Geist"
}/*EDITMODE-END*/;

function darken(hex, amt) {
  const n = parseInt(hex.slice(1), 16);
  let r = (n >> 16) - amt, g = ((n >> 8) & 255) - amt, b = (n & 255) - amt;
  r = Math.max(0, r); g = Math.max(0, g); b = Math.max(0, b);
  return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
function tint(hex, amt) {
  const n = parseInt(hex.slice(1), 16);
  let r = (n >> 16), g = ((n >> 8) & 255), b = (n & 255);
  r = Math.round(r + (255 - r) * amt); g = Math.round(g + (255 - g) * amt); b = Math.round(b + (255 - b) * amt);
  return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

/* ---- Firebase auth state ---- */
function useFirebaseAuth() {
  const [authState, setAuthState] = useState({ status: 'loading', user: null, profile: null });
  useEffect(() => {
    let unsub = null;
    let active = true;
    (window.__firebaseReady || Promise.resolve(window.KlipzyFirebase)).then((fb) => {
      if (!active || !fb) return;
      unsub = fb.onAuth((res) => {
        if (!active) return;
        if (res && res.user) setAuthState({ status: 'in', user: res.user, profile: res.profile });
        else setAuthState({ status: 'out', user: null, profile: null });
      });
    });
    return () => { active = false; if (unsub) unsub(); };
  }, []);
  // Live-patch the profile when settings/photo change, so the sidebar
  // avatar + name update immediately without a full re-auth.
  useEffect(() => {
    const on = (e) => {
      const d = e.detail || {};
      setAuthState((s) => (s.user && (!d.uid || d.uid === s.user.uid)
        ? { ...s, profile: { ...(s.profile || {}), ...(d.patch || {}) } } : s));
    };
    window.addEventListener('klipzy-profile', on);
    return () => window.removeEventListener('klipzy-profile', on);
  }, []);
  return authState;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [route, setRoute] = useState('landing');
  const [params, setParams] = useState({});
  const audFromHash = () => (location.hash.replace(/[#/]/g, '').toLowerCase() === 'zimoliem' ? 'brand' : 'clipper');
  const [aud, setAud] = useState(audFromHash);
  const [lang, setLang] = useState(() => { try { return localStorage.getItem('klipzy_lang') || 'lv'; } catch (_) { return 'lv'; } });
  useEffect(() => {
    const onLang = (e) => setLang(e.detail || (localStorage.getItem('klipzy_lang') || 'lv'));
    window.addEventListener('klipzy-lang', onLang);
    return () => window.removeEventListener('klipzy-lang', onLang);
  }, []);
  const authState = useFirebaseAuth();
  const scrollRef = useRef(null);
  // keep the URL language prefix in sync when the switcher changes language
  const langSyncRef = useRef(lang);
  useEffect(() => {
    if (langSyncRef.current === lang) return;
    langSyncRef.current = lang;
    try { history.replaceState(null, '', pathFor(route, params)); } catch (_) {}
  }, [lang]);

  // ---- Clean path-based routing (real URLs like klipzy.lv/kampanas) --------
  // BASE is the site sub-path the app is mounted at (theme injects it; '/' on
  // Firebase Hosting, e.g. '/' or '/app/' on WordPress). All routes resolve
  // against it so the app works at the domain root or a sub-path.
  const BASE = (function () { let b = (typeof window !== 'undefined' && window.KLIPZY_BASE) || '/'; if (!b.startsWith('/')) b = '/' + b; if (!b.endsWith('/')) b += '/'; return b; })();
  const SLUGS = { landing: '', marketplace: 'kampanas', pricing: 'cenas', academy: 'macibas', 'for-clippers': 'klipotajiem', 'for-brands': 'zimoliem-info', about: 'par-mums', blog: 'blogs', contact: 'kontakti', help: 'palidziba', auth: 'pieslegties', clipper: 'panelis', brand: 'zimola-panelis', admin: 'admin' };
  const LEGAL_SLUG = { terms: 'noteikumi', privacy: 'privatums', security: 'drosiba' };
  const slugToRoute = (seg0) => {
    if (seg0 === 'zimoliem') return { route: 'landing', params: {} };
    for (const k in SLUGS) if (SLUGS[k] === seg0 && seg0) return { route: k, params: {} };
    for (const k in LEGAL_SLUG) if (LEGAL_SLUG[k] === seg0) return { route: 'legal', params: { page: k } };
    return null;
  };
  const langSeg = () => (lang === 'en' ? 'en/' : '');
  // Build the URL path for a route. Campaigns/articles carry a name-slug.
  const pathFor = (r, p) => {
    let seg;
    if (r === 'article') seg = 'raksts/' + (p.slug || p.id || '');
    else if (r === 'campaign') seg = 'kampanas/' + (p.slug || p.id || '');
    else if (r === 'legal') seg = LEGAL_SLUG[p.page || 'terms'] || 'noteikumi';
    else if (r === 'landing') seg = (aud === 'brand' ? 'zimoliem' : '');
    else seg = SLUGS[r] != null ? SLUGS[r] : '';
    return BASE + langSeg() + seg;
  };
  // Read the language prefix (en/lv) from the URL, if present.
  const langFromPath = () => {
    let path = location.pathname; if (path.startsWith(BASE)) path = path.slice(BASE.length);
    var seg0 = path.replace(/^\/+/, '').split('/')[0];
    return seg0 === 'en' ? 'en' : (seg0 === 'lv' ? 'lv' : null);
  };
  const parsePath = () => {
    let path = location.pathname;
    if (path.startsWith(BASE)) path = path.slice(BASE.length);
    path = path.replace(/^\/+/, '').replace(/\/+$/, '');
    // migrate any legacy #/… links to the same segments
    if (!path && location.hash) path = location.hash.replace(/^#\/?/, '').replace(/\/+$/, '');
    const segs = path.split('/').filter(Boolean);
    if (segs[0] === 'en' || segs[0] === 'lv') segs.shift(); // drop language prefix
    if (!segs.length) return { route: 'landing', params: {} };
    // Preview/host contexts serve the app as a file (…/Klipzy.html) or under a
    // deep path — treat any filename-like segment as the landing page, not 404.
    if (segs[segs.length - 1].indexOf('.') !== -1) return { route: 'landing', params: {} };
    if (segs[0] === 'raksts' && segs[1]) return { route: 'article', params: { slug: segs[1], id: segs[1], from: 'blog' } };
    if (segs[0] === 'kampanas' && segs[1]) return { route: 'campaign', params: { slug: segs[1], id: segs[1] } };
    return slugToRoute(segs[0]);
  };
  const audFromPath = () => {
    let path = location.pathname; if (path.startsWith(BASE)) path = path.slice(BASE.length);
    var segs = path.replace(/\/+$/, '').replace(/^\/+/, '').split('/');
    if (segs[0] === 'en' || segs[0] === 'lv') segs.shift();
    return segs[0] === 'zimoliem' ? 'brand' : 'clipper';
  };

  const go = (r, p = {}) => {
    // remember where we came from so the auth screen can offer a real "back"
    if (r === 'auth') { try { p = { ...p, from: route }; } catch (_) {} }
    setParams(p);
    setRoute(r);
    const url = pathFor(r, p);
    if (location.pathname + location.hash !== url) history.pushState(null, '', url);
    requestAnimationFrame(() => {
      const sc = document.querySelector('.app-scroll');
      if (sc) sc.scrollTop = 0;
    });
  };

  const setAudience = (a) => {
    setAud(a);
    setParams({});
    setRoute('landing');
    history.pushState(null, '', BASE + langSeg() + (a === 'brand' ? 'zimoliem' : ''));
    requestAnimationFrame(() => { const sc = document.querySelector('.app-scroll'); if (sc) sc.scrollTop = 0; });
  };

  useEffect(() => {
    const applyFromPath = () => {
      // adopt language from the URL prefix (/en/… or /lv/…) when present
      var lp = langFromPath();
      if (lp) { try { localStorage.setItem('klipzy_lang', lp); } catch (_) {} setLang(lp); window.dispatchEvent(new CustomEvent('klipzy-lang', { detail: lp })); }
      setAud(audFromPath());
      const parsed = parsePath();
      const next = parsed ? parsed.route : 'notfound';
      // Only touch route state when the URL actually points somewhere new, so a
      // mobile soft-keyboard viewport resize (which can fire spurious events)
      // never remounts the current screen and wipes an in-progress input.
      setRoute((cur) => (cur === next ? cur : next));
      if (parsed) setParams(parsed.params || {});
    };
    applyFromPath();
    window.addEventListener('popstate', applyFromPath);
    window.addEventListener('hashchange', applyFromPath);
    return () => { window.removeEventListener('popstate', applyFromPath); window.removeEventListener('hashchange', applyFromPath); };
  }, []);

  // ---- Role-based access control ----
  // Each dashboard route is restricted to one role. If a signed-in user lands
  // on a dashboard that isn't theirs, send them to their own.
  const DASHBOARDS = { clipper: true, brand: true, admin: true };
  const role = authState.profile && authState.profile.role;
  useEffect(() => {
    if (!DASHBOARDS[route]) return;        // not a protected dashboard
    if (authState.status !== 'in') return; // handled by the render guard below
    if (!role) return;                     // wait until the role is known
    const home = homeForRole(role);
    if (route !== home) go(home, { tab: 'panel' });
  }, [route, authState.status, role]);

  // Per-page document title (tab name).
  useEffect(() => {
    const en = lang === 'en';
    const T = {
      landing: en ? 'Klipzy' : 'Klipzy',
      marketplace: en ? 'Campaigns' : 'Kampaņas',
      pricing: en ? 'Pricing' : 'Cenas',
      academy: en ? 'Learning' : 'Mācības',
      'for-clippers': en ? 'For Clippers' : 'Klipotājiem',
      'for-brands': en ? 'For Brands' : 'Zīmoliem',
      about: en ? 'About us' : 'Par mums',
      blog: en ? 'Blog' : 'Blogs',
      article: en ? 'Blog' : 'Blogs',
      contact: en ? 'Contact' : 'Kontakti',
      help: en ? 'Help' : 'Palīdzība',
      legal: en ? 'Legal' : 'Juridiskā informācija',
      campaign: en ? 'Campaign' : 'Kampaņa',
      auth: en ? 'Sign in' : 'Pieslēgties',
      clipper: en ? 'Dashboard' : 'Panelis',
      brand: en ? 'Dashboard' : 'Panelis',
      admin: en ? 'Admin' : 'Administrācija',
      notfound: en ? 'Page not found' : 'Lapa nav atrasta',
    };
    const name = T[route];
    document.title = (!name || route === 'landing') ? 'Klipzy' : name + ' — Klipzy';
  }, [route, lang]);

  // apply tweaks to :root
  useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--accent', t.accent);
    r.style.setProperty('--accent-700', darken(t.accent, 28));
    r.style.setProperty('--accent-500', tint(t.accent, 0.12));
    r.style.setProperty('--accent-tint', tint(t.accent, 0.92));
    r.style.setProperty('--accent-tint-2', tint(t.accent, 0.82));
    r.style.setProperty('--r-sm', (t.radius - 2) + 'px');
    r.style.setProperty('--r', t.radius + 'px');
    r.style.setProperty('--r-lg', (t.radius + 4) + 'px');
    r.style.setProperty('--r-xl', (t.radius + 10) + 'px');
    r.style.setProperty('--font', `'${t.font}', -apple-system, BlinkMacSystemFont, sans-serif`);
  }, [t.accent, t.radius, t.font]);

  let screen;
  if (DASHBOARDS[route]) {
    // Protected dashboards: auth + role gate.
    if (authState.status === 'loading') screen = <AuthLoading />;
    else if (authState.status === 'out') screen = <Auth key="guard" go={go} params={{ mode: 'login' }} />;
    else if (!role || route !== homeForRole(role)) screen = <AuthLoading />; // role loading or redirecting
    else if (route === 'clipper') screen = <ClipperApp key={JSON.stringify(params)} go={go} params={params} user={authState} />;
    else if (route === 'brand') screen = <BrandApp key={JSON.stringify(params)} go={go} params={params} user={authState} />;
    else if (route === 'admin') screen = <AdminApp key={JSON.stringify(params)} go={go} params={params} user={authState} />;
  }
  else if (route === 'landing') screen = <Landing go={go} aud={aud} setAud={setAudience} lang={lang} setLang={setLang} user={authState} />;
  else if (route === 'marketplace') screen = <Marketplace go={go} user={authState} />;
  else if (route === 'campaign') screen = <CampaignDetail go={go} params={params} user={authState} />;
  else if (route === 'academy') screen = <Academy go={go} />;
  else if (route === 'article') screen = <ArticleDetail go={go} params={params} />;
  else if (route === 'legal') screen = <LegalPage go={go} params={params} />;
  else if (route === 'pricing') screen = <PricingPage go={go} />;
  else if (route === 'for-clippers') screen = <ClippersPage go={go} />;
  else if (route === 'for-brands') screen = <BrandsPage go={go} />;
  else if (route === 'about') screen = <AboutPage go={go} />;
  else if (route === 'blog') screen = <BlogPage go={go} />;
  else if (route === 'contact') screen = <ContactPage go={go} />;
  else if (route === 'help') screen = <HelpPage go={go} />;
  else if (route === 'notfound') screen = <NotFound go={go} lang={lang} setLang={setLang} aud={aud} setAud={setAudience} />;
  else if (route === 'auth') screen = <Auth key={params.mode || 'auth'} go={go} params={params} />;
  else screen = <Landing go={go} aud={aud} setAud={setAudience} lang={lang} setLang={setLang} user={authState} />;

  return (
    <div style={{ height: '100vh', overflow: 'hidden' }}>
      <div key={route} style={{ height: '100%' }}>{screen}</div>

      <TweaksPanel>
        <TweakSection label="Zīmols" />
        <TweakColor label="Akcenta krāsa" value={t.accent}
          options={['#2563EB', '#3B82F6', '#4F46E5', '#0EA5E9', '#7C3AED']}
          onChange={(v) => setTweak('accent', v)} />
        <TweakSection label="Forma" />
        <TweakSlider label="Stūru noapaļojums" value={t.radius} min={4} max={18} step={1} unit="px"
          onChange={(v) => setTweak('radius', v)} />
        <TweakSection label="Tipogrāfija" />
        <TweakRadio label="Fonts" value={t.font}
          options={['Geist', 'Inter', 'System']}
          onChange={(v) => setTweak('font', v)} />
      </TweaksPanel>
    </div>
  );
}

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