// app.jsx — production bootstrap: тема + загрузка живых данных из /api/portfolio.
// Заменяет инлайн-скрипт дизайн-исходника. Подключается последним (после
// portfolio-data / portfolio-atoms / portfolio-screen).

const { useState, useEffect } = React;

const DARK = "taupe";          // вариант B — тёмная
const LIGHT = "exchangeLight"; // вариант B — светлая

// Telegram WebApp SDK
const tg = window.Telegram && window.Telegram.WebApp;
const INIT_DATA = (tg && tg.initData) || "";

// Тема берётся из Telegram / системы устройства (без сохранённого выбора —
// приложение всегда следует текущей теме окружения).
function detectEnv() {
  try {
    if (tg && tg.colorScheme) return tg.colorScheme === "light" ? "light" : "dark";
  } catch (e) {}
  if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) return "light";
  return "dark";
}

// ---- theme toggle ----
function SunIcon() {
  return (
    <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="4" />
      <path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" />
    </svg>);
}
function MoonIcon() {
  return (
    <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" />
    </svg>);
}
function ThemeToggle({ mode, onToggle }) {
  const dark = mode === "dark";
  return (
    <button
      onClick={onToggle}
      aria-label={dark ? "Светлая тема" : "Тёмная тема"}
      style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        width: 34, height: 34, borderRadius: 10,
        border: "1px solid var(--border)", background: "var(--card2)",
        color: "var(--muted)", cursor: "pointer", padding: 0,
      }}>
      {dark ? <SunIcon /> : <MoonIcon />}
    </button>);
}

// ---- status screens (loading / error / empty) ----
function CenterMsg({ theme, children }) {
  const vars = window.THEMES[theme].vars;
  return (
    <div style={{ ...vars, minHeight: "60vh", display: "flex", alignItems: "center", justifyContent: "center", padding: "40px 20px", textAlign: "center", color: "var(--muted)", fontSize: 14.5, fontFamily: "ui-sans-serif, -apple-system, 'Segoe UI', system-ui, sans-serif", lineHeight: 1.5 }}>
      <div>{children}</div>
    </div>);
}
function Spinner() {
  return (
    <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"
      style={{ animation: "pf-spin 0.8s linear infinite", color: "var(--muted)" }}>
      <path d="M21 12a9 9 0 1 1-2.64-6.36" />
    </svg>);
}

// ---- main app ----
function App() {
  const [mode, setMode] = useState(detectEnv);
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const theme = mode === "dark" ? DARK : LIGHT;
  const bg = window.THEMES[theme].vars["--bg"];

  // фон страницы + theme-color под текущую тему
  useEffect(() => {
    document.body.style.background = bg;
    const page = document.getElementById("page");
    if (page) page.style.background = bg;
    const meta = document.querySelector('meta[name="theme-color"]') || (() => {
      const m = document.createElement("meta"); m.name = "theme-color"; document.head.appendChild(m); return m;
    })();
    meta.content = bg;
  }, [mode, bg]);

  // живое следование теме устройства/Telegram: реагируем на смену темы
  useEffect(() => {
    const apply = () => setMode(detectEnv());
    let tgBound = false;
    try { if (tg && tg.onEvent) { tg.onEvent("themeChanged", apply); tgBound = true; } } catch (e) {}
    let mq = null;
    if (window.matchMedia) {
      mq = window.matchMedia("(prefers-color-scheme: dark)");
      if (mq.addEventListener) mq.addEventListener("change", apply);
      else if (mq.addListener) mq.addListener(apply);
    }
    return () => {
      try { if (tgBound && tg.offEvent) tg.offEvent("themeChanged", apply); } catch (e) {}
      if (mq) {
        if (mq.removeEventListener) mq.removeEventListener("change", apply);
        else if (mq.removeListener) mq.removeListener(apply);
      }
    };
  }, []);

  async function load() {
    if (!INIT_DATA) {
      setError("Откройте приложение через кнопку в Telegram.");
      setLoading(false);
      return;
    }
    try {
      const res = await fetch("api/portfolio", {
        headers: { Authorization: "tma " + INIT_DATA },
        cache: "no-store",
      });
      if (res.status === 401) { setError("Сессия истекла. Закройте и снова откройте мини-апп."); setLoading(false); return; }
      if (res.status === 403) { setError("Доступ запрещён."); setLoading(false); return; }
      if (!res.ok) { setError("Ошибка сервера (" + res.status + "). Попробуйте обновить."); setLoading(false); return; }
      const json = await res.json();
      setData(window.mapPortfolio(json));
      setError(null);
      setLoading(false);
    } catch (e) {
      // при наличии старых данных не затираем экран — просто показываем последнюю ошибку
      if (!data) setError("Нет соединения. Потяните «Обновить».");
      setLoading(false);
    }
  }

  useEffect(() => {
    if (tg) { try { tg.ready(); tg.expand(); } catch (e) {} }
    load();
    // eslint-disable-next-line
  }, []);

  const toggle = () => setMode((m) => (m === "dark" ? "light" : "dark"));

  // первичная загрузка
  if (loading && !data) return <CenterMsg theme={theme}><div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }}><Spinner />Загрузка портфеля…</div></CenterMsg>;
  // ошибка без данных
  if (error && !data) return (
    <CenterMsg theme={theme}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 14 }}>
        <div>{error}</div>
        <button onClick={() => { setLoading(true); setError(null); load(); }}
          style={{ padding: "9px 18px", borderRadius: 10, border: "1px solid var(--border)", background: "var(--card2)", color: "var(--text)", fontSize: 14, fontWeight: 600, cursor: "pointer" }}>
          Обновить
        </button>
      </div>
    </CenterMsg>);
  // пустой портфель
  if (data && data.empty) return <CenterMsg theme={theme}>Портфель пуст.<br />Добавьте сделки через бота — и они появятся здесь.</CenterMsg>;

  return (
    <window.PortfolioScreen
      theme={theme}
      width="100%"
      data={data}
      onRefresh={load}
      headerExtra={<ThemeToggle mode={mode} onToggle={toggle} />}
    />);
}

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