// App shell with Framer Motion page transitions

const { useState: u, useEffect: e } = React;
var { AnimatePresence, motion } = window.Motion || {};
if (!motion) {
  motion = new Proxy({}, {
    get: (_, tag) => React.forwardRef((inputProps, ref) => {
      const props = Object.assign({}, inputProps || {});
      const children = props.children;
      delete props.children;
      delete props.initial;
      delete props.animate;
      delete props.exit;
      delete props.transition;
      delete props.whileHover;
      delete props.whileTap;
      delete props.layout;
      delete props.variants;
      delete props.custom;
      return React.createElement(tag, Object.assign({}, props, { ref }), children);
    }),
  });
}
if (!AnimatePresence) {
  AnimatePresence = ({ children }) => React.createElement(React.Fragment, null, children);
}

const TWEAK_DEFAULS = /*EDITMODE-BEGIN*/{
  "accentHue": 268,
  "accentName": "Indigo",
  "fontHeadlineSerifAccent": true,
  "showBadges": true
}/*EDITMODE-END*/;

const routeFromPath = () => {
  const path = window.location.pathname.replace(/^\/+|\/+$/g, '');
  if (path === 'explore' || path === 'recent') return { name: 'recent', params: {} };
  if (path === 'ai-news') return { name: 'aiNews', params: {} };
  const aiPostMatch = path.match(/^ai-news\/(.+)$/);
  if (aiPostMatch) return { name: 'aiPost', params: { slug: decodeURIComponent(aiPostMatch[1]) } };
  const newsPostMatch = path.match(/^news\/(.+)$/);
  if (newsPostMatch) return { name: 'aiPost', params: { slug: decodeURIComponent(newsPostMatch[1]) } };
  if (path === 'signin') return { name: 'signin', params: {} };
  if (path === 'account') return { name: 'account', params: {} };
  if (path === 'pricing') return { name: 'pricing', params: {} };
  if (path === 'admin' || path === 'analytics') return { name: 'analytics', params: {} };
  if (path === 'about') return { name: 'about', params: {} };
  if (path === 'privacy') return { name: 'privacy', params: {} };
  if (path === 'terms') return { name: 'terms', params: {} };
  const reportMatch = path.match(/^report\/(.+)$/);
  if (reportMatch) return { name: 'result', params: { id: decodeURIComponent(reportMatch[1]) } };
  return { name: 'home', params: {} };
};

