"use client";

// src/components/shell/product-context.tsx
import * as React3 from "react";
import { useTheme } from "next-themes";
import { useLocation } from "react-router-dom";
import {
  useAppStore,
  getActiveCustomProductBrand,
  hasConfiguredCustomProducts,
  isListedCustomProduct
} from "@exxatdesignux/product-framework/app-store";
import {
  brandForProduct,
  EXXAT_ONE_SCHOOLS_BRAND,
  EXXAT_ONE_SITES_BRAND,
  EXXAT_PRISM_BRAND
} from "@exxatdesignux/product-framework/product-brand";
import { brandColorsEquivalent } from "@exxatdesignux/product-framework/brand-color-match";
import { normalizeBrandAccentColor } from "@exxatdesignux/product-framework/brand-accent-color";
import { resolveProductFromPath } from "@exxatdesignux/product-framework/product-routing";
import { listRegisteredProducts } from "@exxatdesignux/product-framework/product-registry";
import { ensureShippedCatalogLoaded as ensureShippedCatalogLoaded2 } from "@exxatdesignux/product-framework/tenant-products/shipped-catalog";
import { hydrateTenantProducts } from "@exxatdesignux/product-framework/tenant-products/hydrate";

// src/components/shell/product-authoring-context.tsx
import * as React2 from "react";
import {
  isPlatformCreatorWorkspace,
  setRuntimeProductAuthoring
} from "@exxatdesignux/product-framework/product-authoring-gate";
import {
  isProductAuthoringEnabled,
  isProductAuthoringRuntimeAllowed
} from "@exxatdesignux/product-framework/product-authoring";

// src/components/shell/builder-dev-sync.tsx
import * as React from "react";
import { ensureShippedCatalogLoaded } from "@exxatdesignux/product-framework/tenant-products/shipped-catalog";
import {
  isBuilderDevSyncEnvironment,
  startBuilderDevSync
} from "@exxatdesignux/product-framework/tenant-products/builder-dev-sync";
function BuilderDevSync() {
  const authoring = useProductAuthoringEnabled();
  React.useEffect(() => {
    if (!authoring || !isBuilderDevSyncEnvironment()) return;
    let stop = () => {
    };
    void ensureShippedCatalogLoaded().finally(() => {
      stop = startBuilderDevSync();
    });
    return () => stop();
  }, [authoring]);
  return null;
}

// src/components/shell/product-authoring-context.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var ProductAuthoringContext = React2.createContext(
  void 0
);
function ProductAuthoringProvider({
  enabled,
  children
}) {
  const resolved = React2.useMemo(
    () => resolveProductAuthoring(enabled),
    [enabled]
  );
  React2.useEffect(() => {
    setRuntimeProductAuthoring(enabled === void 0 ? null : enabled);
    return () => setRuntimeProductAuthoring(null);
  }, [enabled]);
  return /* @__PURE__ */ jsxs(ProductAuthoringContext.Provider, { value: resolved, children: [
    /* @__PURE__ */ jsx(BuilderDevSync, {}),
    children
  ] });
}
function resolveProductAuthoring(explicit) {
  if (explicit !== void 0) return explicit;
  if (!isProductAuthoringRuntimeAllowed()) return false;
  return isProductAuthoringEnabled();
}
function useProductAuthoringEnabled() {
  const ctx = React2.useContext(ProductAuthoringContext);
  if (ctx !== void 0) return ctx;
  if (!isProductAuthoringRuntimeAllowed()) return false;
  return isProductAuthoringEnabled();
}

