/* global React, ReactDOM */
/* Main App: routing, wallet-only auth, tweaks */
const { useState, useEffect, useMemo } = React;

function loadSaved(){
  try { return JSON.parse(localStorage.getItem('nwo-tweaks')||'null') || window.TWEAK_DEFAULTS; }
  catch { return window.TWEAK_DEFAULTS; }
}

function App() {
  const [route, setRoute] = useState(() => (location.hash.replace('#','') || 'landing'));
  const [walletAddr, setWallet] = useState(() => localStorage.getItem('nwo_wallet') || null);
  const [walletAvailable] = useState(typeof window.ethereum !== 'undefined');
  const [authOpen, setAuthOpen] = useState(false);
  const [railOpen, setRailOpen] = useState(false);
  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [tweaks, setTweaks] = useState(loadSaved);

  // Persist wallet address across reloads (the wallet itself is the auth)
  useEffect(() => {
    if (walletAddr) localStorage.setItem('nwo_wallet', walletAddr);
    else localStorage.removeItem('nwo_wallet');
  }, [walletAddr]);

  // Listen for tweak activation (HF Space edit-mode integration)
  useEffect(() => {
    const h = (e) => {
      if (!e.data) return;
      if (e.data.type === '__activate_edit_mode') setTweaksOpen(true);
      if (e.data.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', h);
    window.parent.postMessage({ type:'__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', h);
  }, []);

  useEffect(() => { localStorage.setItem('nwo-tweaks', JSON.stringify(tweaks)); }, [tweaks]);

  // Apply tweaks
  useEffect(() => {
    const r = document.documentElement;
    const hue = tweaks.greenHue || 135;
    r.style.setProperty('--g-primary', `oklch(0.82 0.26 ${hue})`);
    r.style.setProperty('--g-soft',    `oklch(0.82 0.26 ${hue} / 0.5)`);
    r.style.setProperty('--g-dim',     `oklch(0.82 0.26 ${hue} / 0.25)`);
    r.style.setProperty('--g-glow',    `oklch(0.82 0.26 ${hue} / 0.15)`);
    r.style.setProperty('--scan-op', tweaks.scanOpacity);
    r.style.setProperty('--grid-op', tweaks.gridOpacity);
    r.style.setProperty('--font-body', `"${tweaks.fontBody}", system-ui, sans-serif`);
  }, [tweaks]);

  // Hash routing
  useEffect(() => {
    const h = () => setRoute(location.hash.replace('#','') || 'landing');
    window.addEventListener('hashchange', h);
    return () => window.removeEventListener('hashchange', h);
  }, []);

  // External auth trigger (e.g. from a "Connect" button somewhere in pages)
  useEffect(() => {
    const h = () => {
      // If wallet is available, trigger connect directly. Otherwise open
      // the modal so user sees the "MetaMask not detected" guidance.
      if (window.ethereum) connect();
      else setAuthOpen(true);
    };
    window.addEventListener('nwo-auth', h);
    return () => window.removeEventListener('nwo-auth', h);
  }, []);

  // Listen for wallet account changes / disconnects in MetaMask itself
  useEffect(() => {
    if (!window.ethereum || !window.ethereum.on) return;
    const onAccountsChanged = (accs) => {
      // Clear signed session whenever account changes/disconnects
      if (typeof window.nwoClearSession === 'function') window.nwoClearSession();
      if (!accs || !accs.length) setWallet(null);
      else setWallet(accs[0]);
    };
    window.ethereum.on('accountsChanged', onAccountsChanged);
    return () => {
      if (window.ethereum.removeListener) {
        window.ethereum.removeListener('accountsChanged', onAccountsChanged);
      }
    };
  }, []);

  const connect = async () => {
    if (!window.ethereum) {
      // Show the modal so the user knows what's missing
      setAuthOpen(true);
      return;
    }
    try {
      const accs = await window.ethereum.request({ method: 'eth_requestAccounts' });
      if (accs && accs[0]) {
        setWallet(accs[0]);
        setAuthOpen(false);
      }
    } catch (e) {
      console.warn('wallet connect rejected:', e?.message || e);
    }
  };

  const disconnect = () => {
    setWallet(null);
    // Clear signed session so a future reconnect re-prompts for signature
    if (typeof window.nwoClearSession === 'function') {
      window.nwoClearSession();
    }
    // Note: this only forgets the wallet locally. MetaMask itself still has
    // the account paired with the site. Full disconnect requires the user
    // to revoke in MetaMask's connected-sites UI.
  };

  const navigate = (item) => {
    if (!item) return;
    // Private items require a connected wallet. If not connected, trigger
    // wallet connect directly (no email/password modal anymore).
    if (item.private && !walletAddr) {
      if (window.ethereum) connect();
      else setAuthOpen(true);
      return;
    }
    location.hash = item.id;
  };

  const renderPage = () => {
    const {
      LandingPage, DashboardPage, TrackingPage, ApiKeysPage, ChatPage,
      RouterPage, EthicsPage, IoTPage, EndpointsPage, ApiDocsPage,
      HFDemoPage, OwnRobotPage, BotMarketPage, AgentGraphPage,
      AutobotPage, CardiacPage, ApocalypsePage, ZeroPointPage, InfoPage
    } = window;
    switch(route) {
      case 'landing': return <LandingPage onLogin={connect} onWallet={connect} walletAvailable={walletAvailable} walletAddr={walletAddr}/>;
      case 'dashboard': return <DashboardPage walletAddr={walletAddr}/>;
      case 'tracking': return <TrackingPage walletAddr={walletAddr}/>;
      case 'api-keys': return <ApiKeysPage walletAddr={walletAddr}/>;
      case 'chat': return <ChatPage walletAddr={walletAddr}/>;
      case 'router': return <RouterPage walletAddr={walletAddr}/>;
      case 'ethics': return <EthicsPage/>;
      case 'iot': return <IoTPage walletAddr={walletAddr}/>;
      case 'endpoints': return <EndpointsPage/>;
      case 'api-docs': return <ApiDocsPage/>;
      case 'hf-demo': return <HFDemoPage/>;
      case 'own-robot': return <OwnRobotPage/>;
      case 'bot-market': return <BotMarketPage/>;
      case 'agent-graph': return <AgentGraphPage/>;
      case 'apocalypse': return <ApocalypsePage/>;
      case 'zeropoint': return <ZeroPointPage/>;
      case 'autobot': return <AutobotPage/>;
      case 'cardiac': return <CardiacPage/>;
      default: return <InfoPage slug={route} walletAddr={walletAddr}/>;
    }
  };

  return (
    <div className="app">
      <window.Header
        walletAddr={walletAddr}
        onConnect={connect}
        onDisconnect={disconnect}
        onMenu={()=>setRailOpen(o=>!o)}
      />
      <div className="body">
        <window.Rail active={route} onNav={navigate} open={railOpen} setOpen={setRailOpen}/>
        <main className="main" onClick={()=>setRailOpen(false)}>
          <div className="main-inner" key={route}>
            {renderPage()}
          </div>
          <window.Footer/>
        </main>
      </div>
      {authOpen && <window.AuthModal
        onClose={()=>setAuthOpen(false)}
        onConnect={connect}
        walletAvailable={walletAvailable}
      />}
      {tweaksOpen && <window.TweaksPanel tweaks={tweaks} setTweaks={setTweaks} onClose={()=>{
        setTweaksOpen(false);
        window.parent.postMessage({type:'__deactivate_edit_mode'},'*');
      }}/>}
    </div>
  );
}

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