import React, { useEffect } from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route, Navigate, useLocation } from "react-router-dom";
import "./pdf-text-layer.css";
import { AuthProvider, useAuth } from "./components/AuthContext.jsx";
import { BrandProvider } from "./components/BrandContext.jsx";
import { PlanProvider } from "./components/PlanContext.jsx";
import { ThemeModeProvider } from "./theme.jsx";
import DashboardPage from "./pages/DashboardPage.jsx";
import SignPage from "./pages/SignPage.jsx";
import AdminPage from "./pages/AdminPage.jsx";
import AdminPanelPage from "./pages/AdminPanelPage.jsx";
import LandingPage from "./pages/LandingPage.jsx";
import PricingPage from "./pages/PricingPage.jsx";
import UpgradePage from "./pages/UpgradePage.jsx";
import UpgradeSuccessPage from "./pages/UpgradeSuccessPage.jsx";
import TeamAcceptPage from "./pages/TeamAcceptPage.jsx";
import CardsPage from "./pages/CardsPage.jsx";
import CardEditorPage from "./pages/CardEditorPage.jsx";
import PublicCardPage from "./pages/PublicCardPage.jsx";
import QuotesPage from "./pages/QuotesPage.jsx";
import QuoteEditorPage from "./pages/QuoteEditorPage.jsx";
import PublicQuotePage from "./pages/PublicQuotePage.jsx";
import VerifyPage from "./pages/VerifyPage.jsx";
import HelpPage from "./pages/HelpPage.jsx";
import AccessibilityPage from "./pages/AccessibilityPage.jsx";
import PrivacyPage from "./pages/PrivacyPage.jsx";
import TermsPage from "./pages/TermsPage.jsx";
import BlogIndexPage from "./pages/BlogIndexPage.jsx";
import BlogPostPage from "./pages/BlogPostPage.jsx";
import AdminBlogPage from "./pages/AdminBlogPage.jsx";
import PublicSignPage from "./pages/PublicSignPage.jsx";
import DigitalSignaturePage from "./pages/DigitalSignaturePage.jsx";
import QuotesToolPage from "./pages/QuotesToolPage.jsx";
import BusinessCardsPage from "./pages/BusinessCardsPage.jsx";
import AudiencePage from "./pages/audiences/AudiencePage.jsx";
import AudiencesHubPage from "./pages/audiences/AudiencesHubPage.jsx";
import { AUDIENCE_SLUGS } from "../shared/audiences.js";
import AccessibilityWidget from "./components/AccessibilityWidget.jsx";
import CookieBanner from "./components/CookieBanner.jsx";

// Domain migration: legacy domain redirects permanently to new branded domain.
// We do this at the top of main.jsx so the redirect happens before any React
// render, login, or API call - preventing flicker and broken state.
const HOSTNAME = window.location.hostname;
const LEGACY_HOSTS = ["beta-pdf.pages.dev", "pdf-signer.pages.dev"];
const NEW_DOMAIN = "https://chik-app.com";
if (LEGACY_HOSTS.includes(HOSTNAME)) {
  // Preserve path + query so deep links keep working after redirect.
  const target = NEW_DOMAIN + window.location.pathname + window.location.search + window.location.hash;
  window.location.replace(target);
  // Don't render anything during the redirect - prevents flash of old domain
  throw new Error("Redirecting to chik-app.com");
}

