/* ============================================================
   AfricaMart — App shell & router
   ============================================================ */

// Catches JS errors in any child tree so one broken component
// can't crash the entire SPA.
class ErrorBoundary extends React.Component {
  constructor(props) { super(props); this.state = { error: null }; }
  static getDerivedStateFromError(err) { return { error: err }; }
  componentDidCatch(err, info) { console.error("[AfricaMart] Uncaught error:", err, info); }
  render() {
    if (!this.state.error) return this.props.children;
    return (
      <div style={{ padding: "80px 24px", textAlign: "center", fontFamily: "DM Sans, sans-serif" }}>
        <div style={{ fontSize: 40, marginBottom: 16 }}>⚠️</div>
        <h2 style={{ fontSize: 22, marginBottom: 8 }}>Something went wrong</h2>
        <p style={{ color: "#666", marginBottom: 24 }}>{this.state.error.message}</p>
        <button onClick={() => { this.setState({ error: null }); window.location.reload(); }}
          style={{ padding: "10px 24px", background: "#1a2e44", color: "#fff", border: "none", borderRadius: 8, cursor: "pointer", fontSize: 15 }}>
          Reload page
        </button>
      </div>
    );
  }
}

function computeSEO(route) {
  const { page, params = {} } = route;
  const base = { url: "/", title: "AfricaMart — Pan-African B2B Marketplace", description: "Source from verified suppliers across all 54 African countries. Steel, agriculture, construction, textiles and more.", ogType: "website" };
  if (page === "browse") return { ...base, url: "/browse" + (params.cat ? "/" + params.cat : ""), title: (params.cat ? AM.catById[params.cat].name + " — " : "") + "Browse products | AfricaMart", description: "Search and compare products from verified African suppliers. Filter by category, country, MOQ and price." };
  if (page === "suppliers") return { ...base, url: "/suppliers", title: "Verified suppliers across Africa | AfricaMart", description: "Discover vetted manufacturers, exporters and distributors across all 54 African countries." };
  if (page === "rfq") return { ...base, url: "/rfq", title: "RFQ Board — Request for Quotation | AfricaMart", description: "Post your sourcing requirements and receive quotes from verified suppliers across Africa." };
  if (page === "sell") return { ...base, url: "/sell", title: "Sell on AfricaMart — Start your online store in minutes", description: "Open a free storefront, list your products, and reach 118,000+ verified B2B buyers across Africa. Get started in minutes." };
  if (page === "company") {
    const COMPANY_SEO = {
      about: { title: "About AfricaMart | Pan-African B2B Marketplace", description: "AfricaMart is the pan-African B2B marketplace connecting verified suppliers and buyers across all 54 African countries." },
      "trust-safety": { title: "Trust & Safety | AfricaMart", description: "How AfricaMart helps buyers and suppliers trade safely — verification, ratings, secure communication and dispute support." },
      "trade-assurance": { title: "Trade Assurance | AfricaMart", description: "Trade with more confidence on AfricaMart — verified suppliers, transparent ratings, documented RFQ terms and dispute support." },
      help: { title: "Help Center | AfricaMart", description: "Answers to common questions for buyers and suppliers on AfricaMart, plus quick links to get started." },
      contact: { title: "Contact AfricaMart", description: "Get in touch with the AfricaMart team for general inquiries, trust & safety reports, or supplier support." },
    };
    const c = COMPANY_SEO[params.slug] || COMPANY_SEO.about;
    return { ...base, url: "/" + (params.slug || "about"), title: c.title, description: c.description };
  }
  if (page === "auth") return { ...base, url: routeToPath(route), title: (params.mode === "register" ? "Create account" : params.mode === "forgot" ? "Forgot password" : params.mode === "reset" ? "Reset password" : "Log in") + " | AfricaMart" };
  if (page === "dashboard") return { ...base, url: "/dashboard", title: ((params.role || "buyer") === "supplier" ? "Supplier" : "Buyer") + " dashboard | AfricaMart" };
  if (page === "store") {
    const s = AM.supplierBySlug[params.slug] || AM.SUPPLIERS[0];
    const c = AM.countryByCode[s.country];
    const isPremium = params.variant === "premium" || (params.variant !== "standard" && s.tier === "premium");
    if (isPremium) {
      // white-label: hides AfricaMart chrome for an own-branding preview,
      // but the page is still served (and indexed) at africamart.co —
      // SEO tags must canonicalize to the real URL, not a placeholder domain.
      return {
        url: "/supplier/" + s.slug, ogType: "profile",
        title: s.name + " — " + s.tags.slice(0, 2).join(", ") + " | " + c.name,
        description: s.bio.slice(0, 155),
        jsonld: { "@context": "https://schema.org", "@type": "Organization", name: s.name, address: { "@type": "PostalAddress", addressCountry: c.name }, aggregateRating: { "@type": "AggregateRating", ratingValue: s.rating, reviewCount: s.reviews }, makesOffer: s.tags },
      };
    }
    return {
      url: "/supplier/" + s.slug, ogType: "profile",
      title: s.name + " — " + (s.kind === "service" ? (s.serviceType + " service provider") : "Supplier") + " on AfricaMart | " + c.name,
      description: s.bio.slice(0, 155),
      jsonld: { "@context": "https://schema.org", "@type": s.kind === "service" ? "ProfessionalService" : "Organization", name: s.name, address: { "@type": "PostalAddress", addressCountry: c.name }, aggregateRating: { "@type": "AggregateRating", ratingValue: s.rating, reviewCount: s.reviews }, makesOffer: s.tags },
    };
  }
  if (page === "product") {
    const p = AM.productBySlug[params.slug] || AM.PRODUCTS[0];
    const s = AM.supplierById[p.supplier] || AM.SUPPLIERS[0];
    return {
      url: "/product/" + p.slug, ogType: "product",
      title: p.name + " — " + s.name + " | AfricaMart",
      description: p.desc.slice(0, 155),
      jsonld: { "@context": "https://schema.org", "@type": "Product", name: p.name, sku: p.sku, category: AM.catById[p.cat].name, brand: { "@type": "Brand", name: s.name }, offers: { "@type": "Offer", price: p.priceUSD, priceCurrency: "USD", availability: "https://schema.org/InStock", eligibleQuantity: { "@type": "QuantitativeValue", minValue: p.moq, unitText: p.moqUnit } } },
    };
  }
  return base;
}

