const API_URL = "https://younalyse-api-646149995822.europe-west1.run.app";

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/ {
  theme: "light",
  density: "normal",
  accent: "#2563EB",
  showMobile: false,
}; /*EDITMODE-END*/

const ToastContext = React.createContext(null);

const ToastProvider = ({ children }) => {
  const [toasts, setToasts] = React.useState([]);
  const addToast = React.useCallback((message, type = "info") => {
    const id = Date.now();
    setToasts((prev) => [...prev, { id, message, type }]);
    setTimeout(
      () => setToasts((prev) => prev.filter((t) => t.id !== id)),
      4000,
    );
  }, []);
  const removeToast = (id) =>
    setToasts((prev) => prev.filter((t) => t.id !== id));
  return (
    <ToastContext.Provider value={addToast}>
      {children}
      <div
        style={{
          position: "fixed",
          bottom: 24,
          left: "50%",
          transform: "translateX(-50%)",
          display: "flex",
          flexDirection: "column",
          gap: 8,
          zIndex: 9999,
          pointerEvents: "none",
        }}
      >
        {toasts.map((t) => (
          <div
            key={t.id}
            style={{
              display: "flex",
              alignItems: "center",
              gap: 10,
              padding: "10px 16px",
              borderRadius: "var(--radius)",
              background:
                t.type === "error"
                  ? "var(--bad)"
                  : t.type === "ok"
                    ? "var(--good)"
                    : "var(--fg)",
              color: "#fff",
              fontSize: 13,
              fontWeight: 500,
              boxShadow: "var(--shadow-lg)",
              pointerEvents: "all",
              animation: "slideUp 0.2s ease-out",
              minWidth: 280,
              maxWidth: 480,
            }}
          >
            <span style={{ flex: 1 }}>{t.message}</span>
            <button
              onClick={() => removeToast(t.id)}
              style={{
                background: "none",
                border: "none",
                color: "rgba(255,255,255,0.7)",
                cursor: "pointer",
                fontSize: 16,
                lineHeight: 1,
                padding: 0,
              }}
            >
              ✕
            </button>
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
};

const useToast = () => React.useContext(ToastContext);

const App = ({ tweaks, setTweak }) => {
  const toast = useToast();
  const [authed, setAuthed] = React.useState(false);
  const [userId, setUserId] = React.useState(null);
  const [userProfile, setUserProfile] = React.useState(null);
  const [teamInfo, setTeamInfo] = React.useState(null); // null = не member

  // OAuth-каналы пользователя и активный канал
  const [oauthChannels, setOauthChannels] = React.useState([]);
  const [activeChannel, setActiveChannel] = React.useState(null); // null = все каналы

  const loadOauthChannels = React.useCallback((uid) => {
    if (!uid) return;
    fetch(`${API_URL}/api/analytics/channels?user_id=${uid}`)
      .then((r) => r.json())
      .then((json) => {
        const channels = json.channels || [];
        setOauthChannels(channels);
        // Не выбираем канал автоматически — по умолчанию "все"
      })
      .catch(() => {});
  }, []);

  React.useEffect(() => {
    window.supabaseClient.auth.getSession().then(({ data: { session } }) => {
      if (session) {
        setAuthed(true);
        setUserId(session.user.id);
        fetch(`${API_URL}/api/profile?user_id=${session.user.id}`)
          .then((r) => r.json())
          .then((profile) => setUserProfile(profile))
          .catch(() => {});
        loadOauthChannels(session.user.id);
      }
    });
    const {
      data: { subscription },
    } = window.supabaseClient.auth.onAuthStateChange((_event, session) => {
      setAuthed(!!session);
      setUserId(session?.user?.id || null);
      if (session?.user?.id) {
        fetch(`${API_URL}/api/profile?user_id=${session.user.id}`)
          .then((r) => r.json())
          .then((profile) => {
            setUserProfile(profile);
            // Применяем промокод если он есть в localStorage и профиль новый
            // (нет referral_source — значит промокод ещё не применялся)
            if (!profile?.referral_source) {
              try {
                const promoCode = localStorage.getItem("youna_promo");
                const utmRaw = localStorage.getItem("youna_utm");
                const utm = utmRaw ? JSON.parse(utmRaw) : {};
                // Проверяем срок хранения UTM (30 дней)
                const isUtmFresh =
                  utm.saved_at && Date.now() - utm.saved_at < 30 * 86400000;
                const code = promoCode || (isUtmFresh ? utm.ref : null);
                if (code) {
                  fetch(`${API_URL}/api/promos/apply`, {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({
                      user_id: session.user.id,
                      code,
                      utm_source: isUtmFresh ? utm.utm_source : null,
                      utm_medium: isUtmFresh ? utm.utm_medium : null,
                      utm_campaign: isUtmFresh ? utm.utm_campaign : null,
                    }),
                  })
                    .then(() => {
                      // Очищаем после применения
                      localStorage.removeItem("youna_promo");
                      localStorage.removeItem("youna_utm");
                      // Перезагружаем профиль с новым тиром
                      fetch(`${API_URL}/api/profile?user_id=${session.user.id}`)
                        .then((r) => r.json())
                        .then((p) => setUserProfile(p))
                        .catch(() => {});
                    })
                    .catch(() => {});
                }
              } catch {}
            }
          })
          .catch(() => {});
        loadOauthChannels(session.user.id);
      } else {
        setUserProfile(null);
        setOauthChannels([]);
        setActiveChannel(null);
      }
    });
    return () => subscription.unsubscribe();
  }, [loadOauthChannels]);

  React.useEffect(() => {
    const onNavigate = (e) => setPage(e.detail);
    window.addEventListener("navigate", onNavigate);
    return () => window.removeEventListener("navigate", onNavigate);
  }, []);

  // Резолвим принадлежность к команде
  React.useEffect(() => {
    if (!userId) {
      setTeamInfo(null);
      return;
    }
    fetch(`${API_URL}/api/team/resolve?user_id=${userId}`)
      .then((r) => r.json())
      .then((d) => setTeamInfo(d.is_member ? d : null))
      .catch(() => setTeamInfo(null));
  }, [userId]);

  // Перехват UTM-параметров и промокода при первом визите
  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const ref = params.get("ref");
    const utmSource = params.get("utm_source");
    const utmMedium = params.get("utm_medium");
    const utmCampaign = params.get("utm_campaign");

    // Сохраняем в localStorage на 30 дней если есть параметры
    if (ref || utmSource) {
      const utmData = {
        ref: ref || null,
        utm_source: utmSource || null,
        utm_medium: utmMedium || null,
        utm_campaign: utmCampaign || null,
        saved_at: Date.now(),
      };
      try {
        localStorage.setItem("youna_utm", JSON.stringify(utmData));
      } catch {}
    }

    // Применяем промокод при регистрации нового пользователя
    if (ref) {
      try {
        localStorage.setItem("youna_promo", ref.toUpperCase());
      } catch {}
    }
  }, []);

  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.get("page") === "analytics") {
      setPage("analytics");
      if (params.get("connected") === "true") {
        toast("YouTube channel connected!", "ok");
        // Перезагружаем каналы после подключения нового
        if (userId) loadOauthChannels(userId);
      }
      if (params.get("error")) {
        toast("Failed to connect YouTube channel", "error");
      }
      window.history.replaceState({}, "", window.location.pathname);
    }
  }, [userId, loadOauthChannels]);

  const [page, setPage] = React.useState("analysis");
  const [results, setResults] = React.useState([]);

  const [selectedRunFilter, setSelectedRunFilter] = React.useState(null);
  const [showHidden, setShowHidden] = React.useState(false);

  const fetchResults = React.useCallback(
    (uid, hidden = false, afterRunId = null) => {
      const params = new URLSearchParams();
      if (uid) params.set("user_id", uid);
      if (hidden) params.set("show_hidden", "true");
      fetch(`${API_URL}/api/results?${params.toString()}`)
        .then((r) => {
          if (!r.ok) throw new Error(`Server error ${r.status}`);
          return r.json();
        })
        .then((json) => {
          if (json.videos) {
            setResults(
              json.videos.map((v) => ({
                id: v.id,
                runId: v.run_id || null,
                analyzedAt: v.analyzed_at || v.created_at || null,
                channelName: v.channel_name,
                subscribers: v.subscribers,
                title: v.title,
                url: v.url,
                publishedAt: v.published_at,
                tags: v.tags ? v.tags.split(", ") : [],
                views: v.views,
                likes: v.likes,
                commentsCount: v.comments_count,
                engagementPct: parseFloat(v.engagement_pct) || 0,
                transcript: v.transcript || "",
                durationSec: v.duration_sec || 0,
                aiSummary: "",
                sampleComments: [],
                openQuestions: [],
              })),
            );
            // Устанавливаем фильтр по рану после загрузки данных
            if (afterRunId) {
              setSelectedRunFilter(afterRunId);
            }
          }
        })
        .catch((e) => {
          console.error("fetchResults error:", e);
          toast("Failed to load results. Please try again.", "error");
        });
    },
    [toast],
  );

  React.useEffect(() => {
    if (userId) fetchResults(userId);
  }, [userId]);

  const [openVideo, setOpenVideo] = React.useState(null);
  const [runState, setRunState] = React.useState("idle");
  const [runLog, setRunLog] = React.useState([]);
  const [runProgress, setRunProgress] = React.useState(0);
  const runTimers = React.useRef([]);
  const pollInterval = React.useRef(null);

  React.useEffect(() => {
    document.documentElement.setAttribute("data-theme", tweaks.theme);
    document.documentElement.setAttribute("data-density", tweaks.density);
    document.documentElement.style.setProperty("--accent", tweaks.accent);
    const softHex = tweaks.accent + "1A";
    document.documentElement.style.setProperty("--accent-soft", softHex);
  }, [tweaks.theme, tweaks.density, tweaks.accent]);

  const stopRun = () => {
    runTimers.current.forEach(clearTimeout);
    runTimers.current = [];
    if (pollInterval.current) {
      clearInterval(pollInterval.current);
      pollInterval.current = null;
    }
    setRunState("idle");
    setRunLog([]);
    setRunProgress(0);
  };

  const ts = () => {
    const d = new Date();
    return [d.getHours(), d.getMinutes(), d.getSeconds()]
      .map((n) => String(n).padStart(2, "0"))
      .join(":");
  };

  const startRun = async (cfg) => {
    setRunState("running");
    setRunLog([]);
    setRunProgress(0);
    setSelectedRunFilter(null);

    const body =
      cfg.mode === "video"
        ? {
            mode: "video",
            channels: [],
            video_urls: cfg.video_urls || [],
            user_id: userId,
            analyze_comments: cfg.analyzeComments === true,
            generate_summary: cfg.generateSummary === true,
          }
        : {
            mode: "channel",
            channels: cfg.channels,
            video_urls: [],
            user_id: userId,
            max_videos: cfg.maxVideos || 20,
            content_filter: cfg.contentFilter || "all",
            transcript_seconds: 30,
            analyze_comments: cfg.analyzeComments === true,
            generate_summary: cfg.generateSummary === true,
          };

    try {
      const response = await fetch(`${API_URL}/api/analysis/run`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });

      if (!response.ok) throw new Error(`Server error ${response.status}`);
      const data = await response.json();

      if (data.error) {
        toast(data.message || "Ошибка запуска", "error");
        setRunState("idle");
        return;
      }

      const runId = data.run_id;
      setRunLog((prev) => [
        ...prev,
        { t: ts(), level: "", text: `→ Run ID: ${runId}` },
      ]);
      setRunProgress(1);

      // Поллинг статуса каждые 3 секунды
      if (pollInterval.current) clearInterval(pollInterval.current);
      pollInterval.current = setInterval(async () => {
        try {
          const st = await fetch(
            `${API_URL}/api/analysis/status/${runId}`,
          ).then((r) => r.json());
          const step = st.progress_step || "";
          const detail = st.progress_detail || "";

          if (detail)
            setRunLog((prev) => {
              const last = prev[prev.length - 1];
              if (last?.text === detail) return prev;
              return [...prev, { t: ts(), level: "", text: detail }];
            });

          if (step === "collect") setRunProgress(1);
          else if (step === "transcript") setRunProgress(2);
          else if (step === "comments") setRunProgress(3);
          else if (step === "analyze") setRunProgress(4);
          else if (step === "done") {
            setRunProgress(6);
            setRunState("done");
            fetchResults(userId, false, runId);
            toast(
              window.T?.analysisComplete ||
                "Анализ завершён! Результаты готовы.",
              "ok",
            );
            clearInterval(pollInterval.current);
            pollInterval.current = null;
          } else if (st.status === "completed") {
            setRunProgress(6);
            setRunState("done");
            fetchResults(userId, false, runId);
            toast(
              window.T?.analysisComplete ||
                "Анализ завершён! Результаты готовы.",
              "ok",
            );
            clearInterval(pollInterval.current);
            pollInterval.current = null;
          } else if (st.status === "failed" || step === "error") {
            const errMsg =
              detail ||
              st.progress_detail ||
              "Ошибка анализа — проверьте URL канала";
            toast(errMsg, "error");
            setRunLog((prev) => [
              ...prev,
              { t: ts(), level: "err", text: "❌ " + errMsg },
            ]);
            setRunState("idle");
            setRunProgress(0);
            clearInterval(pollInterval.current);
            pollInterval.current = null;
          }
        } catch (e) {}
      }, 3000);
    } catch (err) {
      const msg = err.message.includes("Failed to fetch")
        ? "Cannot connect to server. Check your internet connection."
        : `Run failed: ${err.message}`;
      setRunLog((prev) => [...prev, { t: ts(), level: "err", text: msg }]);
      setRunState("idle");
      toast(msg, "error");
    }
  };

  React.useEffect(() => () => runTimers.current.forEach(clearTimeout), []);

  const openVideoIdx = openVideo
    ? results.findIndex((r) => r.id === openVideo.id)
    : -1;
  const openPrev = () =>
    openVideoIdx > 0 && setOpenVideo(results[openVideoIdx - 1]);
  const openNext = () =>
    openVideoIdx < results.length - 1 &&
    setOpenVideo(results[openVideoIdx + 1]);

  const titleByPage = {
    admin: ["Admin", "P&L Dashboard"],
    analysis: [window.T?.navNewAnalysis || "Новый анализ", null],
    results: [
      window.T?.resultsTitle || "Results",
      `${results.length} ${window.PRODUCT_MODE === "ru" ? "видео" : "videos"}`,
    ],
    keywords: [
      window.T?.keywordsTitle || "Keywords",
      (() => {
        const u = window._kwUsage;
        if (!u) return null;
        const isRU = window.PRODUCT_MODE === "ru";
        const daily = u.keywords_daily;
        const ws = u.wordstat;
        const dailyStr = daily
          ? `${window.T?.kwToday || "Today"}: ${daily.used}/${daily.limit === 999999 ? "∞" : daily.limit}`
          : null;
        const wsStr =
          isRU && ws
            ? `${window.T?.kwSearchSource ? "Поиск" : "Wordstat"}: ${ws.used}/${ws.limit === 999999 ? "∞" : ws.limit}`
            : null;
        return [wsStr, dailyStr].filter(Boolean).join(" · ") || null;
      })(),
    ],
    analytics: [window.T?.analyticsTitle || "Analytics", null],
    comments: [window.T?.commentsTitle || "Comments", null],
    transcripts: [window.T?.navTranscripts || "Транскрипты", null],
    tags: [window.T?.navTags || "Теги", null],
    compare: [window.T?.compareTitle || "Compare", null],
    plans: [window.T?.navPlans || "Plans", null],
    settings: [window.T?.navSettings || "Настройки", null],
  };
  const [t, _sub] = titleByPage[page] || [page, null];
  const sub =
    page === "analysis" && window._analysisUsage
      ? (() => {
          const u = window._analysisUsage;
          const runsInf = u.runs?.limit === 999999;
          const videosInf = u.videos_per_run === 999999;
          const runsStr = `${window.T?.quotaRuns || "Ранов"}: ${u.runs?.used != null ? u.runs.used + " / " : ""}${runsInf ? "∞" : u.runs?.limit}`;
          const vidStr = `${window.T?.quotaVideos || "Видео/ран"}: ${videosInf ? "∞" : u.videos_per_run}`;
          return runsStr + "  ·  " + vidStr;
        })()
      : _sub;

  const handleViewResults = () => setPage("results");

  // Дропдаун OAuth-каналов — показываем если подключено 2+ канала
  const ChannelSwitcher = () => {
    if (oauthChannels.length < 2) return null;
    return (
      <select
        className="select"
        value={activeChannel?.channel_id || "all"}
        onChange={(e) => {
          const val = e.target.value;
          if (val === "all") {
            setActiveChannel(null);
          } else {
            const ch = oauthChannels.find((c) => c.channel_id === val);
            setActiveChannel(ch || null);
          }
        }}
        style={{ height: 28, fontSize: 12, width: 190 }}
        title="Active channel"
      >
        <option value="all">
          {window.T?.resultsAllChannels || "Все каналы"}
        </option>
        {oauthChannels.map((ch) => (
          <option key={ch.channel_id} value={ch.channel_id}>
            {ch.channel_name}
          </option>
        ))}
      </select>
    );
  };

  if (!authed) {
    return (
      <>
        <LoginScreen
          onLogin={(user, isNewUser) => {
            setAuthed(true);
            if (isNewUser) {
              setTimeout(
                () => toast("Welcome! Your account has been created. 🎉", "ok"),
                300,
              );
            } else {
              setTimeout(() => toast("Welcome back!", "ok"), 300);
            }
          }}
        />
        <TweaksUI tweaks={tweaks} setTweak={setTweak} />
      </>
    );
  }

  return (
    <>
      <div className="app">
        <Sidebar
          page={page}
          setPage={(p) => {
            setPage(p);
          }}
          collapsed={false}
          userProfile={userProfile}
          onLogout={async () => {
            await window.supabaseClient.auth.signOut();
            setAuthed(false);
            setUserId(null);
            toast("Signed out successfully.", "ok");
          }}
          onLogoClick={() => {
            setPage("analysis");
            setRunState("idle");
            setRunLog([]);
            setRunProgress(0);
          }}
          onThemeToggle={() =>
            setTweak("theme", tweaks.theme === "light" ? "dark" : "light")
          }
          isDark={tweaks.theme === "dark"}
        />
        <main className="main">
          {teamInfo && <TeamMemberBanner ownerName={teamInfo.owner_name} />}
          <Topbar
            title={t}
            subtitle={sub}
            right={
              <>
                <ChannelSwitcher />

                {(() => {
                  const h = window.location.hostname;
                  const isStage =
                    !h.includes("youna-ru") &&
                    !h.includes("younalyse-en") &&
                    !h.includes("youna.ru") &&
                    !h.includes("youna.app") &&
                    !h.includes("younalyse.com");
                  if (!isStage) return null;
                  const currentMode = window.PRODUCT_MODE || "ru";
                  return (
                    <div className="segmented" style={{ fontSize: 11 }}>
                      {["ru", "en"].map((m) => (
                        <button
                          key={m}
                          className={currentMode === m ? "active" : ""}
                          onClick={() => {
                            localStorage.setItem("youna_product_mode", m);
                            window.location.reload();
                          }}
                          style={{ padding: "0 8px", minWidth: 36 }}
                        >
                          {m === "ru" ? "🇷🇺 RU" : "🌍 EN"}
                        </button>
                      ))}
                    </div>
                  );
                })()}

                {(() => {
                  const tier = userProfile?.subscription_tier;
                  const daysLeft = getTrialDaysLeft(userProfile?.trial_ends_at);
                  const isOnTrial =
                    userProfile?.trial_ends_at &&
                    tier !== "superadmin" &&
                    !["pro", "producer", "studio"].includes(tier);
                  if (tier === "expired" || (isOnTrial && daysLeft === 0)) {
                    return (
                      <button
                        className="btn sm danger"
                        style={{ fontWeight: 600 }}
                        onClick={() => setPage("plans")}
                      >
                        {window.T?.trialExpiredBadge ||
                          "Триал истёк · Выбрать план"}
                      </button>
                    );
                  }
                  if (isOnTrial && daysLeft > 0) {
                    return (
                      <button
                        className="btn sm"
                        style={{
                          background: "var(--accent-soft)",
                          border: "1px solid var(--accent)",
                          color: "var(--accent)",
                          fontWeight: 600,
                        }}
                        onClick={() => setPage("plans")}
                      >
                        {window.T?.trialActiveBadge
                          ? window.T.trialActiveBadge.replace("{n}", daysLeft)
                          : `Триал · ${daysLeft} дн · Upgrade`}
                      </button>
                    );
                  }
                  return null;
                })()}
              </>
            }
          />
          <div className="scroll-area">
            {page === "analysis" && (
              <AnalysisScreen
                onRun={startRun}
                userId={userId}
                userProfile={userProfile}
                runState={runState}
                runLog={runLog}
                runProgress={runProgress}
                onStop={stopRun}
                onViewResults={handleViewResults}
                onNewAnalysis={() => {
                  setRunState("idle");
                  setRunLog([]);
                  setRunProgress(0);
                }}
              />
            )}
            {page === "plans" && (
              <PlansScreen userProfile={userProfile} userId={userId} />
            )}
            {page === "results" && (
              <ResultsScreen
                results={results}
                userId={userId}
                showHidden={showHidden}
                onToggleHidden={(val) => {
                  setShowHidden(val);
                  fetchResults(userId, val);
                }}
                onOpen={setOpenVideo}
                density={tweaks.density}
                userProfile={userProfile}
                selectedRunFilter={selectedRunFilter}
                onRunFilterChange={(runId) =>
                  setSelectedRunFilter(runId || null)
                }
                onClearAllFilters={() => {
                  setSelectedRunFilter(null);
                  fetchResults(userId);
                }}
                activeChannel={activeChannel}
                onToast={toast}
              />
            )}
            {page === "keywords" && (
              <KeywordsScreen
                userId={userId}
                userProfile={userProfile}
                activeChannel={activeChannel}
              />
            )}
            {page === "comments" && (
              <CommentsScreen
                userId={userId}
                activeChannel={activeChannel}
                onOpenVideo={setOpenVideo}
                allResults={results}
                onToast={toast}
              />
            )}
            {page === "transcripts" && (
              <TranscriptsScreen
                userId={userId}
                activeChannel={activeChannel}
                onOpenVideo={setOpenVideo}
                allResults={results}
                onToast={toast}
              />
            )}
            {page === "tags" && <TagsScreen userId={userId} onToast={toast} />}
            {page === "analytics" && (
              <AnalyticsScreen userId={userId} activeChannel={activeChannel} />
            )}
            {page === "compare" && (
              <CompareScreen
                userId={userId}
                userProfile={userProfile}
                oauthChannels={oauthChannels}
              />
            )}
            {page === "settings" && (
              <SettingsScreen
                tweaks={tweaks}
                setTweak={setTweak}
                userId={userId}
                userProfile={userProfile}
              />
            )}
            {page === "admin" && <AdminDashboardScreen userId={userId} />}
          </div>
        </main>
      </div>
      <MobileNav page={page} setPage={setPage} />
      {openVideo && (
        <DetailOverlay
          video={openVideo}
          allResults={results}
          userId={userId}
          onClose={() => setOpenVideo(null)}
          onPrev={openPrev}
          onNext={openNext}
        />
      )}
      <TweaksUI tweaks={tweaks} setTweak={setTweak} />
    </>
  );
};

