import * as zustand_middleware from 'zustand/middleware';
import * as zustand from 'zustand';
import { CustomProductBrand } from './product-framework/custom-product-defaults.js';

/** Identifies a built-in or custom product slot in the switcher / settings. */
interface ProductRef {
    product: Product;
    /** Required when `product === "exxat-custom"` — index into `customProducts[]`. */
    customIndex?: number;
}
declare function productRefKey(ref: ProductRef): string;
declare function productRefsEqual(a: ProductRef, b: ProductRef): boolean;
declare function isProductRefHidden(ref: ProductRef, hiddenProducts: ProductRef[]): boolean;
/** Prism when `startupProduct` is unset. */
declare function effectiveStartupProduct(startupProduct: ProductRef | null): ProductRef;
declare function isStartupProductRef(ref: ProductRef, startupProduct: ProductRef | null): boolean;
declare function startupDashboardPath(startupProduct: ProductRef | null, customProducts?: CustomProductBrand[]): string;
/** Normalize a ref after removing `customProducts[removedIndex]`. */
declare function adjustProductRefAfterCustomRemoval(ref: ProductRef | null, removedIndex: number): ProductRef | null;
declare function adjustHiddenProductsAfterCustomRemoval(hidden: ProductRef[], removedIndex: number): ProductRef[];

type Product = "exxat-prism" | "exxat-one-schools" | "exxat-one-sites" | "exxat-custom";
/** Returns the URL slug owned by `product` (e.g. `"prism"` for `"exxat-prism"`). */
declare function productSlug(product: Product): string;
/**
 * Inspects the leading path segment of `pathname` and returns the matching
 * product id. Returns `null` for shell-global routes (`/`, `/login`,
 * `/settings`, `/help`, demo routes) — those don't belong to any product.
 */
declare function productFromPath(pathname: string, customProducts?: CustomProductBrand[]): Product | null;
/**
 * Compose a product-namespaced `persistKey` (per-hub state never leaks across
 * products). Pass to `<HubTable persistKey={...}>` / `<ListPageTemplate
 * persistKey={...}>` / `usePersistedState` for any state that belongs to a
 * single product.
 */
declare function productPersistKey(product: Product, hubKey: string, customProducts?: CustomProductBrand[], activeCustomIndex?: number): string;

/** Placeholder scaffold — not a real tenant product (Settings Add-product default). */
declare function isCustomProductPlaceholder(brand: CustomProductBrand | null | undefined): boolean;
/** True once the tenant has saved a real Custom slot (not scaffold defaults). */
declare function isCustomProductConfigured(brand: CustomProductBrand | null | undefined): boolean;
/** Any explicitly saved custom row in `customProducts[]`. */
declare function isListedCustomProduct(brand: CustomProductBrand | null | undefined): boolean;
declare function hasConfiguredCustomProducts(products: CustomProductBrand[] | null | undefined): boolean;
declare function getActiveCustomProductBrand(state: {
    customProducts: CustomProductBrand[];
    activeCustomIndex: number;
}): CustomProductBrand | null;
interface AppState {
    /** Currently active product — drives theme class and sidebar logo */
    product: Product;
    setProduct: (product: Product) => void;
    /**
     * Tenant-configured custom product slots — suffix + brand-color per entry.
     * Settings → Appearance → Add product appends here; each row in the list
     * and switcher maps to one index. `activeCustomIndex` picks which entry
     * drives chrome when `product === "exxat-custom"`.
     */
    customProducts: CustomProductBrand[];
    activeCustomIndex: number;
    addCustomProduct: (brand: CustomProductBrand) => number;
    updateCustomProduct: (index: number, brand: CustomProductBrand) => void;
    removeCustomProduct: (index: number) => void;
    setActiveCustomIndex: (index: number) => void;
    setCustomProducts: (products: CustomProductBrand[]) => void;
    /**
     * Per-product brand color overrides — drives the mark gradient + wordmark
     * suffix tint when the user picks a custom color for a built-in product
     * (Exxat One / Prism) or for the custom slot. Settings → Appearance →
     * Product uses these so the color picker actually re-colours the rendered
     * logo (mark + suffix), instead of just the unused `brandColor` on the
     * underlying `ProductBrandConfig`.
     */
    productBrandColors: Partial<Record<Product, string>>;
    setProductBrandColor: (product: Product, color: string | null) => void;
    /**
     * Products hidden from the switcher — each custom row is independent
     * (`{ product: "exxat-custom", customIndex: 1 }`).
     */
    hiddenProducts: ProductRef[];
    hideProduct: (ref: ProductRef) => void;
    showProduct: (ref: ProductRef) => void;
    /** Opens on cold start (`/`). `null` → Exxat Prism. */
    startupProduct: ProductRef | null;
    setStartupProduct: (ref: ProductRef | null) => void;
    /** True while the shell is applying a product switch (theme + navigation). */
    productSwitching: boolean;
    setProductSwitching: (switching: boolean) => void;
}
declare const useAppStore: zustand.UseBoundStore<Omit<zustand.StoreApi<AppState>, "persist" | "setState"> & {
    setState(partial: AppState | Partial<AppState> | ((state: AppState) => AppState | Partial<AppState>), replace?: false | undefined): unknown;
    setState(state: AppState | ((state: AppState) => AppState), replace: true): unknown;
    persist: {
        setOptions: (options: Partial<zustand_middleware.PersistOptions<AppState, unknown, unknown>>) => void;
        clearStorage: () => void;
        rehydrate: () => Promise<void> | void;
        hasHydrated: () => boolean;
        onHydrate: (fn: (state: AppState) => void) => () => void;
        onFinishHydration: (fn: (state: AppState) => void) => () => void;
        getOptions: () => Partial<zustand_middleware.PersistOptions<AppState, unknown, unknown>>;
    };
}>;

export { type Product as P, type ProductRef as a, adjustHiddenProductsAfterCustomRemoval as b, adjustProductRefAfterCustomRemoval as c, isCustomProductPlaceholder as d, effectiveStartupProduct as e, isListedCustomProduct as f, getActiveCustomProductBrand as g, hasConfiguredCustomProducts as h, isCustomProductConfigured as i, isProductRefHidden as j, isStartupProductRef as k, productPersistKey as l, productRefKey as m, productRefsEqual as n, productSlug as o, productFromPath as p, startupDashboardPath as s, useAppStore as u };