// ── Client-side routing (path <-> {page, params}) ──────────────
// Maps a route to the URL shown in the address bar.
function routeToPath(route) {
  const { page, params = {} } = route;
  if (page === "home") return "/";
  if (page === "browse") return "/browse" + (params.cat ? "/" + params.cat : "");
  if (page === "suppliers") return "/suppliers";
  if (page === "rfq") return "/rfq";
  if (page === "sell") return "/sell";
  if (page === "company") return "/" + (params.slug || "about");
  if (page === "dashboard") return "/dashboard";
  if (page === "store") return "/supplier/" + params.slug;
  if (page === "product") return "/product/" + params.slug;
  if (page === "auth") {
    const mode = params.mode || "login";
    if (mode === "register") return params.role === "supplier" ? "/register/supplier" : "/register";
    if (mode === "forgot") return "/forgot-password";
    if (mode === "reset") return "/reset-password";
    return "/login";
  }
  return "/";
}

// Maps the current address-bar path to a {page, params} route.
function routeFromPath(pathname) {
  const parts = (pathname || "/").split("/").filter(Boolean);
  if (parts.length === 0) return { page: "home", params: {} };
  switch (parts[0]) {
    case "browse": return { page: "browse", params: (parts[1] && AM.catById[parts[1]]) ? { cat: parts[1] } : {} };
    case "suppliers": return { page: "suppliers", params: {} };
    case "rfq": return { page: "rfq", params: {} };
    case "sell": return { page: "sell", params: {} };
    case "about": return { page: "company", params: { slug: "about" } };
    case "trust-safety": return { page: "company", params: { slug: "trust-safety" } };
    case "trade-assurance": return { page: "company", params: { slug: "trade-assurance" } };
    case "help": return { page: "company", params: { slug: "help" } };
    case "contact": return { page: "company", params: { slug: "contact" } };
    case "dashboard": return { page: "dashboard", params: {} };
    case "login": return { page: "auth", params: { mode: "login" } };
    case "register": return { page: "auth", params: { mode: "register", role: parts[1] === "supplier" ? "supplier" : "buyer" } };
    case "forgot-password": return { page: "auth", params: { mode: "forgot" } };
    case "reset-password": return { page: "auth", params: { mode: "reset" } };
    case "product": return parts[1] ? { page: "product", params: { slug: parts[1] } } : { page: "home", params: {} };
    case "supplier": return parts[1] ? { page: "store", params: { slug: parts[1] } } : { page: "home", params: {} };
    case "store": return parts[1] ? { page: "store", params: { slug: parts[1] } } : { page: "home", params: {} }; // legacy
    default: return { page: "home", params: {} };
  }
}

