// FartBet — App root: API-driven state, routing, palette tweaks
const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA, useCallback: useCallbackA } = React;

const PALETTES = {
  betboom:  { accent: '#FFD600', accent2: '#FFC400', accent3: '#B47700', ink: '#0a0a0a', bg: '#0a0a0a', surface: '#161616', name: 'BetBoom · жёлтый' },
  casino:   { accent: '#00E676', accent2: '#00C853', accent3: '#0a5d2c', ink: '#04140A', bg: '#0a0f0a', surface: '#0f1a13', name: 'Casino · зелёный' },
  cyber:    { accent: '#00E5FF', accent2: '#00B8D4', accent3: '#006978', ink: '#001318', bg: '#0a0d12', surface: '#11161e', name: 'Cyber · циан' },
  fire:     { accent: '#FF6D00', accent2: '#FF3D00', accent3: '#7a2a00', ink: '#0a0500', bg: '#0d0805', surface: '#1a1108', name: 'Fire · оранжевый' },
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "betboom",
  "density": "regular"
}/*EDITMODE-END*/;

function applyPalette(name) {
  const p = PALETTES[name] || PALETTES.betboom;
  const r = document.documentElement.style;
  r.setProperty('--accent', p.accent);
  r.setProperty('--accent-2', p.accent2);
  r.setProperty('--accent-3', p.accent3);
  r.setProperty('--accent-ink', p.ink);
  r.setProperty('--bg', p.bg);
  r.setProperty('--surface', p.surface);
}

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useEffectA(() => { applyPalette(tweaks.palette); }, [tweaks.palette]);

  const [route, setRoute]   = useStateA({ name: 'home' });
  const [user, setUser]     = useStateA(null);
  const [authOpen, setAuthOpen] = useStateA(false);
  const [selections, setSelections] = useStateA([]);
  const [bets, setBets]     = useStateA([]);
  const [events, setEvents] = useStateA([]);
  const [users, setUsers]   = useStateA([]);
  const [spark, setSpark]   = useStateA({});
  const [categories, setCategories] = useStateA({});
  const [config, setConfig] = useStateA({ devMode: true });
  const [toast, setToast]   = useStateA(null);
  const [loading, setLoading] = useStateA(true);
  const [searchQuery, setSearchQuery] = useStateA('');

  // ── Data refresh ──────────────────────────────────────────────────────
  const refresh = useCallbackA(async () => {
    const [evts, bts, usrs, spk, cfg] = await Promise.all([
      api.getEvents(), api.getBets(), api.getUsers(), api.getSpark(), api.getConfig(),
    ]);
    setEvents(evts);
    setBets(bts);
    setUsers(usrs);
    setSpark(spk);
    if (cfg && cfg.categories) setCategories(cfg.categories);
  }, []);

  // ── Initial load ──────────────────────────────────────────────────────
  useEffectA(() => {
    (async () => {
      try {
        // Check for invite token in URL
        const urlParams = new URLSearchParams(window.location.search);
        const inviteToken = urlParams.get('invite');
        if (inviteToken) {
          // Remove token from URL without reload
          const cleanUrl = window.location.pathname;
          window.history.replaceState({}, '', cleanUrl);
          const res = await api.useInvite(inviteToken);
          if (res.ok) {
            const [cfg] = await Promise.all([api.getConfig()]);
            setConfig(cfg);
            setCategories(cfg.categories || {});
            setUser(res.user);
            setToast({ msg: `Привет, ${res.user.name.split(' ')[0]}! Добро пожаловать в FartBet.`, kind: 'ok' });
            await refresh();
            setLoading(false);
            return;
          }
          // Invalid invite — continue normal load but show error
          setToast({ msg: 'Ссылка-приглашение недействительна или уже использована', kind: 'err' });
        }

        const [me, cfg] = await Promise.all([api.getMe(), api.getConfig()]);
        setConfig(cfg);
        setCategories(cfg.categories || {});
        if (me && me.id) { setUser(me); }
        else { setAuthOpen(true); }
        await refresh();
      } catch (e) {
        console.error('Init error', e);
        setAuthOpen(true);
      }
      setLoading(false);
    })();
  }, []);

  // ── Periodic refresh ──────────────────────────────────────────────────
  useEffectA(() => {
    const iv = setInterval(() => { refresh(); refreshUser(); }, 5000);
    return () => clearInterval(iv);
  }, [refresh]);

  // ── Refresh current user balance ──────────────────────────────────────
  const refreshUser = useCallbackA(async () => {
    const me = await api.getMe();
    if (me && me.id) setUser(me);
  }, []);

  // ── liveData object (same shape for screens) ─────────────────────────
  const liveData = useMemoA(() => ({
    USERS: users,
    EVENTS: events,
    BETS: bets,
    CATEGORIES: categories,
    SPARK: spark,
    byId: (id) => users.find(u => u.id === id),
  }), [users, events, bets, categories, spark]);

  // ── Auth ──────────────────────────────────────────────────────────────
  const loginDirect = async (userObj) => {
    setUser(userObj);
    setAuthOpen(false);
    setToast({ msg: `Привет, ${userObj.name.split(' ')[0]}! Удачи в линии.`, kind: 'ok' });
    await refresh();
  };

  const loginTelegram = async (tgData) => {
    try {
      const res = await api.telegramAuth(tgData);
      if (res.ok) {
        setUser(res.user);
        setAuthOpen(false);
        setToast({ msg: `Привет, ${res.user.name.split(' ')[0]}! Удачи в линии.`, kind: 'ok' });
        await refresh();
      } else {
        setToast({ msg: res.error || 'Ошибка авторизации через Telegram', kind: 'err' });
      }
    } catch (e) {
      setToast({ msg: 'Ошибка сети', kind: 'err' });
    }
  };

  const devLogin = async (uid) => {
    try {
      const res = await api.devLogin(uid);
      if (res.ok) {
        setUser(res.user);
        setAuthOpen(false);
        setToast({ msg: `Привет, ${res.user.name.split(' ')[0]}! Удачи в линии.`, kind: 'ok' });
        await refresh();
      } else {
        setToast({ msg: res.error || 'Ошибка входа', kind: 'err' });
      }
    } catch (e) {
      setToast({ msg: 'Ошибка сети', kind: 'err' });
    }
  };

  const logout = async () => {
    await api.logout();
    setUser(null);
    setRoute({ name: 'home' });
    setAuthOpen(true);
  };

  // ── Selections ────────────────────────────────────────────────────────
  const addSel = (event, out) => {

    setSelections(prev => {
      const exists = prev.find(s => s.event.id === event.id && s.outcomeId === out.id);
      if (exists) return prev.filter(s => !(s.event.id === event.id && s.outcomeId === out.id));
      const filtered = prev.filter(s => s.event.id !== event.id);
      return [...filtered, { event, outcomeId: out.id, outcomeLabel: out.label, coef: out.coef }];
    });
  };
  const isSelected = (eid, oid) => selections.some(s => s.event.id === eid && s.outcomeId === oid);
  const removeSel = (i) => setSelections(prev => prev.filter((_, idx) => idx !== i));
  const clearSel = () => setSelections([]);

  // ── Place bet (API) ───────────────────────────────────────────────────
  const placeBet = async (stake, totalCoef, potential) => {
    if (!user || stake > user.balance || selections.length === 0) return;
    try {
      const res = await api.placeBet({
        selections: selections.map(s => ({
          eventId: s.event.id,
          outcomeId: s.outcomeId,
          coef: s.coef,
        })),
        stake,
      });
      if (res.ok) {
        setUser(u => ({ ...u, balance: res.balance }));
        setSelections([]);
        await refresh();
        setToast({ msg: `Ставка принята: ${formatPC(stake)} PC → возможный выигрыш ${formatPC(potential)} PC`, kind: 'ok' });
        setRoute({ name: 'board' });
      } else {
        setToast({ msg: res.error || 'Ошибка при размещении ставки', kind: 'err' });
      }
    } catch (e) {
      setToast({ msg: 'Ошибка сети', kind: 'err' });
    }
  };

  // ── Toast auto-hide ───────────────────────────────────────────────────
  useEffectA(() => {
    if (!toast) return;
    const t = setTimeout(() => setToast(null), 3200);
    return () => clearTimeout(t);
  }, [toast]);

  // ── Admin: create / settle event (API) ────────────────────────────────
  const createEvent = async (e) => {
    try {
      const res = await api.createEvent(e);
      if (res.ok) {
        await refresh();
        setToast({ msg: `Событие «${e.title.slice(0, 28)}…» опубликовано`, kind: 'ok' });
      } else {
        setToast({ msg: res.error || 'Ошибка создания', kind: 'err' });
      }
    } catch (err) {
      setToast({ msg: 'Ошибка сети', kind: 'err' });
    }
  };

  const settleEvent = async (eid, oid) => {
    try {
      let res;
      if (oid === '__close') {
        res = await api.closeEvent(eid);
        if (res.ok) { await refresh(); setToast({ msg: 'Приём ставок закрыт', kind: 'ok' }); }
      } else if (oid === '__cancel') {
        res = await api.cancelEvent(eid);
        if (res.ok) { await refresh(); setToast({ msg: 'Событие отменено · ставки возвращены', kind: 'ok' }); }
      } else {
        res = await api.settleEvent(eid, oid);
        if (res.ok) {
          await Promise.all([refresh(), refreshUser()]);
          setToast({ msg: 'Итог объявлен. Балансы обновлены.', kind: 'ok' });
        }
      }
      if (res && !res.ok) setToast({ msg: res.error || 'Ошибка', kind: 'err' });
    } catch (err) {
      setToast({ msg: 'Ошибка сети', kind: 'err' });
    }
  };

  // ── Render ────────────────────────────────────────────────────────────
  if (loading) {
    return <div style={{ display:'flex', alignItems:'center', justifyContent:'center', height:'100vh', color:'var(--text-2)', fontSize:16 }}>Загрузка…</div>;
  }

  const showSlip = route.name === 'home' || route.name === 'event';
  const currentEvent = route.name === 'event' ? events.find(e => e.id === route.id) : null;

  return (
    <div className={cx('app', !showSlip && 'app-no-slip')}>
      <HeaderBar user={user} route={route} setRoute={setRoute} onLogout={logout} onOpenAuth={() => setAuthOpen(true)} onSearch={setSearchQuery} searchQuery={searchQuery} />
      <LeftRail route={route} setRoute={setRoute} user={user} data={liveData} onOpenAuth={() => setAuthOpen(true)} />

      <main className="main">
        {route.name === 'home' && (
          <HomeScreen data={liveData} route={route} setRoute={setRoute} addSel={addSel} isSelected={isSelected} recentBets={bets} user={user} searchQuery={searchQuery} />
        )}
        {route.name === 'event' && (
          <EventScreen event={currentEvent} data={liveData} setRoute={setRoute} addSel={addSel} isSelected={isSelected} recentBets={bets} user={user} />
        )}
        {route.name === 'board' && (
          <BoardScreen data={liveData} recentBets={bets} setRoute={setRoute} user={user} />
        )}
        {route.name === 'rating' && (
          <RatingScreen data={liveData} user={user} setRoute={setRoute} />
        )}
        {route.name === 'profile' && (
          <ProfileScreen user={user} data={liveData} recentBets={bets} setRoute={setRoute} onLogout={logout} />
        )}
        {route.name === 'history' && (
          <HistoryScreen user={user} data={liveData} recentBets={bets} setRoute={setRoute} />
        )}
        {route.name === 'admin' && (
          <AdminScreen user={user} data={liveData} recentBets={bets} setRoute={setRoute}
                       onCreateEvent={createEvent} onSettle={settleEvent} onRefreshUsers={refresh} />
        )}
      </main>

      {showSlip && (
        <aside className="slip-col">
          <BetSlip
            selections={selections}
            removeSel={removeSel}
            clearSel={clearSel}
            onPlace={placeBet}
            user={user}
            onOpenAuth={() => setAuthOpen(true)}
          />
        </aside>
      )}

      <AuthModal open={authOpen} onClose={() => user && setAuthOpen(false)}
                 onLogin={loginTelegram} onDevLogin={devLogin}
                 users={users} config={config} />

      <Toast msg={toast?.msg} kind={toast?.kind} />
      <CookieBanner />

      <TweaksPanel>
        <TweakSection label="Палитра" />
        <TweakSelect
          label="Цветовая схема"
          value={tweaks.palette}
          options={Object.entries(PALETTES).map(([k, p]) => ({ value: k, label: p.name }))}
          onChange={(v) => setTweak('palette', v)}
        />
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 6, marginTop: 4 }}>
          {Object.entries(PALETTES).map(([k, p]) => (
            <button key={k}
              onClick={() => setTweak('palette', k)}
              title={p.name}
              style={{
                height: 40, borderRadius: 8,
                background: `linear-gradient(135deg, ${p.accent} 0%, ${p.bg} 100%)`,
                border: tweaks.palette === k ? '2px solid #29261b' : '1px solid rgba(0,0,0,.1)',
                cursor: 'pointer',
              }} />
          ))}
        </div>
      </TweaksPanel>
    </div>
  );
}

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