import * as react from 'react';
import { ReactNode, SelectHTMLAttributes } from 'react';
import { Generation } from '../studio/index.js';
import { IntegrationConnection } from '@tangle-network/sandbox-ui/integrations';
import { Image } from 'lucide-react';

type StudioRole = 'owner' | 'admin' | 'editor' | 'viewer';
interface StudioWorkspaceProps {
    generations: Generation[];
    totalCost: number;
    workspaceId?: string;
    role: StudioRole;
    /** Polling endpoint override (default `/api/generations`). */
    generationsEndpoint?: string;
    /** Build a vault link, optionally to a specific file. Defaults to `/app/<workspaceId>/vault`. */
    vaultHref?: (filePath?: string | null) => string;
    /** Integrations page href for the publish-package "Connect" link. Defaults to `/app/<workspaceId>/integrations`. */
    integrationsHref?: string;
}
/**
 * The full studio surface: header + composer + result canvas + library drawer,
 * with the generation orchestrator (merge/poll/revalidate) wired in. The host
 * route owns the loader (auth, RBAC, the generation query) and the server
 * endpoints (`/api/generate`, `/api/media-models`, `/api/generations`); this
 * shell renders that data and drives the live UI. Role gates the composer
 * (viewers get a read-only library) and the integration-management affordances.
 */
declare function StudioWorkspace({ generations, totalCost, workspaceId, role, generationsEndpoint, vaultHref, integrationsHref, }: StudioWorkspaceProps): react.JSX.Element;

/**
 * The generation orchestrator behind a studio surface: it merges the loader's
 * rows with in-flight live generations, computes the latest batch for the
 * canvas, polls running generations until they settle, and revalidates the
 * route loader when a status changes.
 *
 * The merge keeps the canvas, the library, and the polling path looking at the
 * same full list. Polling hits `generationsEndpoint` (default `/api/generations`,
 * the convention both apps already serve); pass an override if a product routes
 * it elsewhere. `onGenerated` is wired to the composer's per-result callback.
 */
declare function useStudioGenerations(loaderGenerations: Generation[], options?: {
    workspaceId?: string;
    generationsEndpoint?: string;
}): {
    mergedGenerations: Generation[];
    latestBatch: Generation[];
    onGenerated: (generation: Generation) => void;
};

declare function ComposerHero({ workspaceId, integrationsHref, canManageIntegrations, align, surfaceClassName, onGenerated, }: {
    workspaceId?: string;
    integrationsHref?: string;
    canManageIntegrations: boolean;
    /** Heading treatment: `center` (focus mode) vs `start` (composer as a left rail). */
    align?: 'center' | 'start';
    /** Background of the composer card. Host apps pass their own surface token so
     *  the card can share a tone with the app shell (e.g. the sidebar). */
    surfaceClassName?: string;
    onGenerated: (generation: Generation) => void;
}): react.JSX.Element;

declare function Field({ label, htmlFor, className, children, }: {
    label: string;
    htmlFor?: string;
    className?: string;
    children: ReactNode;
}): react.JSX.Element;
declare function Stepper({ value, min, max, onChange, }: {
    value: number;
    min: number;
    max: number;
    onChange: (value: number) => void;
}): react.JSX.Element;
declare function ComposerDisclosure({ summary, children }: {
    summary: ReactNode;
    children: ReactNode;
}): react.JSX.Element;
declare function NativeSelect(props: SelectHTMLAttributes<HTMLSelectElement>): react.JSX.Element;

declare function StudioHeader({ count, onOpenLibrary, canGenerate, }: {
    count: number;
    onOpenLibrary: () => void;
    canGenerate: boolean;
}): react.JSX.Element;

/**
 * Right-side overlay sheet built on Radix Dialog — gives focus-trap, scroll-lock,
 * and Escape-to-close for free. Slide/fade come from the studio-sheet-* classes in
 * ./studio.css (driven by Radix data-state), not tailwindcss-animate.
 */
declare function StudioSheet({ open, onOpenChange, title, children, }: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    title: string;
    children: ReactNode;
}): react.JSX.Element;

declare function ResultCanvas({ batch, onOpenLibrary, onSelect, }: {
    batch: Generation[];
    onOpenLibrary: () => void;
    onSelect: (generation: Generation) => void;
}): react.JSX.Element;

declare function LibraryDrawer({ open, onOpenChange, generations, totalCost, typeFilter, onFilterChange, vaultHref, selected, onSelect, }: {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    generations: Generation[];
    totalCost: number;
    typeFilter: string | null;
    onFilterChange: (type: string | null) => void;
    vaultHref?: (filePath?: string | null) => string;
    selected: Generation | null;
    onSelect: (generation: Generation | null) => void;
}): react.JSX.Element;

/**
 * Inline asset gallery — the same filter + stats + card grid as the library
 * drawer's list view, but with no sheet chrome so it can sit on the page beside
 * the composer. In-flight generations need no special handling: they arrive at
 * the front of `generations` (via `useStudioGenerations.mergedGenerations`) and
 * `GenerationCard` renders their `pending`/`running` shimmer.
 */
declare function LibraryPanel({ generations, totalCost, typeFilter, onFilterChange, onSelect, }: {
    generations: Generation[];
    totalCost: number;
    typeFilter: string | null;
    onFilterChange: (type: string | null) => void;
    onSelect: (generation: Generation) => void;
}): react.JSX.Element;