// src/components/shell/product-context.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
var PRODUCT_THEME_CLASSES = [
  "theme-one",
  "theme-lavender",
  "theme-prism",
  "theme-rose",
  "theme-custom"
];
var DEFAULT_PRODUCT_ACCENT = {
  "exxat-prism": EXXAT_PRISM_BRAND.brandColor,
  "exxat-one-schools": EXXAT_ONE_SCHOOLS_BRAND.brandColor,
  "exxat-one-sites": EXXAT_ONE_SITES_BRAND.brandColor,
  // Custom has no fixed default accent — its colour is whatever the tenant
  // configured in Settings → Appearance → Add product. Treat any override
  // value as a real override (we always want `theme-custom` chrome here).
  "exxat-custom": ""
};
function accentOverrideActive(product, override) {
  if (!override?.trim()) return false;
  const defaultAccent = DEFAULT_PRODUCT_ACCENT[product]?.trim();
  if (!defaultAccent) return true;
  return !brandColorsEquivalent(override, defaultAccent);
}
function resolveProductThemeClass(product, productBrandColors) {
  const hasAccentOverride = accentOverrideActive(product, productBrandColors[product]);
  if (product === "exxat-custom" || hasAccentOverride) return "theme-custom";
  if (product === "exxat-one-schools" || product === "exxat-one-sites") return "theme-one";
  return "theme-prism";
}
function resolveThemeContext(product, customProducts, activeCustomIndex, customProductBrand, pathname) {
  const fromUrl = resolveProductFromPath(pathname, customProducts);
  if (fromUrl?.product === "exxat-custom" && fromUrl.customIndex !== void 0) {
    const brand = customProducts[fromUrl.customIndex];
    if (isListedCustomProduct(brand)) {
      return { product: "exxat-custom", customBrand: brand };
    }
  }
  if (product === "exxat-custom" && isListedCustomProduct(customProductBrand)) {
    return { product, customBrand: customProductBrand };
  }
  if (product === "exxat-custom" && customProducts.length > 0) {
    const idx = Math.max(0, Math.min(activeCustomIndex, customProducts.length - 1));
    const brand = customProducts[idx];
    if (isListedCustomProduct(brand)) {
      return { product, customBrand: brand };
    }
  }
  return { product, customBrand: customProductBrand };
}
function syncProductThemeToDocument(product, customProducts, activeCustomIndex, customProductBrand, productBrandColors, pathname) {
  const html = document.documentElement;
  for (const themeClass2 of PRODUCT_THEME_CLASSES) {
    html.classList.remove(themeClass2);
  }
  const { product: effectiveProduct, customBrand } = resolveThemeContext(
    product,
    customProducts,
    activeCustomIndex,
    customProductBrand,
    pathname
  );
  const themeClass = resolveProductThemeClass(effectiveProduct, productBrandColors);
  const effectiveBrandColor = effectiveProduct === "exxat-custom" && customBrand?.brandColor?.trim() ? normalizeBrandAccentColor(customBrand.brandColor) : brandForProduct(effectiveProduct, customBrand, productBrandColors).brandColor;
  html.style.setProperty("--custom-product-brand-color", effectiveBrandColor);
  html.classList.add(themeClass);
}
function expectedThemeSnapshot(pathname) {
  const state = useAppStore.getState();
  const customBrand = getActiveCustomProductBrand(state);
  const { product: effectiveProduct, customBrand: resolvedBrand } = resolveThemeContext(
    state.product,
    state.customProducts,
    state.activeCustomIndex,
    customBrand,
    pathname
  );
  const expectedTheme = resolveProductThemeClass(effectiveProduct, state.productBrandColors);
  const expectedBrandColor = effectiveProduct === "exxat-custom" && resolvedBrand?.brandColor?.trim() ? normalizeBrandAccentColor(resolvedBrand.brandColor) : brandForProduct(effectiveProduct, resolvedBrand, state.productBrandColors).brandColor;
  return { expectedTheme, expectedBrandColor };
}
function themeDocumentNeedsResync(pathname) {
  const { expectedTheme, expectedBrandColor } = expectedThemeSnapshot(pathname);
  const html = document.documentElement;
  if (!html.classList.contains(expectedTheme)) return true;
  for (const themeClass of PRODUCT_THEME_CLASSES) {
    if (themeClass !== expectedTheme && html.classList.contains(themeClass)) return true;
  }
  if (expectedTheme === "theme-custom") {
    const current = html.style.getPropertyValue("--custom-product-brand-color").trim();
    if (!current || !brandColorsEquivalent(current, expectedBrandColor)) return true;
  }
  return false;
}
function syncActiveProductThemeFromStore(pathname) {
  const state = useAppStore.getState();
  syncProductThemeToDocument(
    state.product,
    state.customProducts,
    state.activeCustomIndex,
    getActiveCustomProductBrand(state),
    state.productBrandColors,
    pathname ?? (typeof window !== "undefined" ? window.location.pathname : "/")
  );
}
function useProduct() {
  const product = useAppStore((s) => s.product);
  const setProduct = useAppStore((s) => s.setProduct);
  const customProducts = useAppStore((s) => s.customProducts);
  const activeCustomIndex = useAppStore((s) => s.activeCustomIndex);
  const customProductBrand = useAppStore((s) => getActiveCustomProductBrand(s));
  const addCustomProduct = useAppStore((s) => s.addCustomProduct);
  const updateCustomProduct = useAppStore((s) => s.updateCustomProduct);
  const removeCustomProduct = useAppStore((s) => s.removeCustomProduct);
  const setActiveCustomIndex = useAppStore((s) => s.setActiveCustomIndex);
  const setCustomProducts = useAppStore((s) => s.setCustomProducts);
  const productBrandColors = useAppStore((s) => s.productBrandColors);
  const setProductBrandColor = useAppStore((s) => s.setProductBrandColor);
  const hiddenProducts = useAppStore((s) => s.hiddenProducts);
  const hideProduct = useAppStore((s) => s.hideProduct);
  const showProduct = useAppStore((s) => s.showProduct);
  const startupProduct = useAppStore((s) => s.startupProduct);
  const setStartupProduct = useAppStore((s) => s.setStartupProduct);
  return {
    product,
    setProduct,
    customProducts,
    activeCustomIndex,
    customProductBrand,
    addCustomProduct,
    updateCustomProduct,
    removeCustomProduct,
    setActiveCustomIndex,
    setCustomProducts,
    productBrandColors,
    setProductBrandColor,
    hiddenProducts,
    hideProduct,
    showProduct,
    startupProduct,
    setStartupProduct
  };
}
function ProductProvider({ children, authoring }) {
  const product = useAppStore((s) => s.product);
  const customProducts = useAppStore((s) => s.customProducts);
  const activeCustomIndex = useAppStore((s) => s.activeCustomIndex);
  const customProductBrand = useAppStore((s) => getActiveCustomProductBrand(s));
  const productBrandColors = useAppStore((s) => s.productBrandColors);
  const { resolvedTheme } = useTheme();
  const { pathname } = useLocation();
  React3.useEffect(() => {
    function syncTenantCatalogIntoAppStore() {
      const state = useAppStore.getState();
      const cleaned = state.customProducts.filter(isListedCustomProduct);
      const { customProducts: catalogMirror } = hydrateTenantProducts({
        customProducts: cleaned,
        codeProducts: [...listRegisteredProducts()]
      });
      const mirror = catalogMirror.length > 0 ? catalogMirror : cleaned;
      const safeMirror = mirror.length === 0 && cleaned.length > 0 ? cleaned : mirror;
      if (safeMirror.length !== state.customProducts.length || safeMirror.some((cp, i) => cp.suffix !== state.customProducts[i]?.suffix)) {
        state.setCustomProducts(safeMirror);
      }
      if (state.activeCustomIndex >= safeMirror.length) {
        state.setActiveCustomIndex(Math.max(0, safeMirror.length - 1));
      }
      if (state.product === "exxat-custom" && !hasConfiguredCustomProducts(safeMirror)) {
        state.setProduct("exxat-prism");
      }
      syncActiveProductThemeFromStore(window.location.pathname);
    }
    function runBootstrap() {
      void ensureShippedCatalogLoaded2().finally(syncTenantCatalogIntoAppStore);
    }
    const unsub = useAppStore.persist.onFinishHydration(runBootstrap);
    if (!useAppStore.persist.hasHydrated()) {
      void useAppStore.persist.rehydrate();
    } else {
      runBootstrap();
    }
    return unsub;
  }, []);
  React3.useLayoutEffect(() => {
    if (product === "exxat-custom" && !hasConfiguredCustomProducts(customProducts)) {
      useAppStore.getState().setProduct("exxat-prism");
    }
    const apply = () => {
      syncActiveProductThemeFromStore(pathname);
      useAppStore.getState().setProductSwitching(false);
    };
    apply();
    const raf = requestAnimationFrame(apply);
    const observer = new MutationObserver(() => {
      if (themeDocumentNeedsResync(pathname)) {
        apply();
      }
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "style"]
    });
    const unsubStore = useAppStore.subscribe((state, prev) => {
      if (state.product !== prev.product || state.activeCustomIndex !== prev.activeCustomIndex || state.customProducts !== prev.customProducts || state.productBrandColors !== prev.productBrandColors) {
        apply();
      }
    });
    return () => {
      cancelAnimationFrame(raf);
      observer.disconnect();
      unsubStore();
    };
  }, [
    activeCustomIndex,
    customProductBrand,
    customProducts,
    pathname,
    product,
    productBrandColors,
    resolvedTheme
  ]);
  return /* @__PURE__ */ jsx2(ProductAuthoringProvider, { enabled: authoring, children });
}
export {
  ProductProvider,
  syncActiveProductThemeFromStore,
  useProduct
};
//# sourceMappingURL=product-context.js.map