// Main app — Saladin Numerology multi-screen prototype
// Screens: landing → form → result. Switch via Tweaks panel or in-page buttons.

const { useState, useEffect, useRef, useCallback } = React;
const APP_BASE_PATH = '/than-so-hoc';
const APP_BASE_PATH_NO_SLASH = APP_BASE_PATH.replace(/\/+$/, '') || '/than-so-hoc';

function stripBasePath(pathname) {
  const raw = String(pathname || '/');
  const clean = raw.replace(/\/+$/, '') || '/';
  if (clean === APP_BASE_PATH_NO_SLASH) return '/';
  if (clean.startsWith(`${APP_BASE_PATH_NO_SLASH}/`)) return clean.slice(APP_BASE_PATH_NO_SLASH.length) || '/';
  return clean;
}

function withBasePath(pathname) {
  const local = String(pathname || '/');
  if (local === '/') return `${APP_BASE_PATH_NO_SLASH}/`;
  return `${APP_BASE_PATH_NO_SLASH}${local.startsWith('/') ? local : `/${local}`}`;
}

function readProfileFromUrl() {
  if (typeof window === 'undefined') return {};
  const p = new URLSearchParams(window.location.search || '');
  const name = (p.get('name') || '').trim();
  const dob = (p.get('dob') || '').trim();
  const gender = (p.get('gender') || '').trim();
  const email = (p.get('email') || '').trim();
  const out = {};
  if (name) out.name = name;
  if (dob) out.dob = dob;
  if (gender) out.gender = gender;
  if (email) out.email = email;
  return out;
}

function resolveProfileWithUrl(baseProfile, urlProfile) {
  const base = { ...(baseProfile || {}) };
  const url = { ...(urlProfile || {}) };
  const hasUrlData = !!(url.name || url.dob || url.gender || url.email);
  if (!hasUrlData) return base;
  const resolved = { ...base, ...url };
  const changedByUrl =
    (url.name && url.name !== base.name) ||
    (url.dob && url.dob !== base.dob) ||
    (url.gender && url.gender !== base.gender) ||
    (url.email && url.email !== base.email);
  if (changedByUrl && resolved.numbers) delete resolved.numbers;
  return resolved;
}

function profileToSearch(profile) {
  const p = new URLSearchParams();
  if (profile && profile.name) p.set('name', profile.name);
  if (profile && profile.dob) p.set('dob', profile.dob);
  if (profile && profile.gender) p.set('gender', profile.gender);
  if (profile && profile.email) p.set('email', profile.email);
  const s = p.toString();
  return s ? `?${s}` : '';
}

function screenFromPath(pathname) {
  const path = stripBasePath(pathname);
  if (path === '/' || path === '/home') return 'landing';
  if (path === '/form') return 'form';
  if (path === '/result') return 'result';
  if (path === '/detail') return 'detail';
  if (path === '/about-xtra') return 'aboutXtra';
  return 'landing';
}

function pathFromScreen(screen) {
  if (screen === 'form') return '/form';
  if (screen === 'result') return '/result';
  if (screen === 'detail') return '/detail';
  if (screen === 'aboutXtra') return '/about-xtra';
  return '/';
}

function sendLeadToExcel(payload) {
  if (typeof window === 'undefined') return;
  try {
    fetch('/api/lead', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload || {}),
      keepalive: true,
    }).catch(() => {});
  } catch (e) {
    // Non-blocking logging only; never break form submit flow.
    console.warn('[lead-webhook] submit failed');
  }
}

