// app.jsx — root: auth, routing, shared state, toasts, API integration
const { useState, useEffect, useCallback } = React;

const ACCENTS = {
  Blue:    { c6: '#0a66ff', c7: '#0a52d6', c5: '#599bff', c1: '#d9e8ff', c0: '#eef5ff', rgb: '10,102,255' },
  Indigo:  { c6: '#4f46e5', c7: '#4338ca', c5: '#818cf8', c1: '#e0e7ff', c0: '#eef2ff', rgb: '79,70,229' },
  Violet:  { c6: '#7c3aed', c7: '#6d28d9', c5: '#a78bfa', c1: '#ede9fe', c0: '#f5f3ff', rgb: '124,58,237' },
  Emerald: { c6: '#059669', c7: '#047857', c5: '#34d399', c1: '#d1fae5', c0: '#ecfdf5', rgb: '5,150,105' },
  Coral:   { c6: '#f4623a', c7: '#e14e29', c5: '#fb8a5c', c1: '#ffe2d5', c0: '#fff3ee', rgb: '244,98,58' },
};
const RADII = {
  Sharp:   { xs: '4px', sm: '6px', r: '8px',  lg: '10px', xl: '13px' },
  Default: { xs: '7px', sm: '10px', r: '13px', lg: '17px', xl: '22px' },
  Round:   { xs: '10px', sm: '14px', r: '18px', lg: '24px', xl: '30px' },
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "Light",
  "accent": "Blue",
  "radius": "Default",
  "density": "Comfortable",
  "railStyle": "Tinted"
}/*EDITMODE-END*/;

function Toasts({ items }) {
  const Icon = window.Icon;
  return (
    <div className="toast-wrap">
      {items.map(t => (
        <div className="toast" key={t.id}>
          <span className="tic"><Icon name="check" size={15} /></span>{t.msg}
        </div>
      ))}
    </div>
  );
}

