import React from 'react';
import { type ResolvedMediaTransform, type DirectImageUrlOptions } from '@riverbankcms/media-core';
import type { Media } from '../../../lib/media';
/**
 * Options for image URL resolution.
 * Requires either dimensions or explicit original request.
 */
export type ImageOptions = {
    width: number;
    height?: number;
    quality?: number;
    resize?: 'cover' | 'contain' | 'fill';
} | {
    width?: number;
    height: number;
    quality?: number;
    resize?: 'cover' | 'contain' | 'fill';
} | {
    original: true;
};
export type ResolveImageUrlContext = {
    supabaseUrl?: string;
    siteId?: string;
    /**
     * Optional per-call media asset index for resolving identifier-only media values
     * without mutating persisted content shapes.
     */
    mediaAssetIndex?: MediaAssetIndex;
};
export type ResolveImageUrlContextInput = Readonly<{
    supabaseUrl?: string;
    siteId?: string;
    mediaAssetIndex?: MediaAssetIndex;
    mediaAssets?: readonly MediaAssetIndexItem[];
}>;
export type MediaAssetIndexItem = Readonly<{
    id: string;
    identifier?: string | null;
    storageBucket?: string;
    storagePath?: string;
    width?: number | null;
    height?: number | null;
    mimeType?: string;
}>;
export type MediaAssetIndex = Readonly<{
    byId: ReadonlyMap<string, MediaAssetIndexItem>;
    byIdentifier: ReadonlyMap<string, MediaAssetIndexItem>;
}>;
export declare function buildMediaAssetIndex(assets: readonly MediaAssetIndexItem[] | undefined): MediaAssetIndex | undefined;
export type ResolveImageSourceSetOptions = {
    widthCandidates?: readonly number[];
    sizes?: string;
    resize?: 'cover' | 'contain' | 'fill';
    quality?: number;
    targetAspectRatio?: number;
    defaultWidth?: number;
};
export type ResolvedImageSourceSet = {
    src: string;
    srcSet: string;
    sizes?: string;
    /**
     * Best-effort direct Supabase URL (uncropped/unrotated beyond CSS) that can be used as a degraded fallback
     * if the proxy fails. Intended for runtime safety.
     */
    fallbackSrc?: string;
};
export declare function buildResolveImageUrlContext(input: ResolveImageUrlContextInput | undefined): ResolveImageUrlContext;
export declare function resolveMediaStorageUrl(value: Media, context?: ResolveImageUrlContext | null, transformOptions?: DirectImageUrlOptions): string | undefined;
/**
 * Common image size presets.
 * Use these for consistent sizing across the application.
 */
export declare const ImagePresets: {
    /** Small thumbnails (200px) - for block previews, lists */
    readonly thumbnail: {
        readonly width: 200;
        readonly quality: 80;
        readonly resize: "contain";
    };
    /** Card-sized images (600px) - for cards, grids */
    readonly card: {
        readonly width: 600;
        readonly quality: 80;
        readonly resize: "contain";
    };
    /** Hero images (1200px) - for above-fold content */
    readonly hero: {
        readonly width: 1200;
        readonly quality: 85;
        readonly resize: "contain";
    };
    /** Full-width images (1920px) - for backgrounds, large displays */
    readonly full: {
        readonly width: 1920;
        readonly quality: 85;
        readonly resize: "contain";
    };
};
/**
 * Media context for URL resolution.
 * Contains site-specific values needed to build storage URLs.
 */
type MediaContext = {
    supabaseUrl?: string;
    siteId?: string;
    mediaAssetIndex?: MediaAssetIndex;
};
/**
 * Run a function with the given media context.
 * On server: Uses AsyncLocalStorage to isolate context per request.
 * On client: Temporarily sets module-level context for the duration of the call.
 *
 * @example
 * ```tsx
 * runWithMediaContext(
 *   { supabaseUrl: 'https://...', siteId: 'abc-123' },
 *   () => renderPage(page)
 * )
 * ```
 */
export declare function runWithMediaContext<T>(context: MediaContext, fn: () => T): T;
/**
 * Set the Supabase URL in the current context.
 * @deprecated Use runWithMediaContext instead for request isolation.
 */
export declare function setContextSupabaseUrl(url: string | undefined): void;
/**
 * Set the site ID in the current context.
 * @deprecated Use runWithMediaContext instead for request isolation.
 */