function updateSeoForLocation() {
  if (typeof window === 'undefined' || typeof document === 'undefined') return;
  const path = stripBasePath(window.location.pathname || '/');
  const qs = new URLSearchParams(window.location.search || '');
  const hasPersonalQuery = !!(qs.get('name') || qs.get('dob') || qs.get('gender') || qs.get('email'));
  const shouldNoIndex = path === '/result' || path === '/detail' || hasPersonalQuery;

  let robots = document.querySelector('meta[name="robots"]');
  if (!robots) {
    robots = document.createElement('meta');
    robots.setAttribute('name', 'robots');
    document.head.appendChild(robots);
  }
  robots.setAttribute(
    'content',
    shouldNoIndex
      ? 'noindex,nofollow,noarchive'
      : 'index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1'
  );

  let canonical = document.querySelector('link[rel="canonical"]');
  if (!canonical) {
    canonical = document.createElement('link');
    canonical.setAttribute('rel', 'canonical');
    document.head.appendChild(canonical);
  }
  const origin = window.location.origin || 'https://xtra.saladin.vn';
  canonical.setAttribute('href', `${origin}${withBasePath('/')}`);
}

function getLifePathFromProfile(profile) {
  const p = profile || {};
  if (p.numbers && Number.isFinite(Number(p.numbers.lifePath))) return Number(p.numbers.lifePath);
  if (p.dob && typeof window !== 'undefined' && window.SaladinNumerology && window.SaladinNumerology.calculateAll) {
    try {
      const nums = window.SaladinNumerology.calculateAll({ name: p.name || '', dob: p.dob });
      if (nums && Number.isFinite(Number(nums.lifePath))) return Number(nums.lifePath);
    } catch (e) {}
  }
  return null;
}

function trackPageView(screenName) {
  if (typeof window === 'undefined' || typeof window.gtag !== 'function') return;
  const pagePath = `${window.location.pathname || '/'}${window.location.search || ''}`;
  window.gtag('event', 'page_view', {
    page_path: pagePath,
    page_location: window.location.href || '',
    page_title: document.title || '',
    screen_name: String(screenName || ''),
  });
}

