import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { TamaguiProvider } from "tamagui";
import "./index.css";
import App from "./App.tsx";
import tamaguiConfig from "./themes/tamagui.config";
import { i18nReady } from "./i18n";
import { initMessageListener } from "@/services/messageListener";
import { initSentry } from "@/config/sentry";
import { registerAllFlows } from "@/flows";
import { withBase, getStorageKey } from "@/utils/env";

/**
 * 发版后旧 hash chunk 失效的兜底：懒加载 chunk（或其 CSS 依赖）拉取失败时，
 * Vite 注入的 preload helper 会派发 vite:preloadError（仅生产构建存在，dev 不触发），
 * 此时整页刷新拉取新 HTML 即可拿到新 hash 的资源。
 * 60s 内只自动刷新一次，避免 CDN 未同步等场景下的刷新死循环；
 * 二次失败不 preventDefault，让错误照常抛给路由 ErrorBoundary 与 Sentry。
 */
const PRELOAD_ERROR_RELOAD_KEY = getStorageKey("preload_error_reload_at");
window.addEventListener("vite:preloadError", event => {
  const last = Number(sessionStorage.getItem(PRELOAD_ERROR_RELOAD_KEY) ?? 0);
  if (Date.now() - last < 60_000) return;
  sessionStorage.setItem(PRELOAD_ERROR_RELOAD_KEY, String(Date.now()));
  event.preventDefault();
  window.location.reload();
});

/**
 * 启用 API mock(MSW,仅 dev 且 VITE_ENABLE_MOCK=true 时)
 *
 * 生产构建中 import.meta.env.DEV 被静态替换为 false,整段连同 src/mocks/ 被消除。
 * worker 就绪后才继续启动,保证首批请求也能被拦截;启动失败不阻塞应用(请求走真实后端)。
 */
async function enableMocking() {
  if (!import.meta.env.DEV || import.meta.env.VITE_ENABLE_MOCK !== "true") {
    return;
  }
  try {
    const { worker } = await import("@/mocks/browser");
    await worker.start({
      onUnhandledRequest: "bypass",
      serviceWorker: { url: withBase("/mockServiceWorker.js") },
    });
  } catch (error) {
    console.error("[Mock] Failed to start MSW worker:", error);
  }
}

enableMocking().then(() => {
  // 初始化 Sentry 错误监控
  initSentry();

  // 注册所有 Flow
  registerAllFlows();

  initMessageListener();

  const root = createRoot(document.getElementById("root")!);

  i18nReady.finally(() => {
    root.render(
      <StrictMode>
        <TamaguiProvider config={tamaguiConfig}>
          <App />
        </TamaguiProvider>
      </StrictMode>
    );
  });
});
