/* Company Stock Price — main app: routing, theme, tweaks. */
const LEGAL_ROUTES = window.CSP_ROUTER.LEGAL;

const FONT_MAP = {
  'Plus Jakarta Sans': "'Plus Jakarta Sans', system-ui, sans-serif",
  'Manrope': "'Manrope', system-ui, sans-serif",
  'Space Grotesk': "'Space Grotesk', system-ui, sans-serif",
  'Syne': "'Syne', system-ui, sans-serif",
};
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2563eb",
  "font": "Plus Jakarta Sans",
  "radius": 12,
  "density": "regular"
}/*EDITMODE-END*/;

function applyRouteState(parsed, setters) {
  const { setRoute, setScreenerMode, setStock, setStockLoading, setStockError, setArticleId } = setters;
  const route = parsed.route === 'screener' ? 'screener' : parsed.route;
  setRoute(route);
  setScreenerMode(parsed.screenerMode || 'browse');
  if (parsed.route === 'newsarticle') setArticleId(parsed.articleId || null);
  else if (setArticleId) setArticleId(null);
  if (parsed.route !== 'stockdetail') {
    setStock(null);
    setStockLoading(false);
    setStockError(null);
  }
}

function App() {
  const t0 = useTweaks(TWEAK_DEFAULTS);
  const t = t0[0], setTweak = t0[1];
  const L = useLive();
  const MD = useMarketData();
  const initial = window.CSP_ROUTER.migrateHashToPath();
  const [route, setRoute] = useState(initial.route === 'screener' ? 'screener' : initial.route);
  const [screenerMode, setScreenerMode] = useState(initial.screenerMode || 'browse');
  const [stock, setStock] = useState(null);
  const [stockSymbol, setStockSymbol] = useState(initial.route === 'stockdetail' ? initial.symbol : null);
  const [stockLoading, setStockLoading] = useState(initial.route === 'stockdetail');
  const [stockError, setStockError] = useState(null);
  const [articleId, setArticleId] = useState(initial.route === 'newsarticle' ? initial.articleId : null);
  const [indicesRegion, setIndicesRegion] = useState('IN');
  const [indicesSel, setIndicesSel] = useState(null);
  const [marketsRegion, setMarketsRegion] = useState('IN');
  const [drawer, setDrawer] = useState(false);
  const [search, setSearch] = useState(false);
  const [theme, setTheme] = useState(() => localStorage.getItem('fp-theme') || 'dark');

  const routeSetters = {
    setRoute,
    setScreenerMode,
    setStock,
    setStockLoading,
    setStockError,
    setArticleId,
  };

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('fp-theme', theme);
  }, [theme]);

  useEffect(() => {
    document.documentElement.style.setProperty('--chart-grid', theme === 'dark' ? '#1e293b' : '#f1f5f9');
  }, [theme]);

  useEffect(() => {
    const h = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setSearch(true); }
      if (e.key === 'Escape') { setSearch(false); setDrawer(false); }
    };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);

  useEffect(() => {
    const onPop = () => {
      const parsed = window.CSP_ROUTER.parseLocation(window.location);
      applyRouteState(parsed, routeSetters);
      if (parsed.route === 'stockdetail') setStockSymbol(parsed.symbol);
      else setStockSymbol(null);
      if (parsed.route === 'newsarticle') setArticleId(parsed.articleId || null);
      else setArticleId(null);
      window.scrollTo(0, 0);
    };
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  useEffect(() => {
    const p = window.location.pathname;
    if (p === '/' || p === '/index.html') {
      window.CSP_ROUTER.navigate('markets', {}, true);
    }
  }, []);

  useEffect(() => {
    if (route !== 'stockdetail' || !stockSymbol) return;
    if (MD.loading && !MD.ready) return;
    let cancelled = false;

    async function loadStockFromUrl() {
      setStockLoading(true);
      setStockError(null);
      const sym = stockSymbol;
      const ticker = sym.replace(/\.NS$/i, '');
      const apiSym = /\.NS$|^\^|INR=X/i.test(sym) ? sym : sym + '.NS';
      const local = MD.stocks.find((s) =>
        s.ticker === ticker || s.ticker === sym || s.symbol === sym || s.symbol === apiSym
      );
      if (local) {
        if (!cancelled) { setStock(local); setStockLoading(false); }
        return;
      }
      try {
        const s = await L.market.getStock(apiSym);
        if (!cancelled) { setStock(s); setStockLoading(false); }
      } catch (e) {
        if (!cancelled) {
          setStock(null);
          setStockLoading(false);
          setStockError(apiErrorMessage(e));
        }
      }
    }

    loadStockFromUrl();
    return () => { cancelled = true; };
  }, [route, stockSymbol, MD.ready, MD.loading]);

  function openArticle(item) {
    if (!item || item.id == null) return;
    if (window.NewsCache) window.NewsCache.put(item);
    setArticleId(String(item.id));
    setRoute('newsarticle');
    window.CSP_ROUTER.navigate('newsarticle', { articleId: item.id });
    window.scrollTo(0, 0);
  }

  function openStock(s) {
    const sym = s.ticker || s.symbol || '';
    setStock(s);
    setStockSymbol(sym);
    setStockLoading(false);
    setStockError(null);
    setRoute('stockdetail');
    window.CSP_ROUTER.navigate('stockdetail', { symbol: sym });
    window.scrollTo(0, 0);
  }

  function nav(key, replace) {
    if (key === 'more') { setDrawer(true); return; }
    setDrawer(false);

    const routeKey = key === 'screener' ? 'screener' : key;
    const modeNext = routeKey === 'screener' ? 'build' : (routeKey === 'stocks' ? 'browse' : screenerMode);

    setRoute(routeKey);
    if (routeKey === 'screener' || routeKey === 'stocks') setScreenerMode(modeNext);
    setStock(null);
    setStockSymbol(null);
    setStockLoading(false);
    setStockError(null);
    setArticleId(null);
    if (routeKey !== 'indices') {
      setIndicesSel(null);
    }

    window.CSP_ROUTER.navigate(routeKey, {}, replace);
    window.scrollTo(0, 0);
  }

  function openIndices(region, label) {
    setIndicesRegion(region || 'IN');
    setIndicesSel(label || null);
    setRoute('indices');
    window.CSP_ROUTER.navigate('indices');
    window.scrollTo(0, 0);
  }

  const appStyle = {
    '--accent': t.accent,
    '--accent-soft': `color-mix(in srgb, ${t.accent} 12%, var(--bg-primary))`,
    '--accent-text': t.accent,
    '--tw-radius': t.radius + 'px',
    '--font-body': FONT_MAP[t.font] || FONT_MAP['Plus Jakarta Sans'],
  };
  const sidebarActive = route === 'stockdetail' ? 'stocks' : (route === 'newsarticle' ? 'news' : route);
  const bottomActive = route === 'stockdetail' ? 'stocks' : (route === 'newsarticle' ? 'news' : ((route === 'screener') ? 'stocks' : route));
  const tickerStocks = MD.stocks.length ? MD.stocks : [];

  if (route === 'admin') {
    return (
      <div className="app" data-density={t.density} style={appStyle}>
        <AdminScreen />
      </div>
    );
  }

  let screen;
  if (route === 'markets') screen = (
    <MarketsScreen
      onOpenStock={openStock}
      onOpenArticle={openArticle}
      onOpenIndices={openIndices}
      initialRegion={marketsRegion}
      onRegionChange={setMarketsRegion}
    />
  );
  else if (route === 'screener' || route === 'stocks') screen = (
    <ScreenerScreen
      onOpenStock={openStock}
      mode={screenerMode}
      onModeChange={(m) => nav(m === 'build' ? 'screener' : 'stocks')}
    />
  );
  else if (route === 'news') screen = <NewsScreen onOpenArticle={openArticle} />;
  else if (route === 'newsarticle') screen = (
    <NewsArticleScreen
      articleId={articleId}
      onBack={() => nav('news')}
      onOpenArticle={openArticle}
    />
  );
  else if (route === 'indices') screen = (
    <IndicesScreen onOpenStock={openStock} initialRegion={indicesRegion} initialSel={indicesSel} />
  );
  else if (route === 'funds') screen = <FundsScreen />;
  else if (route === 'ipo') screen = <IpoScreen />;
  else if (route === 'calc') screen = <CalcScreen />;
  else if (LEGAL_ROUTES.includes(route)) screen = (
    <LegalScreen
      page={route}
      onBack={(page) => {
        if (page && LEGAL_ROUTES.includes(page)) nav(page);
        else nav('markets');
      }}
    />
  );
  else if (route === 'stockdetail') {
    if (stockLoading) screen = <SkeletonStock />;
    else if (stockError) screen = (
      <EmptyState icon="stocks" title="Stock not found" sub={stockError}
        action={<button className="pill" onClick={() => nav('stocks')}>Back to stocks</button>} />
    );
    else if (stock) screen = (
      <StockScreen stock={stock} onOpenStock={openStock} onBack={() => nav('stocks')} onOpenArticle={openArticle} />
    );
    else screen = <SkeletonStock />;
  }
  else {
    screen = (<div><h1 className="h1" style={{ marginBottom: 4 }}>Coming soon</h1><EmptyState icon="markets" title="Under construction" sub="This section is being built." /></div>);
  }

  return (
    <div className="app" data-density={t.density} style={appStyle}>
      {MD.loading && !MD.ready
        ? <SkeletonTicker />
        : tickerStocks.length > 0 && <TickerBar stocks={tickerStocks} onOpenStock={openStock} />}
      <div className="shell">
        <Sidebar current={sidebarActive} onNav={nav} drawerOpen={drawer} onCloseDrawer={() => setDrawer(false)} onHome={() => nav('markets')} />
        <div className={`drawer-scrim ${drawer ? 'show' : ''}`} onClick={() => setDrawer(false)}></div>
        <Topbar theme={theme} onToggleTheme={() => setTheme((x) => (x === 'dark' ? 'light' : 'dark'))}
          onHamburger={() => setDrawer(true)} onOpenSearch={() => setSearch(true)}
          onHome={() => nav('markets')} />
        <main className="main">
          <div className="main-inner">{screen}</div>
          <Footer onNav={nav} />
        </main>
        <BottomNav current={bottomActive} onNav={nav} />
      </div>
      <SearchOverlay open={search} onClose={() => setSearch(false)} onOpenStock={openStock} />

      <TweaksPanel>
        <TweakSection label="Typography" />
        <TweakSelect label="UI font" value={t.font} options={['Plus Jakarta Sans', 'Manrope', 'Space Grotesk', 'Syne']}
          onChange={(v) => setTweak('font', v)} />
        <TweakSection label="Brand" />
        <TweakColor label="Accent" value={t.accent}
          options={['#2563eb', '#0d9488', '#7c3aed', '#dc2626', '#ea580c', '#0f172a']}
          onChange={(v) => setTweak('accent', v)} />
        <TweakSection label="Surface" />
        <TweakSlider label="Corner radius" value={t.radius} min={4} max={20} step={2} unit="px"
          onChange={(v) => setTweak('radius', v)} />
        <TweakRadio label="Density" value={t.density} options={['compact', 'regular', 'comfy']}
          onChange={(v) => setTweak('density', v)} />
      </TweaksPanel>
    </div>
  );
}

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