import * as react from 'react';
import { ReactNode } from 'react';
import * as react_jsx_runtime from 'react/jsx-runtime';

type WaveformMode = 'peaks' | 'live' | 'bars' | 'progress' | 'none';
type WaveformConfig = {
    mode?: WaveformMode;
    peaks?: Float32Array;
    height?: number;
    barWidth?: number;
    barGap?: number;
    bgColor?: string;
    fgColor?: string;
    decodeOnMount?: boolean;
};
type ReactiveCoverMode = false | 'subtle';
type PlayerVariant = 'default' | 'compact' | 'auto';
type PlayerErrorReason = 'network' | 'decode' | 'unsupported' | 'unknown';
type PlayerProps = {
    src: string;
    peaks?: Float32Array;
    title?: string;
    artist?: string;
    album?: string;
    cover?: string;
    variant?: PlayerVariant;
    className?: string;
    waveform?: WaveformConfig;
    reactiveCover?: ReactiveCoverMode;
    autoplay?: boolean;
    loop?: boolean;
    initialVolume?: number;
    muted?: boolean;
    preload?: 'none' | 'metadata' | 'auto';
    exclusive?: boolean;
    onPrev?: () => void;
    onNext?: () => void;
    onPlay?: () => void;
    onPause?: () => void;
    onEnded?: () => void;
    onError?: (reason: PlayerErrorReason, e: unknown) => void;
    onTimeUpdate?: (currentTime: number, duration: number) => void;
    ariaLabel?: string;
    enableKeyboardShortcuts?: boolean;
    /** Focus the player container on mount so its keyboard scope is active
     *  immediately. Pair with `key={src}` upstream when the parent wants a
     *  fresh focus on every source change (file-browser inspector pattern). */
    autoFocus?: boolean;
    seekStartsPlayback?: boolean;
};
type PlayerStateKind = 'idle' | 'loading' | 'decoding' | 'ready' | 'playing' | 'paused' | 'ended' | 'error';
type PlayerState = {
    kind: 'idle' | 'loading';
} | {
    kind: 'decoding';
    duration: number;
} | {
    kind: 'ready' | 'playing' | 'paused' | 'ended';
    duration: number;
    peaks?: Float32Array;
} | {
    kind: 'error';
    reason: PlayerErrorReason;
    duration: number;
};
type PlayerControls = {
    play: () => Promise<void>;
    pause: () => void;
    toggle: () => Promise<void>;
    seek: (seconds: number) => void;
    seekTo: (ratio: number) => void;
    setVolume: (v: number) => void;
    toggleMute: () => void;
    toggleLoop: () => void;
};
type PlayerHandle = {
    audio: HTMLAudioElement;
    play: () => Promise<void>;
    pause: () => void;
    seek: (seconds: number) => void;
    getCurrentTime: () => number;
    getDuration: () => number;
    /** Move keyboard focus to the player container so its hotkey scope
     *  (Space=play/pause, ←→=seek, ↑↓=volume, M=mute) becomes active. */
    focus: () => void;
};

declare const Player: react.ForwardRefExoticComponent<PlayerProps & react.RefAttributes<PlayerHandle>>;

type LevelsStore = {
    subscribe: (cb: () => void) => () => void;
    getCurrent: () => Float32Array;
    set: (next: Float32Array) => void;
    setActive: (active: boolean) => void;
    isActive: () => boolean;
};

type Listener$1 = (activeId: string | null) => void;
declare function setActivePlayer(id: string | null): void;
declare function getActivePlayer(): string | null;
declare function getLastActivePlayer(): string | null;
declare function subscribeActivePlayer(cb: Listener$1): () => void;

type PlayerPreferences = {
    volume: number;
    muted: boolean;
};
type Listener = (prefs: PlayerPreferences) => void;
declare function getPreferences(): PlayerPreferences;
declare function setStoredVolume(volume: number): void;
declare function setStoredMuted(muted: boolean): void;
declare function subscribePreferences(cb: Listener): () => void;

type PlayerMeta = {
    src: string;
    title?: string;
    artist?: string;
    album?: string;
    cover?: string;
    hasPrev: boolean;
    hasNext: boolean;
};

type PlayerProviderProps = {
    src: string;
    peaks?: Float32Array;
    title?: string;
    artist?: string;
    album?: string;
    cover?: string;
    autoplay?: boolean;
    loop?: boolean;
    initialVolume?: number;
    muted?: boolean;
    preload?: 'none' | 'metadata' | 'auto';
    exclusive?: boolean;
    onPrev?: () => void;
    onNext?: () => void;
    onPlay?: () => void;
    onPause?: () => void;
    onEnded?: () => void;
    onError?: (reason: PlayerErrorReason, e: unknown) => void;
    children: ReactNode;
};
declare function PlayerProvider(props: PlayerProviderProps): react_jsx_runtime.JSX.Element;

declare const usePlayerState: () => PlayerState;
declare const usePlayerControls: () => PlayerControls;
declare const usePlayerLevels: () => LevelsStore;
declare const usePlayerMeta: () => PlayerMeta;
declare const usePlayerAudio: () => HTMLAudioElement;
declare const usePlayerPaused: () => boolean;
declare const usePlayerDuration: () => number;

/** Currently active player id. `null` when nothing plays. */
declare function useActivePlayer(): string | null;
/** Most recently active player id. Stays set after pause; useful for "last
 * played" UIs where you want to keep showing a track even when paused. */
declare function useLastActivePlayer(): string | null;
/** True when the given id is currently active. Convenience for conditional
 * styling without comparing strings inline. */
declare function useIsActivePlayer(id: string | null | undefined): boolean;

declare function usePlayerPreferences(): PlayerPreferences;

export { Player as LazyPlayer, Player, type PlayerControls, type PlayerErrorReason, type PlayerHandle, type PlayerPreferences, type PlayerProps, PlayerProvider, type PlayerState, type PlayerStateKind, type PlayerVariant, type ReactiveCoverMode, type WaveformConfig, type WaveformMode, getActivePlayer, getLastActivePlayer, getPreferences, setActivePlayer, setStoredMuted, setStoredVolume, subscribeActivePlayer, subscribePreferences, useActivePlayer, useIsActivePlayer, useLastActivePlayer, usePlayerAudio, usePlayerControls, usePlayerDuration, usePlayerLevels, usePlayerMeta, usePlayerPaused, usePlayerPreferences, usePlayerState };