function applySEO(seo) {
  document.title = seo.title;
  const root = "https://africamart.co";
  const set = (sel, attr, val) => { let el = document.head.querySelector(sel); if (el) el.setAttribute(attr, val); };
  set('meta[name="description"]', "content", seo.description);
  set('link[rel="canonical"]', "href", root + seo.url);
  set('meta[property="og:title"]', "content", seo.title);
  set('meta[property="og:description"]', "content", seo.description);
  set('meta[property="og:url"]', "content", root + seo.url);
  set('meta[property="og:type"]', "content", seo.ogType || "website");
  const ld = document.getElementById("ld-json");
  if (ld) ld.textContent = seo.jsonld ? JSON.stringify(seo.jsonld) : "";
}

// Loads the signed-in buyer's saved items into the shared SavedItems store
// (no-op for supplier accounts — saved_items is keyed off buyers.id)
async function initSavedItems(user, roleOverride) {
  if (!window.SavedItems) return;
  const role = roleOverride || (user.user_metadata || {}).role || "buyer";
  if (role !== "buyer" || !DB.auth) { window.SavedItems.init(null); return; }
  try {
    const buyer = await DB.auth.ensureBuyerRecord(user);
    window.SavedItems.init(buyer.id);
  } catch (e) {
    window.SavedItems.init(null);
  }
}