export declare function setContextSiteId(siteId: string | undefined): void;
export declare function setContextMediaAssetIndex(index: MediaAssetIndex | undefined): void;
export declare function setContextResolveImageUrlContext(context: ResolveImageUrlContext | undefined): void;
export declare function getCurrentResolveImageUrlContext(): ResolveImageUrlContext | undefined;
export declare function setContextMediaAssets(assets: readonly MediaAssetIndexItem[] | undefined): void;
/**
 * Get the Supabase URL for constructing direct storage URLs.
 * Used for serving images directly from Supabase storage CDN.
 *
 * Resolution order:
 * 1. Context URL (set via runWithMediaContext or setContextSupabaseUrl)
 * 2. Environment variable NEXT_PUBLIC_SUPABASE_URL
 *
 * SDK sites receive the URL from the API, so they don't need the env var.
 * Dashboard and frontend apps use the env var.
 */
export declare function getSupabaseUrl(): string;
/**
 * Get the site ID for constructing storage paths.
 * Required for relative path resolution.
 */
export declare function getSiteId(): string | undefined;
export declare function resolveMediaWithContext<TMedia extends Media>(value: TMedia, context?: ResolveImageUrlContext | null): TMedia;
export type MediaNodeProps = {
    value?: Media | null;
    className?: string;
    style?: React.CSSProperties;
    children?: React.ReactNode;
    /** Video playback mode. Background video is decorative, muted, looping, and control-free. */
    videoPlayback?: VideoPlaybackMode;
    /** Image size options. Defaults to ImagePresets.full (1920px) */
    size?: ImageOptions;
    /**
     * Field path relative to the block content root (e.g. "images.0.image").
     * Injected by the runtime resolver for content-bound media nodes.
     */
    fieldPath?: string;
    /** Optional block metadata injected by the runtime resolver */
    blockKind?: string | null;
    blockContent?: unknown;
};
export type VideoPlaybackMode = 'inline' | 'background';
export declare function resolveMediaNodeResponsiveImage(value: Media, size: ImageOptions, style: React.CSSProperties | undefined, slot: {
    fieldPath?: string;
    blockKind?: string | null;
    blockContent?: unknown;
}, context?: ResolveImageUrlContext | null): {
    transformAspectRatio: number | string | undefined;
    responsive?: ResolvedImageSourceSet;
    imageUrl?: string;
    resolvedTransform?: ResolvedMediaTransform;
    isProxy?: boolean;
};
export declare function renderVideo(value: Media, className?: string, style?: React.CSSProperties, context?: ResolveImageUrlContext | null, options?: {
    playback?: VideoPlaybackMode;
}): React.ReactElement | null;
export declare function renderAudio(value: Media, className?: string, style?: React.CSSProperties, context?: ResolveImageUrlContext | null): React.ReactElement | null;
export declare function computeMediaTransformStyle(value: Media, style?: React.CSSProperties, targetAspectRatio?: number | string, options?: {
    resolvedTransform?: ResolvedMediaTransform;
    isProxy?: boolean;
}): React.CSSProperties | undefined;
export declare const computeHotspotStyle: typeof computeMediaTransformStyle;
export declare function resolveTargetAspectRatio(size: ImageOptions): number | undefined;
export declare function MediaPlaceholder({ className, style, }: {
    className?: string;
    style?: React.CSSProperties;
}): React.ReactElement;
export declare const MediaNode: React.FC<MediaNodeProps>;
/**
 * Resolve an image URL from a Media object.
 *
 * @param value - The Media object containing storage path or src
 * @param options - Image sizing options (required to encourage conscious size decisions)
 *   - Use `ImagePresets.thumbnail`, `ImagePresets.card`, etc. for common sizes
 *   - Use `{ width: 800 }` for custom sizes
 *   - Use `{ original: true }` for full-resolution (rare: downloads, print)
 * @returns The resolved image URL, or undefined if not an image
 *
 * @example
 * ```tsx
 * // Using presets
 * resolveImageUrl(media, ImagePresets.card)
 *
 * // Custom size
 * resolveImageUrl(media, { width: 800, quality: 90 })
 *
 * // Original resolution (rare)
 * resolveImageUrl(media, { original: true })
 * ```
 */
export declare function resolveImageUrl(value: Media, options: ImageOptions, context?: ResolveImageUrlContext | null): string | undefined;
export declare function resolveImageUrlWithContext(value: Media, options: ImageOptions, context?: ResolveImageUrlContext | null, transformAspectRatio?: number | string): string | undefined;
export declare function resolveImageSourceSetWithContext(value: Media, options: ResolveImageSourceSetOptions, context?: ResolveImageUrlContext | null): ResolvedImageSourceSet | undefined;
export {};