// Default tweak values — host parses this JSON and rewrites on edits
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "viewport": "desktop",
  "dark": false,
  "screen": "landing"
}/*EDITMODE-END*/;
// ─────────────────────────────────────────────────────────────
// Reveal-on-scroll using IntersectionObserver
// ─────────────────────────────────────────────────────────────
function useReveal(deps = []) {
  useEffect(() => {
    const root = document.querySelector('.page-root');
    if (!root) return;
    const sections = root.querySelectorAll('[data-reveal]');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('is-visible');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' });
    sections.forEach(s => io.observe(s));
    return () => io.disconnect();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);
}

// ─────────────────────────────────────────────────────────────
// Landing — wraps the marketing page sections
// ─────────────────────────────────────────────────────────────
function LandingPage({ mobile, onNavigate, initialData, onDraftChange }) {
  useReveal([mobile]);
  return (
    <div className="page-root" data-screen-label="01 Landing" data-mobile={mobile ? '1' : '0'} style={{
      width: '100%', minHeight: '100%',
      background: 'var(--bg)', color: 'var(--text-default)',
      fontFamily: 'var(--font-sans)', overflowX: 'hidden',
    }}>
      <NumHeader mobile={mobile} />
      <NumHero
        mobile={mobile}
        initialData={initialData}
        onDraftChange={onDraftChange}
        onCta={(payload) => onNavigate('form', payload)}
      />
      <NumWhat mobile={mobile} />
      <NumHow mobile={mobile} />
      <NumTestimonials mobile={mobile} />
      <NumCrossSell mobile={mobile} />
      <NumFooter mobile={mobile} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Form wrapper page (with header + footer)
// ─────────────────────────────────────────────────────────────
function FormPage({ mobile, onSubmit, onBack, initialData, onDraftChange }) {
  return (
    <div className="page-root" data-screen-label="02 Form" data-mobile={mobile ? '1' : '0'} style={{
      width: '100%', minHeight: '100%',
      background: 'var(--bg)', color: 'var(--text-default)',
      fontFamily: 'var(--font-sans)', overflowX: 'hidden',
    }}>
      <NumHeader mobile={mobile} />
      <FormScreen mobile={mobile} onSubmit={onSubmit} onBack={onBack} initialData={initialData} onDraftChange={onDraftChange} />
      <NumFooter mobile={mobile} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Result wrapper page
// ─────────────────────────────────────────────────────────────
function ResultPage({ mobile, user, onBack, onShare, onOpenDetail }) {
  return (
    <div className="page-root" data-screen-label="03 Result" data-mobile={mobile ? '1' : '0'} style={{
      width: '100%', minHeight: '100%',
      background: 'var(--bg)', color: 'var(--text-default)',
      fontFamily: 'var(--font-sans)', overflowX: 'hidden',
    }}>
      <NumHeader mobile={mobile} />
      <ResultScreen mobile={mobile} user={user} onBack={onBack} onShare={onShare} onOpenDetail={onOpenDetail} />
      <NumFooter mobile={mobile} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Detail wrapper page
// ─────────────────────────────────────────────────────────────
function DetailPage({ mobile, n, user, onBack, onShare }) {
  return (
    <div className="page-root" data-screen-label="04 Detail" data-mobile={mobile ? '1' : '0'} style={{
      width: '100%', minHeight: '100%',
      background: 'var(--bg)', color: 'var(--text-default)',
      fontFamily: 'var(--font-sans)', overflowX: 'hidden',
    }}>
      <NumHeader mobile={mobile} />
      <DetailScreen mobile={mobile} n={n} user={user} onBack={onBack} onShare={onShare} />
      <NumFooter mobile={mobile} />
    </div>
  );
}

function AboutXtraPage({ mobile }) {
  return (
    <div className="page-root" data-screen-label="05 About Xtra" data-mobile={mobile ? '1' : '0'} style={{
      width: '100%', minHeight: '100%',
      background: 'var(--bg)', color: 'var(--text-default)',
      fontFamily: 'var(--font-sans)', overflowX: 'hidden',
    }}>
      <NumHeader mobile={mobile} />
      <NumAboutXtra mobile={mobile} />
      <NumFooter mobile={mobile} />
    </div>
  );
}


// ─────────────────────────────────────────────────────────────
// Desktop frame — browser-like chrome around 1440 viewport
// ─────────────────────────────────────────────────────────────
function DesktopFrame({ children }) {
  // Production layout — no fake browser chrome, render full bleed.
  return (
    <div style={{
      background: 'var(--bg)',
      minHeight: '100vh',
      boxSizing: 'border-box',
    }}>
      {children}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// App shell with tweaks + router state
// ─────────────────────────────────────────────────────────────
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const initialUrlProfile = readProfileFromUrl();
  const [user, setUser] = useState(() => {
    return (initialUrlProfile.name && initialUrlProfile.dob && initialUrlProfile.gender) ? initialUrlProfile : null;
  });
  const [detailN, setDetailN] = useState(7);
  const [shareOpen, setShareOpen] = useState(false);
  const [formDraft, setFormDraft] = useState(() => ({ ...initialUrlProfile }));

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', t.dark ? 'dark' : 'light');
  }, [t.dark]);
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const parsePath = () => {
      updateSeoForLocation();
      const next = screenFromPath(window.location.pathname);
      trackPageView(next);
      const profileFromUrl = readProfileFromUrl();
      setTweak('screen', next);
      setFormDraft({ ...profileFromUrl });
      if (profileFromUrl.name && profileFromUrl.dob && profileFromUrl.gender) {
        const nextUser = { ...profileFromUrl };
        try {
          if (window.SaladinNumerology && window.SaladinNumerology.calculateAll) {
            nextUser.numbers = window.SaladinNumerology.calculateAll({
              name: profileFromUrl.name,
              dob: profileFromUrl.dob,
            });
          }
        } catch (e) {}
        setUser(nextUser);
        if (next === 'detail') {
          const lp = getLifePathFromProfile(nextUser);
          if (lp != null) setDetailN(lp);
        }
      } else {
        setUser(null);
      }
    };
    parsePath();
    window.addEventListener('popstate', parsePath);
    return () => window.removeEventListener('popstate', parsePath);
  }, []);

  const autoMobile = typeof window !== 'undefined' && window.innerWidth <= 768;
  const mobile = t.viewport === 'mobile' || autoMobile;
  const screen = t.screen || 'landing';

  useEffect(() => {
    if (typeof window === 'undefined') return;
    updateSeoForLocation();
    // URL should reflect current input immediately, so draft must override stale user state.
    const profile = { ...(user || {}), ...(formDraft || {}) };
    const desired = profileToSearch(profile);
    const current = window.location.search || '';
    if (desired !== current) {
      history.replaceState(null, '', `${window.location.pathname}${desired}`);
    }
  }, [formDraft, user]);

  const upsertDraft = useCallback((patch) => {
    setFormDraft((prev) => {
      const next = { ...prev, ...patch };
      const same = JSON.stringify(prev) === JSON.stringify(next);
      return same ? prev : next;
    });
  }, []);

  const navigate = (next, payload) => {
    if (next === 'form' && payload) {
      upsertDraft(payload);
      sendLeadToExcel({
        submitted_at: new Date().toISOString(),
        source: 'saladin-thansohoc-home-cta',
        page_url: typeof window !== 'undefined' ? window.location.href : '',
        name: payload.name || '',
        dob: payload.dob || '',
        gender: payload.gender || '',
        email: payload.email || '',
        life_path: '',
        soul_urge: '',
        personality: '',
        destiny: '',
        personal_year: '',
      });
    }
    if (next === 'result' && payload) {
      setUser(payload);
    } else if (next === 'result' && !payload && typeof window !== 'undefined') {
      const fromUrl = readProfileFromUrl();
      if (fromUrl.name && fromUrl.dob && fromUrl.gender) {
        const resolved = { ...fromUrl };
        if (!resolved.numbers && window.SaladinNumerology && window.SaladinNumerology.calculateAll) {
          resolved.numbers = window.SaladinNumerology.calculateAll({ name: resolved.name, dob: resolved.dob });
        }
        setUser(resolved);
      } else {
        setUser(null);
      }
    }
    if (next === 'detail' && payload && payload.n) setDetailN(payload.n);
    if (next === 'detail' && (!payload || !payload.n) && typeof window !== 'undefined') {
      try {
        const fromUrl = readProfileFromUrl();
        const lp = getLifePathFromProfile(resolveProfileWithUrl(user || {}, fromUrl));
        if (lp != null) setDetailN(lp);
      } catch (e) {}
    }
    setTweak('screen', next);
    if (typeof window !== 'undefined') {
      const targetPath = pathFromScreen(next);
      const targetPathWithBase = withBasePath(targetPath);
      const url = `${targetPathWithBase}${window.location.search || ''}`;
      if (window.location.pathname !== targetPathWithBase) {
        history.pushState(null, '', url);
        trackPageView(next);
      }
    }
    setShareOpen(false);
  };

  useEffect(() => {
    if (!user && (screen === 'result' || screen === 'detail')) {
      setTweak('screen', 'form');
      if (typeof window !== 'undefined') {
        const formPath = withBasePath('/form');
        if (window.location.pathname !== formPath) {
          history.replaceState(null, '', `${formPath}${window.location.search || ''}`);
          trackPageView('form');
        }
      }
    }
  }, [screen, user]);

  const openShare = () => setShareOpen(true);
  const openDetail = (n) => navigate('detail', { n });
  const Content = (typeof window !== 'undefined' && window.SaladinContent) || {};
  const N = (typeof window !== 'undefined' && window.SaladinNumerology) || {};
  const detailNumberOptions = Object.keys((Content && Content.NUMBER_CONTENT) || {})
    .map(Number)
    .filter((v) => Number.isFinite(v))
    .sort((a, b) => a - b)
    .map((n) => ({ value: String(n), label: `Life Path ${n} — ${(N.NUMBER_NAMES && N.NUMBER_NAMES[n]) || 'Chi tiết'}` }));

  const liveUrlProfile = typeof window !== 'undefined' ? readProfileFromUrl() : {};
  const hasLiveUrlIdentity = !!(liveUrlProfile && liveUrlProfile.name && liveUrlProfile.dob && liveUrlProfile.gender);
  const resolvedFromUrl = hasLiveUrlIdentity ? resolveProfileWithUrl(user || {}, liveUrlProfile) : (user || null);
  if (resolvedFromUrl && !resolvedFromUrl.numbers && resolvedFromUrl.name && resolvedFromUrl.dob && N && N.calculateAll) {
    try {
      resolvedFromUrl.numbers = N.calculateAll({ name: resolvedFromUrl.name, dob: resolvedFromUrl.dob });
    } catch (e) {}
  }
  const u = resolvedFromUrl || { name: 'Bạn', dob: '1990-01-01' };

  const body = (() => {
    if (screen === 'form') {
      return <FormPage mobile={mobile}
                       onBack={() => navigate('landing')}
                       initialData={formDraft}
                       onDraftChange={upsertDraft}
                       onSubmit={(data) => {
                         const N = window.SaladinNumerology;
                         const numbers = N && N.calculateAll ? N.calculateAll(data) : {};
                         if (N && N.trackEvent) N.trackEvent('form_submitted', {
                         gender: data.gender || 'skip',
                         has_email: !!data.email,
                       });
                         upsertDraft(data);
                         navigate('result', { ...data, numbers });
                       }} />;
    }
    if (screen === 'result') {
      return <ResultPage mobile={mobile}
                         user={u}
                         onBack={() => navigate('landing')}
                         onShare={openShare}
                         onOpenDetail={openDetail} />;
    }
    if (screen === 'detail') {
      return <DetailPage mobile={mobile} n={detailN}
                         user={u}
                         onBack={() => navigate('result')}
                         onShare={openShare} />;
    }
    if (screen === 'aboutXtra') {
      return <AboutXtraPage mobile={mobile} />;
    }
    return <LandingPage
      mobile={mobile}
      onNavigate={navigate}
      initialData={formDraft}
      onDraftChange={upsertDraft}
    />;
  })();

  return (
    <>
      <div style={{ position: 'relative' }}>
        <DesktopFrame>{body}</DesktopFrame>
        {/* Share modal is rendered relative to the frame container */}
        <ShareModal open={shareOpen} onClose={() => setShareOpen(false)} user={u} n={detailN} />
      </div>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Screen">
          <TweakSelect
            label="Page"
            value={screen}
            onChange={(v) => navigate(v)}
            options={[
              { value: 'landing', label: '01 — Landing' },
              { value: 'form',    label: '02 — Form' },
              { value: 'result',  label: '03 — Result' },
              { value: 'detail',  label: '04 — Detail (1 con số)' },
            ]}
          />
          {screen === 'detail' && (
            <TweakSelect
              label="Số"
              value={String(detailN)}
              onChange={(v) => setDetailN(Number(v))}
              options={detailNumberOptions.length ? detailNumberOptions : [{ value: '7', label: 'Life Path 7 — Chi tiết' }]}
            />
          )}
          <TweakButton label="Mở Share modal" onClick={openShare} />
        </TweakSection>

        <TweakSection label="Viewport">
          <TweakRadio
            label="Form factor"
            value={t.viewport}
            onChange={(v) => setTweak('viewport', v)}
            options={[
              { value: 'desktop', label: 'Desktop' },
              { value: 'mobile', label: 'Mobile' },
            ]}
          />
        </TweakSection>

        <TweakSection label="Theme">
          <TweakToggle
            label="Dark mode"
            value={t.dark}
            onChange={(v) => setTweak('dark', v)}
          />
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

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