const routeFromLegacyHash = () => {
  const legacyHash = window.location.hash.replace(/^#\/?/, '');
  if (/^(access_token|refresh_token|error|error_code|type)=/.test(legacyHash)) return null;
  if (!legacyHash) return null;
  const cleanPath = legacyHash === 'home' ? '' : legacyHash;
  return `/${cleanPath}`.replace(/\/+$/, '') || '/';
};

const pathForRoute = (name, params = {}) => {
  if (name === 'recent') return '/explore';
  if (name === 'aiNews') return '/ai-news';
  if (name === 'aiPost' && params.slug) return `/ai-news/${encodeURIComponent(params.slug)}`;
  if (name === 'signin') return '/signin';
  if (name === 'account') return '/account';
  if (name === 'pricing') return '/pricing';
  if (name === 'analytics') return '/admin';
  if (name === 'about' || name === 'privacy' || name === 'terms') return `/${name}`;
  if (name === 'result' && params.id) return `/report/${encodeURIComponent(params.id)}`;
  return '/';
};

const PLAN_LIMITS = {
  guest: { label: 'Guest', checks: 2, period: 'day', maxMinutes: 5, claimLimit: 2, sourceLimit: 0, transcript: false, share: false, historyDays: 0 },
  basic: { label: 'Basic', checks: 15, period: 'month', maxMinutes: 8, claimLimit: Infinity, sourceLimit: 5, transcript: true, share: false, historyDays: 30 },
  pro: { label: 'Pro', checks: 150, period: 'month', maxMinutes: 30, claimLimit: Infinity, sourceLimit: 20, transcript: true, share: true, historyDays: Infinity },
  team: { label: 'Team', checks: 1000, period: 'month', maxMinutes: 90, claimLimit: Infinity, sourceLimit: 20, transcript: true, share: true, historyDays: Infinity },
};

const planForUser = (profile) => {
  if (!profile) return 'guest';
  if (profile.plan === 'team' || profile.plan === 'pro') return profile.plan;
  if (profile.trialEndsAt && new Date(profile.trialEndsAt).getTime() > Date.now()) return 'pro';
  return 'basic';
};

const usageKeyForUser = (profile) => profile?.email ? `vv_usage_${profile.email}` : 'vv_usage_guest';

const readUsage = (profile) => {
  try { return JSON.parse(localStorage.getItem(usageKeyForUser(profile)) || '[]'); } catch { return []; }
};

const usageWindowStart = (period) => {
  const now = new Date();
  if (period === 'day') {
    now.setHours(0, 0, 0, 0);
    return now.getTime();
  }
  return new Date(now.getFullYear(), now.getMonth(), 1).getTime();
};

const currentUsageCount = (profile, plan) => {
  const limit = PLAN_LIMITS[plan] || PLAN_LIMITS.guest;
  const start = usageWindowStart(limit.period);
  return readUsage(profile).filter((stamp) => new Date(stamp).getTime() >= start).length;
};

const recordUsage = (profile) => {
  const next = [new Date().toISOString(), ...readUsage(profile)].slice(0, 200);
  localStorage.setItem(usageKeyForUser(profile), JSON.stringify(next));
};

const historyKeyForUser = (profile) => profile?.email ? `vv_history_${profile.email}` : 'vv_history_guest';

const readStoredHistory = (profile) => {
  try { return JSON.parse(localStorage.getItem(historyKeyForUser(profile)) || '[]'); } catch { return []; }
};

const mergeHistory = (...lists) => {
  const seen = new Set();
  return lists.flat().filter((item) => {
    const key = item?.url || item?.reportId;
    if (!key || seen.has(key)) return false;
    seen.add(key);
    return true;
  }).slice(0, 50);
};

const localProfileKeyForEmail = (email) => `vv_profile_${String(email || '').toLowerCase()}`;

const readLocalProfile = (email) => {
  if (!email) return {};
  try { return JSON.parse(localStorage.getItem(localProfileKeyForEmail(email)) || '{}'); } catch { return {}; }
};

const writeLocalProfile = (profile) => {
  if (!profile?.email) return;
  localStorage.setItem(localProfileKeyForEmail(profile.email), JSON.stringify(profile));
};

const SUPABASE_PUBLIC_AUTH = {
  url: 'https://nweitqhgzlzmvjsualti.supabase.co',
  anonKey: 'sb_publishable_VxhcqCKhcNT6fGEALxg10g_mkWlybBR',
};

const profileFromSupabaseUser = (authUser) => {
  if (!authUser) return null;
  const metadata = authUser.user_metadata || {};
  const email = authUser.email || metadata.email || '';
  const saved = readLocalProfile(email);
  return {
    ...saved,
    id: authUser.id,
    email,
    name: metadata.full_name || metadata.name || saved.name || (email ? email.split('@')[0] : 'VidVerdict user'),
    avatar: metadata.avatar_url || metadata.picture || saved.avatar || 'assets/rizwan-kabir.jpg',
    provider: authUser.app_metadata?.provider || saved.provider || 'Email',
  };
};

const loadSupabaseAuthClient = async () => {
  let config = {};
  try {
    const res = await fetch('/api/auth-config');
    config = res.ok ? await res.json() : {};
  } catch {}
  const supabaseUrl = config.supabaseUrl || SUPABASE_PUBLIC_AUTH.url;
  const supabaseAnonKey = config.supabaseAnonKey || SUPABASE_PUBLIC_AUTH.anonKey;
  if (!supabaseUrl || !supabaseAnonKey) {
    throw new Error('Supabase Auth is not configured yet.');
  }
  if (!window.supabase?.createClient) {
    await new Promise((resolve, reject) => {
      const existing = document.querySelector('script[data-vv-supabase-fallback]');
      if (existing) {
        existing.addEventListener('load', resolve, { once: true });
        existing.addEventListener('error', reject, { once: true });
        return;
      }
      const script = document.createElement('script');
      script.src = 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2.49.8/dist/umd/supabase.min.js';
      script.crossOrigin = 'anonymous';
      script.dataset.vvSupabaseFallback = 'true';
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    }).catch(() => {});
  }
  if (!window.supabase?.createClient) {
    throw new Error('Supabase Auth library did not load.');
  }
  return window.supabase.createClient(supabaseUrl, supabaseAnonKey, {
    auth: {
      persistSession: true,
      autoRefreshToken: true,
      detectSessionInUrl: true,
    },
  });
};

const App = () => {
  const [route, setRoute] = u(routeFromPath());
  const [url, setUrl] = u('');
  const [liveReports, setLiveReports] = u({});
  const [aiNewsPosts, setAiNewsPosts] = u([]);
  const [authClient, setAuthClient] = u(null);
  const [authReady, setAuthReady] = u(false);
  const [authError, setAuthError] = u('');
  const [user, setUser] = u(() => {
    try { return JSON.parse(localStorage.getItem('vv_user') || 'null'); } catch { return null; }
  });
  const [userHistory, setUserHistory] = u(() => {
    try {
      const savedUser = JSON.parse(localStorage.getItem('vv_user') || 'null');
      return readStoredHistory(savedUser);
    } catch {
      return [];
    }
  });
  const effectivePlan = planForUser(user);
  const planLimits = PLAN_LIMITS[effectivePlan] || PLAN_LIMITS.guest;
  const [tweaks, setTweaks] = window.useTweaks ? window.useTweaks(TWEAK_DEFAULS) : [TWEAK_DEFAULS, () => {}];

  const applySignedInProfile = (profile, { navigate = false, toast = false } = {}) => {
    const pendingPlan = localStorage.getItem('vv_pending_plan');
    const trialEndsAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();
    const nextProfile = {
      ...profile,
      plan: pendingPlan === 'pro' || pendingPlan === 'team' ? pendingPlan : (profile.plan || 'basic'),
      trialEndsAt: profile.trialEndsAt || trialEndsAt,
    };
    localStorage.removeItem('vv_pending_plan');
    writeLocalProfile(nextProfile);
    const accountHistory = readStoredHistory(nextProfile);
    setUserHistory(mergeHistory(accountHistory));
    setUser(nextProfile);
    if (toast) showToast('Signed in');
    if (navigate) go('account');
  };

  e(() => {
    const legacyPath = routeFromLegacyHash();
    const isHomeAlias = window.location.pathname.replace(/\/+$/, '') === '/home';
    if (legacyPath || isHomeAlias) {
      window.history.replaceState(null, '', legacyPath || '/');
      setRoute(routeFromPath());
    }
  }, []);

  e(() => {
    let active = true;
    let subscription = null;
    loadSupabaseAuthClient()
      .then(async (client) => {
        if (!active) return;
        setAuthClient(client);
        setAuthReady(true);
        setAuthError('');
        const { data } = await client.auth.getSession();
        const profile = profileFromSupabaseUser(data?.session?.user);
        if (profile) applySignedInProfile(profile);
        const listener = client.auth.onAuthStateChange((event, session) => {
          if (!active) return;
          if (event === 'SIGNED_OUT') {
            setUser(null);
            setUserHistory(readStoredHistory(null));
            return;
          }
          const nextProfile = profileFromSupabaseUser(session?.user);
          if (nextProfile) applySignedInProfile(nextProfile);
        });
        subscription = listener?.data?.subscription;
      })
      .catch((error) => {
        if (!active) return;
        setAuthReady(false);
        setAuthError(error.message || 'Supabase Auth is not configured yet.');
      });
    return () => {
      active = false;
      subscription?.unsubscribe?.();
    };
  }, []);

  e(() => {
    let cancelled = false;
    fetch('/api/recent')
      .then((res) => res.ok ? res.json() : { reports: [] })
      .then(({ reports = [] }) => {
        if (cancelled || !Array.isArray(reports)) return;
        setLiveReports((current) => ({
          ...Object.fromEntries(reports.map((report) => [report.id, report])),
          ...current,
        }));
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);

  e(() => {
    let cancelled = false;
    fetch('/api/ai-news')
      .then((res) => res.ok ? res.json() : { posts: [] })
      .then(({ posts = [] }) => {
        if (!cancelled && Array.isArray(posts)) {
          setAiNewsPosts(posts);
        }
      })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);

  e(() => {
    if (user) localStorage.setItem('vv_user', JSON.stringify(user));
    else localStorage.removeItem('vv_user');
  }, [user]);

  e(() => {
    if (route.name !== 'signin') return undefined;
    const clearStaleAuthWarning = () => {
      document.querySelectorAll('.auth-note.error').forEach((node) => {
        if (node.textContent?.includes('Connect Supabase URL and anon key')) {
          node.remove();
        }
      });
    };
    clearStaleAuthWarning();
    const interval = setInterval(clearStaleAuthWarning, 250);
    const timeout = setTimeout(() => clearInterval(interval), 6000);
    return () => {
      clearInterval(interval);
      clearTimeout(timeout);
    };
  }, [route.name]);

  e(() => {
    localStorage.setItem(historyKeyForUser(user), JSON.stringify(userHistory));
  }, [userHistory, user]);

  e(() => {
    const onRouteChange = () => setRoute(routeFromPath());
    window.addEventListener('hashchange', onRouteChange);
    window.addEventListener('popstate', onRouteChange);
    return () => {
      window.removeEventListener('hashchange', onRouteChange);
      window.removeEventListener('popstate', onRouteChange);
    };
  }, []);

  e(() => {
    fetch('/api/visit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ path: window.location.pathname || '/' }),
    }).catch(() => {});
  }, [route.name, route.params.id, route.params.slug]);

  // Apply accent hue
  e(() => {
    const h = tweaks.accentHue ?? 268;
    document.documentElement.style.setProperty('--accent', `oklch(0.48 0.18 ${h})`);
    document.documentElement.style.setProperty('--accent-soft', `oklch(0.96 0.03 ${h})`);
    document.documentElement.style.setProperty('--accent-line', `oklch(0.88 0.06 ${h})`);
  }, [tweaks.accentHue]);

  const go = (name, params = {}) => {
    setRoute({ name, params });
    const nextPath = pathForRoute(name, params);
    const current = `${window.location.pathname}${window.location.search}`;
    if (current !== nextPath || window.location.hash) {
      window.history.pushState(null, '', nextPath);
    }
    window.scrollTo({ top: 0, behavior: 'instant' });
  };

  const onAnalyze = () => {
    const cleanUrl = (url || '').trim();
    if (!/^https?:\/\//i.test(cleanUrl)) {
      showToast('Please paste a URL that starts with http:// or https://');
      return;
    }
    const used = currentUsageCount(user, effectivePlan);
    if (used >= planLimits.checks) {
      showToast(`${planLimits.label} includes ${planLimits.checks} checks/${planLimits.period}. Upgrade to keep going.`);
      go('pricing');
      return;
    }
    let host = '';
    try {
      host = new URL(cleanUrl).hostname.replace(/^www\./, '').toLowerCase();
    } catch {}
    const isSupportedSocial =
      host.includes('youtube') ||
      host === 'youtu.be' ||
      host.includes('tiktok') ||
      host.includes('instagram') ||
      host.includes('x.com') ||
      host.includes('twitter') ||
      host.includes('facebook') ||
      host.includes('fb.watch');
    const isDemo = !isSupportedSocial;
    go('loading', { demo: isDemo });
  };

  const onAnalysisDone = (report) => {
    recordUsage(user);
    setLiveReports((reports) => ({ ...reports, [report.id]: report }));
    if (user && planLimits.historyDays !== 0) {
      setUserHistory((history) => {
        const next = [{ reportId: report.id, url: report.url, checkedAt: report.checkedAt || new Date().toISOString() }, ...history.filter((item) => item.url !== report.url)];
        return next.slice(0, 50);
      });
    }
    go('result', { id: report.id });
  };

  const onAnalysisError = (message) => {
    showToast(message || 'Analysis failed. Please try another public video URL.');
    go('home');
  };

  const onSignIn = (profile) => {
    applySignedInProfile(profile, { navigate: true, toast: true });
  };

  const onSignOut = async () => {
    if (authClient) {
      await authClient.auth.signOut().catch(() => {});
    }
    setUser(null);
    setUserHistory(readStoredHistory(null));
    showToast('Signed out');
    go('home');
  };

  const onChoosePlan = (plan) => {
    if (plan === 'guest') {
      go('home');
      return;
    }
    if (!user) {
      localStorage.setItem('vv_pending_plan', plan);
      showToast(plan === 'basic' ? 'Create a free account to continue' : `Sign in to start ${PLAN_LIMITS[plan]?.label || 'your plan'}`);
      go('signin');
      return;
    }
    const nextUser = { ...user, plan };
    if (plan === 'basic' && !nextUser.trialEndsAt) {
      nextUser.trialEndsAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();
    }
    setUser(nextUser);
    showToast(`${PLAN_LIMITS[plan]?.label || 'Plan'} selected`);
    go('account');
  };

  const pageVariants = {
    initial: { opacity: 0, y: 16, filter: 'blur(3px)' },
    animate: { opacity: 1, y: 0, filter: 'blur(0px)', transition: { duration: 0.45, ease: [0.16, 1, 0.3, 1] } },
    exit: { opacity: 0, y: -10, filter: 'blur(2px)', transition: { duration: 0.25, ease: [0.4, 0, 1, 1] } },
  };

  return (
    <>
      <Nav route={route.name} go={go} user={user} />

      <AnimatePresence mode="wait">
        <motion.div
          key={route.name}
          variants={pageVariants}
          initial="initial"
          animate="animate"
          exit="exit"
        >
          {route.name === 'home' && <HomePage go={go} url={url} setUrl={setUrl} onAnalyze={onAnalyze} />}
          {route.name === 'loading' && <LoadingPage url={url} demo={route.params.demo} maxVideoMinutes={planLimits.maxMinutes} onDone={onAnalysisDone} onError={onAnalysisError} />}
          {route.name === 'result' && <ResultsPage id={route.params.id} reports={liveReports} go={go} plan={effectivePlan} limits={planLimits} user={user} />}
          {route.name === 'recent' && <RecentPage go={go} reports={liveReports} />}
          {route.name === 'aiNews' && <AiNewsPage go={go} />}
          {route.name === 'aiPost' && <AiPostPage slug={route.params.slug} go={go} generatedPosts={aiNewsPosts} />}
          {route.name === 'signin' && <SignInPage go={go} onSignIn={onSignIn} authClient={authClient} authReady={authReady} authError={authError} />}
          {route.name === 'account' && <AccountPage go={go} user={user} reports={liveReports} history={userHistory} onSignOut={onSignOut} />}
          {route.name === 'pricing' && <PricingPage go={go} currentPlan={effectivePlan} onChoosePlan={onChoosePlan} />}
          {route.name === 'analytics' && <AnalyticsPage go={go} />}
          {route.name === 'about' && <AboutPage />}
          {route.name === 'privacy' && <PrivacyPage />}
          {route.name === 'terms' && <TermsPage />}
        </motion.div>
      </AnimatePresence>

      <Footer go={go} />

      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection title="Accent">
            <window.TweakRadio
              label="Color"
              value={tweaks.accentName || 'Indigo'}
              options={[
                { value: 'Blue', label: 'Blue' },
                { value: 'Indigo', label: 'Indigo' },
                { value: 'Violet', label: 'Violet' },
              ]}
              onChange={(v) => {
                const hueMap = { Blue: 245, Indigo: 268, Violet: 295 };
                setTweaks({ accentName: v, accentHue: hueMap[v] });
              }}
            />
            <window.TweakSlider label="Hue" min={200} max={320} step={1}
              value={tweaks.accentHue ?? 268}
              onChange={(v) => setTweaks('accentHue', v)} />
          </window.TweakSection>
          <window.TweakSection title="Demo">
            <window.TweakButton label="Trigger sample analysis" onClick={() => { setUrl('https://www.tiktok.com/@wellness_daily/video/7234891'); go('loading'); }} />
            <window.TweakButton label="Open false-claim report" onClick={() => go('result', { id: 'crypto-prediction' })} />
            <window.TweakButton label="Open balanced report" onClick={() => go('result', { id: 'wellness-coffee' })} />
          </window.TweakSection>
        </window.TweaksPanel>
      )}

      <style>{`
        ${!tweaks.showBadges ? '.badges { display: none !important; }' : ''}
        ${!tweaks.fontHeadlineSerifAccent ? 'h1.display .accent, h2.section-title .serif, .final-cta .serif-em { font-family: "Inter", sans-serif !important; font-style: normal !important; color: inherit !important; }' : ''}
      `}</style>
    </>
  );
};

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