// App shell — orchestrates views, owns Tweaks state

const { useTweaks } = window;
const { TweaksPanel, TweakSection, TweakRadio, TweakToggle, TweakSelect } = window;

const App = () => {
  const [view, setView] = React.useState('analyze'); // analyze | chat | watchlist | history
  const [stage, setStage] = React.useState('landing'); // landing | analyzing | report
  const [coin, setCoin] = React.useState(window.SAMPLE_COIN);
  const [aiReport, setAiReport] = React.useState(null);
  const [aiError, setAiError] = React.useState(null);
  const [watchlist, setWatchlist] = React.useState(() => new Set());
  const [history, setHistory] = React.useState([]); // [{...coin, viewedAt}]
  const [toast, setToast] = React.useState(null);
  const analysisRunRef = React.useRef(0);

  const [tweaks, setTweak] = useTweaks(window.ORACLE_TWEAK_DEFAULTS);

  const flashToast = React.useCallback((msg) => {
    setToast(msg);
    window.clearTimeout(flashToast._t);
    flashToast._t = window.setTimeout(() => setToast(null), 1800);
  }, []);

  const toggleWatch = React.useCallback((c) => {
    setWatchlist(prev => {
      const next = new Set(prev);
      if (next.has(c.ticker)) { next.delete(c.ticker); flashToast(`Removed $${c.ticker} from watchlist`); }
      else { next.add(c.ticker); flashToast(`Added $${c.ticker} to watchlist`); }
      return next;
    });
  }, [flashToast]);

  const pushHistory = React.useCallback((c) => {
    setHistory(prev => {
      const without = prev.filter(h => h.ticker !== c.ticker);
      return [{ ...c, viewedAt: Date.now() }, ...without].slice(0, 24);
    });
  }, []);

  // Apply accent
  React.useEffect(() => {
    const preset = window.ACCENT_PRESETS[tweaks.accent] || window.ACCENT_PRESETS.violet;
    const root = document.documentElement;
    root.style.setProperty('--purple', preset.purple);
    root.style.setProperty('--purple-2', preset.purple2);
    root.style.setProperty('--purple-3', preset.purple3);
    root.style.setProperty('--purple-glow', preset.glow);
  }, [tweaks.accent]);

  // Apply density
  React.useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty('font-size', tweaks.density === 'compact' ? '13px' : tweaks.density === 'roomy' ? '15px' : '14px');
  }, [tweaks.density]);

  // Show / hide grid
  React.useEffect(() => {
    document.body.style.setProperty('--grid-opacity', tweaks.showGrid ? '0.025' : '0');
    let style = document.getElementById('grid-toggle-style');
    if (!style) {
      style = document.createElement('style');
      style.id = 'grid-toggle-style';
      document.head.appendChild(style);
    }
    style.textContent = tweaks.showGrid ? '' : 'body::after { display: none !important; }';
  }, [tweaks.showGrid]);

  const [aiLoading, setAiLoading] = React.useState(false);

  // Step 1: only fetch market data. No AI call. Goes straight to report.
  const runAnalysis = React.useCallback(async (ca) => {
    const runId = ++analysisRunRef.current;
    setAiReport(null);
    setAiError(null);
    setAiLoading(false);
    setView('analyze');

    try {
      const { coin: c } = await window.fetchDexToken(ca);
      if (runId !== analysisRunRef.current) return;
      setCoin(c);
      setStage('report');
    } catch (e) {
      if (runId !== analysisRunRef.current) return;
      flashToast(e?.message || 'Token not found on Solana');
      setStage('landing');
    }
  }, [flashToast]);

  // Step 2: explicit AI call when the user clicks "Analyze with AI" on the report.
  const runAi = React.useCallback(async (opts = {}) => {
    if (!coin?.ca) return;
    const runId = analysisRunRef.current;
    setAiLoading(true);
    setAiError(null);
    setAiReport(null);
    try {
      const report = await window.callOracleReport({
        ca: coin.ca,
        dexData: coin,
        personality: opts.personality || tweaks.personality,
      });
      if (runId !== analysisRunRef.current) return;
      setAiReport(report);
    } catch (e) {
      if (runId !== analysisRunRef.current) return;
      setAiError(e?.message || 'AI analysis failed');
      flashToast('AI analysis failed — try again');
    } finally {
      if (runId === analysisRunRef.current) setAiLoading(false);
    }
  }, [coin, tweaks.personality, flashToast]);

  const startAnalysis = (ca) => { runAnalysis(ca); };

  const handleSetView = (v) => {
    setView(v);
    if (v === 'analyze') setStage(stage === 'landing' ? 'landing' : stage);
  };

  const handleNew = () => {
    setView('analyze');
    setStage('landing');
    setAiReport(null);
    setAiError(null);
    setAiLoading(false);
  };

  const handleRerun = () => {
    if (coin?.ca) runAnalysis(coin.ca);
  };

  const openCoin = (item) => {
    if (item?.ca) { runAnalysis(item.ca); return; }
    const next = item ? { ...window.SAMPLE_COIN, ...item } : coin;
    setCoin(next);
    pushHistory(next);
    setView('analyze');
    setStage('report');
  };

  React.useEffect(() => {
    if (view === 'analyze' && stage === 'report') pushHistory(coin);
  }, [view, stage, coin, pushHistory]);

  return (
    <div style={{ display: 'flex', height: '100%' }}>
      <Sidebar view={view} setView={handleSetView} onNew={handleNew} onOpenRecent={openCoin} history={history} />

      <main style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, position: 'relative' }} data-screen-label={getScreenLabel(view, stage)}>
        {view === 'analyze' && stage === 'landing' && <Landing onAnalyze={startAnalysis} />}
        {view === 'analyze' && stage === 'report' && (
          <Report
            coin={coin}
            aiReport={aiReport}
            aiError={aiError}
            aiLoading={aiLoading}
            onAnalyzeAi={runAi}
            onChat={() => setView('chat')}
            onNew={handleNew}
            onRerun={handleRerun}
            onToggleWatch={() => toggleWatch(coin)}
            onCopy={(text) => { try { navigator.clipboard?.writeText(text); flashToast('Copied'); } catch(e){} }}
            isWatched={watchlist.has(coin.ticker)}
          />
        )}
        {view === 'chat' && (
          <Chat coin={coin} aiReport={aiReport} onBack={() => { setView('analyze'); setStage('report'); }} personality={tweaks.personality} />
        )}
        {view === 'watchlist' && (
          <Watchlist mode="watchlist" onOpen={openCoin} watchlist={watchlist} onToggleWatch={toggleWatch} history={history} />
        )}
        {view === 'history' && (
          <Watchlist mode="history" onOpen={openCoin} watchlist={watchlist} onToggleWatch={toggleWatch} history={history} />
        )}
      </main>

      {toast && (
        <div style={{
          position: 'fixed', left: '50%', bottom: 32, transform: 'translateX(-50%)',
          background: 'rgba(15,10,24,0.92)', border: '1px solid var(--line-2)',
          color: 'var(--ink)', padding: '10px 16px', borderRadius: 3,
          fontSize: 13, fontWeight: 500, zIndex: 9999,
          boxShadow: '0 12px 40px -8px rgba(0,0,0,0.5)',
          backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)',
          animation: 'fadeUp 0.2s ease',
        }}>{toast}</div>
      )}

      <TweaksPanel title="Tweaks">
        <TweakSection label="AI personality">
          <TweakSelect
            value={tweaks.personality}
            onChange={v => setTweak('personality', v)}
            options={[
              { value: 'analyst', label: 'Sharp analyst (default)' },
              { value: 'degen', label: 'Degen — calls out slop' },
              { value: 'dry', label: 'Dry & academic' },
              { value: 'hype', label: 'Hype trader friend' },
            ]}
          />
        </TweakSection>
        <TweakSection label="Accent">
          <TweakRadio
            value={tweaks.accent}
            onChange={v => setTweak('accent', v)}
            options={[
              { value: 'violet', label: 'Violet' },
              { value: 'magenta', label: 'Magenta' },
              { value: 'ultra', label: 'Ultra' },
            ]}
          />
        </TweakSection>
        <TweakSection label="Density">
          <TweakRadio
            value={tweaks.density}
            onChange={v => setTweak('density', v)}
            options={[
              { value: 'compact', label: 'Compact' },
              { value: 'comfortable', label: 'Comfortable' },
              { value: 'roomy', label: 'Roomy' },
            ]}
          />
        </TweakSection>
        <TweakSection label="Background">
          <TweakToggle value={tweaks.showGrid} onChange={v => setTweak('showGrid', v)} label="Show grid" />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
};

function getScreenLabel(view, stage) {
  if (view === 'analyze' && stage === 'landing') return 'Landing — paste CA';
  if (view === 'analyze' && stage === 'report') return 'Detailed report';
  if (view === 'chat') return 'AI chat';
  if (view === 'watchlist') return 'Watchlist';
  if (view === 'history') return 'History';
  return view;
}

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