/**
 * App Types
 *
 * Defines the types for the SynOS app system.
 * Apps provide runtime extensions (actions, widgets, events) and editor modules.
 */
import type { ZodSchema } from 'zod';
import type { ActionExecutor } from '../actions/types';
import type { DecisionStrategy } from '../decisions/types';
import type { NormalizedEvent } from '../events/types';
import type { MountableWidget } from '../widgets/WidgetRegistry';
/**
 * Action definition provided by an app.
 */
export interface AppActionDefinition {
    /** Action kind (e.g., "gamification:awardBadge") */
    kind: string;
    /** Zod schema for validation */
    schema?: ZodSchema;
    /** Executor function */
    executor: ActionExecutor<any>;
}
/**
 * Widget definition provided by an app.
 */
export interface AppWidgetDefinition {
    /** Widget ID (e.g., "gamification:leaderboard") */
    id: string;
    /** The widget component */
    component: MountableWidget;
    /** Optional metadata */
    metadata?: {
        name?: string;
        description?: string;
        icon?: string;
    };
}
/**
 * Context passed to app event handlers.
 */
export interface AppEventContext {
    /** The app ID */
    appId: string;
    /** Access to state store */
    state: {
        get: (key: string) => unknown;
        set: (key: string, value: unknown) => void;
    };
    /** Emit telemetry events */
    telemetry?: {
        emit: (eventName: string, props?: Record<string, unknown>) => void;
    };
    /** Access to surfaces */
    surfaces?: {
        mount: (slot: string, content: unknown, opts?: unknown) => {
            unmount: () => void;
        };
    };
}
/**
 * Event handler definition provided by an app.
 */
export interface AppEventHandler {
    /** Event names to listen for */
    names: string[];
    /** Handler function */
    handler: (event: NormalizedEvent, ctx: AppEventContext) => void | Promise<void>;
}
/**
 * A condition to watch continuously.
 * When the strategy transitions from false → true, the runtime publishes
 * the specified event. This runs in ShadowCanvasOverlay (always mounted),
 * so it fires even when the widget/drawer is closed.
 */
export interface NotifyWatcherEntry {
    /** Unique ID for state tracking and dedup */
    id: string;
    /** DecisionStrategy to evaluate on each EventBus event */
    strategy: DecisionStrategy<boolean>;
    /** Event name to publish when condition transitions false → true */
    eventName: string;
    /** Event props to publish */
    eventProps: Record<string, unknown>;
}
/**
 * Runtime extensions provided by an app.
 */
export interface AppRuntimeExtensions {
    /** Custom action kinds */
    actions?: AppActionDefinition[];
    /** Widget components */
    widgets?: AppWidgetDefinition[];
    /** Event handlers */
    events?: AppEventHandler[];
    /**
     * Extract notify watcher entries from tile config props.
     * Called once when tiles are loaded. The returned entries are evaluated
     * continuously — when a strategy transitions false → true, the runtime
     * publishes the associated event (even if the widget isn't mounted).
     */
    notifyWatchers?: (props: Record<string, unknown>) => NotifyWatcherEntry[];
}
/**
 * Props passed to editor panel components.
 */
export interface EditorPanelProps {
    /** The current config for this app's portion */
    config: Record<string, unknown>;
    /** Callback when config changes */
    onChange: (config: Record<string, unknown>) => void;
    /** Editor utilities */
    editor: {
        /** Mark the editor as dirty (has unsaved changes) */
        setDirty: (dirty: boolean) => void;
        /** Navigate back to home */
        navigateHome: () => Promise<boolean>;
        /** Save the current config */
        save: () => Promise<void>;
        /** Publish the current config */
        publish: (captureScreenshot?: boolean) => Promise<void>;
    };
    /** Platform client for API calls (optional) */
    platformClient?: unknown;
}
/**
 * Editor panel configuration.
 */
export interface EditorPanelConfig {
    /** Panel title */
    title: string;
    /** Panel icon (emoji or icon key) */
    icon: string;
    /** Panel description */
    description: string;
}
/**
 * Editor module provided by an app.
 */
export interface AppEditorModule {
    /** React component for the editor panel */
    component: React.ComponentType<EditorPanelProps>;
    /** Panel configuration */
    panel: EditorPanelConfig;
    /** Extract a display label from a tile action object. Called by EditorHome. */
    getActionLabel?: (action: Record<string, unknown>) => string;
}
/**
 * App manifest - the complete definition of a SynOS app.
 */
export interface AppManifest {
    /** Unique app identifier (e.g., "adaptive-gamification") */
    id: string;
    /** App version (semver) */
    version: string;
    /** Human-readable app name */
    name: string;
    /** App description */
    description?: string;
    /** Runtime extensions */
    runtime?: AppRuntimeExtensions;
    /** Zod schema for this app's config portion */
    configSchema?: ZodSchema;
    /** Editor module (optional - apps without editors are runtime-only) */
    editor?: AppEditorModule;
    /** App dependencies (other app IDs that must be loaded first) */
    dependencies?: string[];
    /** App metadata */
    metadata?: {
        /** Author name or organization */
        author?: string;
        /** Homepage URL */
        homepage?: string;
        /** License identifier */
        license?: string;
        /** Tags for categorization */
        tags?: string[];
        /** Whether this is a built-in app (bundled with runtime) */
        isBuiltIn?: boolean;
    };
}
/**
 * App lifecycle state.
 */
export type AppLifecycleState = 'registered' | 'activating' | 'active' | 'deactivating' | 'inactive' | 'error';
/**
 * App registration - tracked state for a registered app.
 */
export interface AppRegistration {
    /** The app manifest */
    manifest: AppManifest;
    /** Current lifecycle state */
    state: AppLifecycleState;
    /** When the app was registered */
    registeredAt: number;
    /** When the app was last activated */
    activatedAt?: number;
    /** Error message if state is "error" */
    error?: string;
    /** Cleanup function to deactivate the app */
    cleanup?: () => void | Promise<void>;
}
/**
 * Sandboxed runtime context provided to apps.
 */
export interface AppContext {
    /** The app ID */
    appId: string;
    /** State store (scoped to app namespace) */
    state: {
        get: (key: string) => unknown;
        set: (key: string, value: unknown) => void;
        remove: (key: string) => void;
    };
    /** Telemetry (if available) */
    telemetry?: {
        emit: (eventName: string, props?: Record<string, unknown>) => void;
        getSessionId: () => string | undefined;
    };
    /** Surfaces access */
    surfaces: {
        mount: (slot: string, content: unknown, opts?: unknown) => {
            unmount: () => void;
            update: (content: unknown) => void;
        };
        canMount: (slot: string, priority?: number) => boolean;
    };
    /** Event subscription */
    events: {
        subscribe: (callback: (event: NormalizedEvent) => void) => () => void;
        publish: (name: string, props?: Record<string, unknown>) => void;
    };
    /** Register app-provided actions */
    registerAction: (definition: AppActionDefinition) => void;
    /** Register app-provided widgets */
    registerWidget: (definition: AppWidgetDefinition) => void;
}
/**
 * Events emitted by the app registry.
 */
export type AppRegistryEvent = {
    type: 'app:registered';
    appId: string;
    manifest: AppManifest;
} | {
    type: 'app:activated';
    appId: string;
} | {
    type: 'app:deactivated';
    appId: string;
} | {
    type: 'app:error';
    appId: string;
    error: string;
} | {
    type: 'app:unregistered';
    appId: string;
};