const TweaksUI = ({ tweaks, setTweak }) => (
  <TweaksPanel title="Tweaks">
    {/* Переключатель продукта — только на стейдже (index.html) */}
    {typeof window !== "undefined" && window.localStorage && (
      <TweakSection title="Product (Stage only)">
        <TweakRadio
          label="Mode"
          value={window.PRODUCT_MODE || "ru"}
          onChange={(v) => {
            localStorage.setItem("youna_product_mode", v);
            window.location.reload();
          }}
          options={["ru", "en"]}
        />
      </TweakSection>
    )}
    <TweakSection title="Appearance">
      <TweakRadio
        label="Theme"
        value={tweaks.theme}
        onChange={(v) => setTweak("theme", v)}
        options={["light", "dark"]}
      />
      <TweakColor
        label="Accent"
        value={tweaks.accent}
        onChange={(v) => setTweak("accent", v)}
        options={["#2563EB", "#7C3AED", "#059669", "#E11D48"]}
      />
    </TweakSection>
    <TweakSection title="Tables">
      <TweakSelect
        label="Density"
        value={tweaks.density}
        onChange={(v) => setTweak("density", v)}
        options={["compact", "normal", "comfortable"]}
      />
    </TweakSection>
    <TweakSection title="Layout">
      <TweakToggle
        label="Show mobile artboards"
        value={tweaks.showMobile}
        onChange={(v) => setTweak("showMobile", v)}
      />
    </TweakSection>
  </TweaksPanel>
);

const Root = () => {
  const tweakHook = useTweaks(TWEAK_DEFAULTS);
  const tweaks = tweakHook[0];
  React.useEffect(() => {
    document.documentElement.setAttribute("data-theme", tweaks.theme);
  }, [tweaks.theme]);
  return (
    <ToastProvider>
      <App tweaks={tweaks} setTweak={tweakHook[1]} />
    </ToastProvider>
  );
};

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