import { BroadcastDriver } from 'laravel-echo';
import { Broadcaster } from 'laravel-echo';
import { ConnectionStatus } from 'laravel-echo';
import { default as default_2 } from 'laravel-echo';
import { DependencyList } from 'react';
import { EchoOptions } from 'laravel-echo';

declare type BroadcastNotification<TPayload> = TPayload & {
    id: string;
    type: string;
};

declare type Channel = {
    name: string;
    id: string;
    visibility: "private" | "public" | "presence";
};

declare type ChannelReturnType<T extends BroadcastDriver, V extends Channel["visibility"]> = V extends "presence" ? Broadcaster[T]["presence"] : V extends "private" ? Broadcaster[T]["private"] : Broadcaster[T]["public"];

/**
 * Configure the Echo instance with sensible defaults.
 *
 * @link https://laravel.com/docs/broadcasting#client-side-installation
 */
export declare const configureEcho: <T extends BroadcastDriver>(config: EchoOptions<T>) => void;

export { ConnectionStatus }

export declare const echo: <T extends BroadcastDriver>() => default_2<T>;

export declare const echoIsConfigured: () => boolean;

/**
 * Type alias for event names - helps with autocomplete suggestions
 */
declare type EventName = keyof Events & string;

/**
 * Type utility to infer payload type from event name
 */
declare type InferEventPayload<TEvent extends string> = TEvent extends keyof Events ? Events[TEvent] : unknown;

declare type ModelEvent = "Retrieved" | "Creating" | "Created" | "Updating" | "Updated" | "Saving" | "Saved" | "Deleting" | "Deleted" | "Trashed" | "ForceDeleting" | "ForceDeleted" | "Restoring" | "Restored" | "Replicating";

declare type ModelEvents<T extends string> = `.${ModelName<T>}${ModelEvent}` | `${ModelName<T>}${ModelEvent}`;

declare type ModelName<T extends string> = T extends `${infer _}.${infer U}` ? ModelName<U> : T;

declare type ModelPayload<T> = {
    model: T;
    connection: string | null;
    queue: string | null;
    afterCommit: boolean;
};

/**
 * Hook to get the current WebSocket connection status
 *
 * @returns ConnectionStatus - The current connection status
 */
export declare const useConnectionStatus: () => ConnectionStatus;

export declare function useEcho<TEvent extends EventName = EventName, TDriver extends BroadcastDriver = BroadcastDriver, TVisibility extends Channel["visibility"] = "private">(channelName: string, event: TEvent, callback: (payload: InferEventPayload<TEvent>) => void, dependencies?: DependencyList, visibility?: TVisibility): {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => ChannelReturnType<TDriver, TVisibility>;
};

export declare function useEcho<TEvent extends EventName = EventName, TDriver extends BroadcastDriver = BroadcastDriver, TVisibility extends Channel["visibility"] = "private">(channelName: string, event: TEvent[], callback: (payload: InferEventPayload<TEvent>) => void, dependencies?: DependencyList, visibility?: TVisibility): {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => ChannelReturnType<TDriver, TVisibility>;
};

export declare function useEcho<TPayload, TDriver extends BroadcastDriver = BroadcastDriver, TVisibility extends Channel["visibility"] = "private">(channelName: string, event: string | string[], callback: (payload: TPayload) => void, dependencies?: DependencyList, visibility?: TVisibility): {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => ChannelReturnType<TDriver, TVisibility>;
};

export declare const useEchoModel: <TPayload, TModel extends string, TDriver extends BroadcastDriver = BroadcastDriver>(model: TModel, identifier: string | number, event?: ModelEvents<TModel> | ModelEvents<TModel>[], callback?: (payload: ModelPayload<TPayload>) => void, dependencies?: DependencyList) => {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => Broadcaster[TDriver]["private"];
};

export declare const useEchoNotification: <TPayload, TDriver extends BroadcastDriver = BroadcastDriver>(channelName: string, callback?: (payload: BroadcastNotification<TPayload>) => void, event?: string | string[], dependencies?: DependencyList) => {
    /**
     * Stop listening for notification events
     */
    stopListening: () => void;
    /**
     * Listen for notification events
     */
    listen: () => void;
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    channel: () => Broadcaster[TDriver]["private"];
};

export declare const useEchoPresence: <TPayload, TDriver extends BroadcastDriver = BroadcastDriver>(channelName: string, event?: string | string[], callback?: (payload: TPayload) => void, dependencies?: DependencyList) => {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => Broadcaster[TDriver]["presence"];
};

export declare const useEchoPublic: <TPayload, TDriver extends BroadcastDriver = BroadcastDriver>(channelName: string, event?: string | string[], callback?: (payload: TPayload) => void, dependencies?: DependencyList) => {
    leaveChannel: (leaveAll?: boolean) => void;
    leave: () => void;
    stopListening: () => void;
    listen: () => void;
    channel: () => Broadcaster[TDriver]["public"];
};

export { }