/** The visible set for the active type tab (all generations when unfiltered). */
declare function filterGenerations(generations: Generation[], typeFilter: string | null): Generation[];
/**
 * Chrome-less asset grid — the `GenerationCard` grid plus its empty state, with
 * no surrounding tabs/stats/sheet chrome. Composed by both the inline
 * `LibraryPanel` and the `LibraryDrawer`'s list view so the grid and its
 * empty-state copy stay in one place. `generations` is the already-filtered
 * visible set; `typeFilter` only tunes the empty-state message.
 */
declare function GenerationGrid({ generations, typeFilter, onSelect, }: {
    generations: Generation[];
    typeFilter: string | null;
    onSelect: (generation: Generation) => void;
}): react.JSX.Element;

declare function GenerationCard({ generation, onSelect, }: {
    generation: Generation;
    onSelect: (generation: Generation) => void;
}): react.JSX.Element;
declare function GenerationStatusBadge({ generation, inline, }: {
    generation: Generation;
    inline?: boolean;
}): react.JSX.Element | null;

declare function GenerationDetail({ generation, vaultHref, onNavigate, }: {
    generation: Generation;
    vaultHref?: (filePath?: string | null) => string;
    onNavigate?: () => void;
}): react.JSX.Element;

/**
 * Centered detail view for a single generation. Opens when `generation` is set
 * and reports dismissal through `onClose`. GenerationDetail renders the media,
 * type badge, prompt and metadata; the dialog title carries the a11y label.
 */
declare function GenerationDetailModal({ generation, vaultHref, onClose, }: {
    generation: Generation | null;
    vaultHref?: (filePath?: string | null) => string;
    onClose: () => void;
}): react.JSX.Element;

declare function PublishPackageComposer({ caption, postDescription, mentions, cadence, selectedDestinations, connections, connectionError, connectionsLoading, integrationsHref, canManageIntegrations, onCaptionChange, onDescriptionChange, onMentionsChange, onCadenceChange, onDestinationToggle, }: {
    caption: string;
    postDescription: string;
    mentions: string;
    cadence: string;
    selectedDestinations: string[];
    connections: IntegrationConnection[];
    connectionError: Error | null;
    connectionsLoading: boolean;
    integrationsHref?: string;
    canManageIntegrations: boolean;
    onCaptionChange: (value: string) => void;
    onDescriptionChange: (value: string) => void;
    onMentionsChange: (value: string) => void;
    onCadenceChange: (value: string) => void;
    onDestinationToggle: (destination: string) => void;
}): react.JSX.Element;

/** Define configuration options for a type including label, icon, and color properties */
interface TypeConfig {
    label: string;
    icon: typeof Image;
    color: string;
}
/** Map type keys to their corresponding configuration objects including labels, icons, and colors */
declare const TYPE_CONFIG: Record<string, TypeConfig>;
/** Resolve the configuration object for a given type or return the default image configuration */
declare function typeConfigFor(type: string): TypeConfig;

declare function ImageComposer({ size, quality, imageCount, onSizeChange, onQualityChange, onImageCountChange, }: {
    size: string;
    quality: string;
    imageCount: number;
    onSizeChange: (value: string) => void;
    onQualityChange: (value: string) => void;
    onImageCountChange: (value: number) => void;
}): react.JSX.Element;

declare function VideoComposer({ duration, resolution, aspectRatio, referenceImageUrl, onDurationChange, onResolutionChange, onAspectRatioChange, onReferenceImageUrlChange, }: {
    duration: string;
    resolution: string;
    aspectRatio: string;
    referenceImageUrl: string;
    onDurationChange: (value: string) => void;
    onResolutionChange: (value: string) => void;
    onAspectRatioChange: (value: string) => void;
    onReferenceImageUrlChange: (value: string) => void;
}): react.JSX.Element;

declare function SpeechComposer({ voice, onVoiceChange, }: {
    voice: string;
    onVoiceChange: (value: string) => void;
}): react.JSX.Element;

declare function AvatarComposer({ audioUrl, imageUrl, avatarId, onAudioUrlChange, onImageUrlChange, onAvatarIdChange, }: {
    audioUrl: string;
    imageUrl: string;
    avatarId: string;
    onAudioUrlChange: (value: string) => void;
    onImageUrlChange: (value: string) => void;
    onAvatarIdChange: (value: string) => void;
}): react.JSX.Element;

declare function TranscriptionComposer({ audioUrl, language, onAudioUrlChange, onLanguageChange, }: {
    audioUrl: string;
    language: string;
    onAudioUrlChange: (value: string) => void;
    onLanguageChange: (value: string) => void;
}): react.JSX.Element;
declare function TranscriptionOptions({ responseFormat, temperature, onResponseFormatChange, onTemperatureChange, }: {
    responseFormat: string;
    temperature: string;
    onResponseFormatChange: (value: string) => void;
    onTemperatureChange: (value: string) => void;
}): react.JSX.Element;

export { AvatarComposer, ComposerDisclosure, ComposerHero, Field, GenerationCard, GenerationDetail, GenerationDetailModal, GenerationGrid, GenerationStatusBadge, ImageComposer, LibraryDrawer, LibraryPanel, NativeSelect, PublishPackageComposer, ResultCanvas, SpeechComposer, Stepper, StudioHeader, type StudioRole, StudioSheet, StudioWorkspace, type StudioWorkspaceProps, TYPE_CONFIG, TranscriptionComposer, TranscriptionOptions, type TypeConfig, VideoComposer, filterGenerations, typeConfigFor, useStudioGenerations };