// Google OAuth callback handler. After Google redirects back to us, the
// server endpoint /api/auth/google/callback returns an HTML page that
// redirects here with one of these in the URL hash:
//   #google_auth=<token>          - normal login, no 2FA
//   #google_totp_pending=<token>&email=<email> - user has 2FA, prompt for TOTP
// The hash never reaches server logs (browser doesn't send it). We pull it
// out, store/forward as appropriate, and clean up the URL.
(function handleGoogleAuth() {
  const hash = window.location.hash || "";
  if (!hash.includes("google_auth=") && !hash.includes("google_totp_pending=")) return;
  const hashParams = new URLSearchParams(hash.replace(/^#/, ""));

  // 2FA path: user has TOTP enabled, server gave us a pending token instead
  // of a full session. Stash it so LoginPage can prompt for the TOTP code.
  const totpPending = hashParams.get("google_totp_pending");
  const totpEmail = hashParams.get("email");
  if (totpPending && totpEmail) {
    try {
      sessionStorage.setItem("google_totp_pending", JSON.stringify({
        tempToken: totpPending,
        email: totpEmail,
        // 10 minute server-side TTL; track createdAt so the UI can warn if expired.
        createdAt: Date.now(),
      }));
    } catch {}
    // Strip the hash and redirect to /login where the TOTP modal will detect
    // sessionStorage and open automatically.
    window.history.replaceState({}, "", "/login");
    return;
  }

  // Normal path: server gave us a session token. Behave like a regular login.
  const token = hashParams.get("google_auth");
  if (!token) return;
  try {
    localStorage.setItem("auth_token", token);
  } catch {}
  // Strip the hash so the token doesn't stay in the browser history or get
  // bookmarked accidentally.
  const cleanUrl = window.location.pathname + window.location.search;
  window.history.replaceState({}, "", cleanUrl);
})();

// Landed-on-/ logic: logged-in users go to dashboard, otherwise see the landing.
// Tracks page_view events for SPA navigation. Without this, GA4 only sees
// the initial page load - all subsequent React Router navigations are
// invisible. We fire page_view manually on every route change.
//
// Why setTimeout 0: react-router updates the URL before the new page has
// a chance to set its document.title via useEffect. We defer by one tick
// so the title is current when we read it.
function GA4RouteTracker() {
  const location = useLocation();
  useEffect(() => {
    if (typeof window.gtag !== "function") return;
    const t = setTimeout(() => {
      window.gtag("event", "page_view", {
        page_path: location.pathname + location.search,
        page_title: document.title,
        page_location: window.location.href,
      });
    }, 0);
    return () => clearTimeout(t);
  }, [location]);
  return null;
}

function RootRoute() {
  const { user, loading } = useAuth();
  if (loading) return null;
  return user ? <Navigate to="/dashboard" replace /> : <LandingPage />;
}

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <ThemeModeProvider>
      <AuthProvider>
        <PlanProvider>
          <BrandProvider>
            <BrowserRouter>
              <GA4RouteTracker />
              <Routes>
                <Route path="/" element={<RootRoute />} />
                <Route path="/pricing" element={<PricingPage />} />
                <Route path="/upgrade" element={<UpgradePage />} />
                <Route path="/upgrade/success" element={<UpgradeSuccessPage />} />
                <Route path="/login" element={<Navigate to="/" replace />} />
                <Route path="/dashboard" element={<DashboardPage />} />
                <Route path="/new" element={<Navigate to="/dashboard?tab=new" replace />} />
                <Route path="/sign/:sessionId/:token" element={<SignPage />} />
                <Route path="/admin/:sessionId" element={<AdminPage />} />
                <Route path="/admin-panel" element={<AdminPanelPage />} />
                <Route path="/panel" element={<Navigate to="/admin-panel" replace />} />
                <Route path="/team/accept" element={<TeamAcceptPage />} />
                <Route path="/cards" element={<CardsPage />} />
                <Route path="/cards/:cardId/edit" element={<CardEditorPage />} />
                <Route path="/c/:slug" element={<PublicCardPage />} />
                <Route path="/quotes" element={<QuotesPage />} />
                <Route path="/quotes/:quoteId/edit" element={<QuoteEditorPage />} />
                <Route path="/q/:slug" element={<PublicQuotePage />} />
                <Route path="/s/:slug" element={<PublicSignPage />} />
                <Route path="/verify" element={<VerifyPage />} />
                {/* Legacy /verify/:id (by-id, DB-flag verification) was removed; verification is upload-only. Redirect old links to the upload page. */}
                <Route path="/verify/:sessionId" element={<Navigate to="/verify" replace />} />
                <Route path="/help" element={<HelpPage />} />
                <Route path="/privacy" element={<PrivacyPage />} />
                <Route path="/terms" element={<TermsPage />} />
                <Route path="/accessibility" element={<AccessibilityPage />} />
                <Route path="/blog" element={<BlogIndexPage />} />
                <Route path="/blog/:slug" element={<BlogPostPage />} />
                <Route path="/admin-panel/blog" element={<AdminBlogPage />} />
                <Route path="/digital-signature" element={<DigitalSignaturePage />} />
                <Route path="/quotes-tool" element={<QuotesToolPage />} />
                <Route path="/business-cards" element={<BusinessCardsPage />} />
                <Route path="/solutions" element={<AudiencesHubPage />} />
                {AUDIENCE_SLUGS.map((slug) => (
                  <Route key={slug} path={`/${slug}`} element={<AudiencePage slug={slug} />} />
                ))}
                <Route path="*" element={<Navigate to="/" replace />} />
              </Routes>
              <AccessibilityWidget />
              <CookieBanner />
            </BrowserRouter>
          </BrandProvider>
        </PlanProvider>
      </AuthProvider>
    </ThemeModeProvider>
  </React.StrictMode>
);

// Register the PWA service worker (production only - the dev server doesn't
// serve /sw.js the same way, and caching during dev is confusing). This makes
// the app installable and gives a fast offline-capable shell. The SW itself
// never caches API responses or PDFs - see public/sw.js.
if ("serviceWorker" in navigator && import.meta.env.PROD) {
  window.addEventListener("load", () => {
    navigator.serviceWorker.register("/sw.js").catch((err) => {
      console.warn("Service worker registration failed:", err);
    });
  });
}