function App() {
  const [route, setRoute] = useState(() => routeFromPath(window.location.pathname));
  const [currency, setCurrency] = useState("USD");
  const [auth, setAuth] = useState(null);
  const [toastNode, showToast] = useToast();

  const nav = (page, params = {}) => {
    setRoute({ page, params });
    const path = routeToPath({ page, params });
    if (path !== window.location.pathname) window.history.pushState(null, "", path);
    window.scrollTo({ top: 0, behavior: "instant" });
  };

  // ── Sync route with browser back/forward navigation ───────────
  useEffect(() => {
    const onPopState = () => setRoute(routeFromPath(window.location.pathname));
    window.addEventListener("popstate", onPopState);
    return () => window.removeEventListener("popstate", onPopState);
  }, []);

  // ── Restore session on mount + listen for auth changes ───────
  useEffect(() => {
    if (!window.supabaseClient) return;

    // Restore existing session (e.g. after Google OAuth redirect)
    DB.auth.getSession().then(session => {
      if (session?.user) { setAuth(DB.auth.buildAuthState(session.user)); initSavedItems(session.user); }
    }).catch(() => {});

    // Listen for sign-in / sign-out events
    const { data: { subscription } } = DB.auth.onAuthStateChange((event, session) => {
      if (event === "SIGNED_IN" && session?.user) {
        // Email/password sign-in & sign-up are handled by afterSignIn() in
        // auth.page.jsx (it already sets auth, creates the profile row, and
        // redirects). Google OAuth has no such caller — its flow round-trips
        // through a full-page redirect, so handle it here instead.
        if (session.user.app_metadata?.provider === "google") {
          const meta = session.user.user_metadata || {};
          const cameFromAuthPage = route.page === "auth";
          const intendedRole = meta.role || (cameFromAuthPage && route.params.role) || "buyer";

          (async () => {
            try {
              // First sign-in via Google has no role in user_metadata yet — set it
              // based on where the user started (e.g. supplier via "Sell" CTA).
              if (!meta.role) await DB.auth.updateUser({ data: { role: intendedRole } });
              if (intendedRole === "supplier") await DB.auth.ensureSupplierRecord(session.user);
              else await DB.auth.ensureBuyerRecord(session.user);
            } catch (e) {
              console.warn("[AfricaMart] Could not set up profile after sign-in:", e.message);
            }
            const authState = DB.auth.buildAuthState(session.user);
            setAuth({ ...authState, role: intendedRole });
            initSavedItems(session.user, intendedRole);
            if (cameFromAuthPage) {
              nav("dashboard", { role: intendedRole });
              showToast("Welcome" + (authState.name ? ", " + authState.name.split(" ")[0] : "") + "!");
            }
          })();
          return;
        }

        setAuth(DB.auth.buildAuthState(session.user));
        initSavedItems(session.user);
      }
      if (event === "SIGNED_OUT") {
        setAuth(null);
        if (window.SavedItems) window.SavedItems.init(null);
      }
      if (event === "PASSWORD_RECOVERY") {
        nav("auth", { mode: "reset" });
      }
    });

    return () => subscription.unsubscribe();
  }, []);

  const seo = useMemo(() => computeSEO(route), [route]);
  useEffect(() => { applySEO(seo); if (window.lucide) window.lucide.createIcons(); }, [seo]);

  const isFull = route.page === "auth"; // auth has its own full layout (no footer)
  const P = route.params;

  // ----- storefront variant: premium (white-label) vs standard -----
  const storeSupplier = route.page === "store" ? (AM.supplierBySlug[P.slug] || AM.SUPPLIERS[0]) : null;
  const storeVariant = storeSupplier
    ? (P.variant === "premium" || (P.variant !== "standard" && storeSupplier.tier === "premium") ? "premium" : "standard")
    : null;
  const whiteLabel = storeVariant === "premium"; // hides ALL AfricaMart chrome

  return (
    <>
      {!whiteLabel && <Navbar nav={nav} route={route} currency={currency} setCurrency={setCurrency} auth={auth} onSignOut={async () => {
        if (window.supabaseClient) { try { await DB.auth.signOut(); } catch (e) {} }
        setAuth(null); nav("home"); showToast("Signed out");
      }} />}
      <main key={route.page + JSON.stringify(P)}>
        {route.page === "home" && <HomePage nav={nav} currency={currency} showToast={showToast} />}
        {route.page === "browse" && <BrowsePage nav={nav} currency={currency} params={P} showToast={showToast} />}
        {route.page === "suppliers" && <SuppliersPage nav={nav} showToast={showToast} />}
        {route.page === "store" && (storeSupplier.kind === "service"
          ? (storeVariant === "premium"
              ? <PremiumServiceStorePage nav={nav} params={P} showToast={showToast} />
              : <ServiceStorePage nav={nav} params={P} showToast={showToast} />)
          : (storeVariant === "premium"
              ? <PremiumStorePage nav={nav} currency={currency} params={P} showToast={showToast} />
              : <StorePage nav={nav} currency={currency} params={P} showToast={showToast} />))}
        {route.page === "product" && <ProductPage nav={nav} currency={currency} params={P} showToast={showToast} />}
        {route.page === "rfq" && <RFQPage nav={nav} showToast={showToast} />}
        {route.page === "sell" && <SellPage nav={nav} showToast={showToast} />}
        {route.page === "company" && <CompanyPage nav={nav} params={P} showToast={showToast} />}
        {route.page === "auth" && <AuthPage nav={nav} params={P} onAuth={setAuth} showToast={showToast} />}
        {route.page === "dashboard" && <DashboardPage nav={nav} showToast={showToast} />}
      </main>
      {!isFull && route.page !== "dashboard" && !whiteLabel && <Footer nav={nav} />}
      {!whiteLabel && <SEOInspector seo={seo} />}
      {route.page === "store" && P.variant && <StorePreviewSwitch supplier={storeSupplier} variant={storeVariant} nav={nav} />}
      {toastNode}
    </>
  );
}

function mountApp() {
  const loader = document.getElementById("am-loader");
  if (loader) loader.remove();
  ReactDOM.createRoot(document.getElementById("root")).render(
    <ErrorBoundary><App /></ErrorBoundary>
  );
}

// If data-loader already finished before this script ran, mount now.
// Otherwise wait for the "am:ready" event it fires.
if (window.AM_READY) {
  mountApp();
} else {
  document.addEventListener("am:ready", mountApp, { once: true });
}