function App() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  // ── Auth ─────────────────────────────────────────────────────
  const [authUser, setAuthUser] = useState(null);   // null=loading, false=logged out, obj=authed
  const [authReady, setAuthReady] = useState(false);

  useEffect(() => {
    const token = localStorage.getItem('ims_token');
    if (!token) { setAuthUser(false); setAuthReady(true); return; }
    window.API.me()
      .then(u => { setAuthUser(u); setBalance(u.balance); setAuthReady(true); })
      .catch(() => { localStorage.removeItem('ims_token'); setAuthUser(false); setAuthReady(true); });
  }, []);

  const handleLogin = useCallback((user) => {
    setAuthUser(user);
    setBalance(user.balance || 1000);
    window.API.getNotifs().then(ns => setNotifs(ns)).catch(() => {});
  }, []);

  const handleLogout = useCallback(() => {
    localStorage.removeItem('ims_token');
    setAuthUser(false);
    setRoute('home');
  }, []);

  // ── Routing ──────────────────────────────────────────────────
  const [route, setRoute] = useState('home');
  const [collapsed, setCollapsed] = useState(false);
  const [search, setSearch] = useState('');
  const [activeIdea, setActiveIdea] = useState(null);
  const [activeUser, setActiveUser] = useState(null);
  const [prevRoute, setPrevRoute] = useState('home');
  const [addOpen, setAddOpen] = useState(false);
  const [notifOpen, setNotifOpen] = useState(false);
  const [balance, setBalance] = useState(1000);
  const [lang, setLang] = useState('en');
  const toggleLang = () => {
    setLang(l => {
      const next = l === 'en' ? 'ar' : 'en';
      const html = document.documentElement;
      html.setAttribute('dir', next === 'ar' ? 'rtl' : 'ltr');
      html.setAttribute('lang', next);
      if (next === 'ar') {
        html.style.fontFamily = "'Noto Sans Arabic', 'Segoe UI', sans-serif";
      } else {
        html.style.fontFamily = '';
      }
      return next;
    });
  };

  // ── Notifications ─────────────────────────────────────────────
  const [notifs, setNotifs] = useState([]);
  useEffect(() => {
    if (!authUser) return;
    window.API.getNotifs().then(ns => setNotifs(ns)).catch(() => {});
    const iv = setInterval(() => window.API.getNotifs().then(ns => setNotifs(ns)).catch(() => {}), 30000);
    return () => clearInterval(iv);
  }, [!!authUser]);
  const unread = notifs.filter(n => n.unread).length;

  const [toasts, setToasts] = useState([]);
  const toast = useCallback((msg) => {
    const id = Date.now() + Math.random();
    setToasts(ts => [...ts, { id, msg }]);
    setTimeout(() => setToasts(ts => ts.filter(x => x.id !== id)), 2600);
  }, []);

  // ── Votes (optimistic + API) ──────────────────────────────────
  const [votes, setVotes] = useState({});
  const onVote = useCallback(async (id, dir) => {
    const prev = votes[id];
    setVotes(v => ({ ...v, [id]: v[id] === dir ? undefined : dir }));
    try {
      const res = await window.API.voteIdea(id, dir);
      setVotes(v => ({ ...v, [id]: res.vote || undefined }));
    } catch (e) {
      setVotes(v => ({ ...v, [id]: prev }));
      toast('Vote failed: ' + e.message);
    }
  }, [votes, toast]);

  const go = useCallback((r) => { setPrevRoute(route); setRoute(r); document.querySelector('.content')?.scrollTo(0, 0); }, [route]);
  const openIdea = useCallback((idea) => { setActiveIdea(idea); setPrevRoute(route); setRoute('idea'); document.querySelector('.content')?.scrollTo(0, 0); }, [route]);
  const openUser = useCallback((user) => { setActiveUser(user); setPrevRoute(route); setRoute('user'); document.querySelector('.content')?.scrollTo(0, 0); }, [route]);

  const redeem = useCallback(async (award) => {
    try {
      const res = await window.API.redeem(award.id);
      setBalance(res.balance);
      toast(`Redeemed "${award.title}" · -${award.cost} pts`);
    } catch (e) {
      toast('Redemption failed: ' + e.message);
    }
  }, [toast]);

  const submitIdea = useCallback(async ({ title, description, category, tags, coverImage, extraImage, video }) => {
    try {
      await window.API.createIdea({ title, description, category, tags, coverImage, extraImage, video });
      setAddOpen(false);
      window.API.me().then(u => setBalance(u.balance)).catch(() => {});
      setRoute('myideas');
      toast(`Idea "${title}" submitted · +150 pts`);
    } catch (e) {
      toast('Submit failed: ' + e.message);
    }
  }, [toast]);

  const onSearchSubmit = useCallback((val, enter) => {
    if (enter && val.trim()) { setRoute('search'); document.querySelector('.content')?.scrollTo(0, 0); }
    else if (val.trim() && route !== 'search') { setRoute('search'); }
    else if (!val.trim() && route === 'search') { setRoute('home'); }
  }, [route]);

  const readNotif = useCallback(async (id) => {
    setNotifs(ns => ns.map(n => n.id === id ? { ...n, unread: false } : n));
    try { await window.API.readNotif(id); } catch {}
  }, []);
  const readAllNotifs = useCallback(async () => {
    setNotifs(ns => ns.map(n => ({ ...n, unread: false })));
    try { await window.API.readAllNotifs(); } catch {}
  }, []);

  const saveProfile = useCallback(() => { go('profile'); toast('Profile saved'); }, [go, toast]);

  // ⌘K focuses search
  useEffect(() => {
    const h = (e) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); document.querySelector('.search input')?.focus(); } };
    window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h);
  }, []);

  // apply tweaks → CSS vars
  useEffect(() => {
    const r = document.documentElement.style;
    document.body.classList.add('no-anim');
    const a = ACCENTS[t.accent] || ACCENTS.Blue;
    r.setProperty('--accent', a.c6); r.setProperty('--accent-600', a.c6); r.setProperty('--accent-700', a.c7);
    r.setProperty('--accent-300', a.c5); r.setProperty('--accent-100', a.c1); r.setProperty('--accent-50', a.c0);
    r.setProperty('--accent-rgb', a.rgb);
    const rad = RADII[t.radius] || RADII.Default;
    r.setProperty('--r-xs', rad.xs); r.setProperty('--r-sm', rad.sm); r.setProperty('--r', rad.r);
    r.setProperty('--r-lg', rad.lg); r.setProperty('--r-xl', rad.xl);
    r.setProperty('--density', t.density === 'Compact' ? '0.6' : '1');
    const dark = t.theme === 'Dark';
    document.body.classList.toggle('dark', dark);
    r.setProperty('--accent-50', dark ? `rgba(${a.rgb},.16)` : a.c0);
    r.setProperty('--accent-100', dark ? `rgba(${a.rgb},.26)` : a.c1);
    r.setProperty('--accent-700', dark ? a.c5 : a.c7);
    requestAnimationFrame(() => requestAnimationFrame(() => document.body.classList.remove('no-anim')));
  }, [t.accent, t.radius, t.density, t.theme]);

  const screen = () => {
    const listProps = { votes, onVote, openIdea };
    switch (route) {
      case 'home':          return <window.HomeScreen search={search} currentUser={authUser} {...listProps} />;
      case 'search':        return <window.SearchResults query={search} setSearch={setSearch} openIdea={openIdea} openUser={openUser} votes={votes} onVote={onVote} />;
      case 'addIdea':       return <window.AddIdeaPage goBack={() => go(prevRoute === 'addIdea' ? 'home' : prevRoute)} onSubmit={submitIdea} />;
      case 'dashboard':     return <window.DashboardScreen openIdea={openIdea} openUser={openUser} votes={votes} onVote={onVote} />;
      case 'myideas':       return <window.MyIdeasScreen currentUser={authUser} {...listProps} />;
      case 'favorite':      return <window.FavoriteScreen {...listProps} />;
      case 'profile':       return <window.ProfileScreen currentUser={authUser} onEdit={() => go('editProfile')} openUser={openUser} />;
      case 'editProfile':   return <window.EditProfileScreen currentUser={authUser} goBack={() => go('profile')} onSave={saveProfile} />;
      case 'settings':      return <window.SettingsScreen onLogout={handleLogout} />;
      case 'trade':         return <window.TradeScreen balance={balance} onRedeem={redeem} onHistory={() => go('balanceDetail')} />;
      case 'balanceDetail': return <window.BalanceDetailScreen balance={balance} goBack={() => go('trade')} />;
      case 'user':          return <window.PublicProfileScreen user={activeUser} goBack={() => go(prevRoute)} openIdea={openIdea} votes={votes} onVote={onVote} />;
      case 'idea':          return <window.IdeaDetail idea={activeIdea} vote={votes[activeIdea?.id]} onVote={onVote} goBack={() => go(prevRoute)} openUser={openUser} currentUser={authUser} />;
      default:              return <window.HomeScreen search={search} currentUser={authUser} {...listProps} />;
    }
  };

  // nav highlight: map sub-routes back to their owning nav section
  const navMap = { idea: prevRoute, user: prevRoute, editProfile: 'profile', balanceDetail: 'trade', search: 'home', addIdea: prevRoute };
  const navRoute = navMap[route] || route;

  // ── Auth gate ─────────────────────────────────────────────────
  if (!authReady) return (
    <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--bg)' }}>
      <div style={{ width: 40, height: 40, border: '3px solid var(--line)', borderTopColor: 'var(--accent)', borderRadius: '50%', animation: 'spin 0.8s linear infinite' }} />
    </div>
  );
  if (!authUser) return <window.LoginScreen onLogin={handleLogin} />;

  return (
    <div className={`app ${collapsed ? 'rail-collapsed' : ''} ${t.railStyle === 'Filled' ? 'rail-filled' : ''}`}>
      <window.Sidebar route={navRoute} go={go} collapsed={collapsed} balance={balance} lang={lang} />
      <div className="main">
        <window.Topbar toggleRail={() => setCollapsed(c => !c)} search={search} setSearch={setSearch} balance={balance} onAdd={() => go('addIdea')} onNav={go} onSearchSubmit={onSearchSubmit} notifOpen={notifOpen} setNotifOpen={setNotifOpen} unread={unread} currentUser={authUser} lang={lang} toggleLang={toggleLang} />
        <div className="content">{screen()}</div>
      </div>
      <window.NotificationsPanel open={notifOpen} onClose={() => setNotifOpen(false)} items={notifs} onRead={readNotif} onReadAll={readAllNotifs} />
      <window.AddIdeaDrawer open={addOpen} onClose={() => setAddOpen(false)} onSubmit={submitIdea} />
      <Toasts items={toasts} />
      <window.TweaksPanel>
        <window.TweakSection label="Theme" />
        <window.TweakRadio label="Mode" value={t.theme} options={['Light', 'Dark']} onChange={(v) => setTweak('theme', v)} />
        <window.TweakSection label="Brand accent" />
        <window.TweakColor label="Accent" value={(ACCENTS[t.accent]||ACCENTS.Blue).c6}
          options={Object.values(ACCENTS).map(a => a.c6)}
          onChange={(hex) => setTweak('accent', Object.keys(ACCENTS).find(k => ACCENTS[k].c6 === hex) || 'Blue')} />
        <window.TweakSection label="Shape & density" />
        <window.TweakRadio label="Corners" value={t.radius} options={['Sharp', 'Default', 'Round']} onChange={(v) => setTweak('radius', v)} />
        <window.TweakRadio label="Density" value={t.density} options={['Comfortable', 'Compact']} onChange={(v) => setTweak('density', v)} />
        <window.TweakSection label="Navigation" />
        <window.TweakRadio label="Active item" value={t.railStyle} options={['Tinted', 'Filled']} onChange={(v) => setTweak('railStyle', v)} />
      </window.TweaksPanel>
    </div>
  );
}

// alias fix
window.Toasts = Toasts;
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
