import { ClientUser, User } from "discord.js";
import { Synthra, TrackPartial } from "./Manager";
import { Node, NodeStats } from "./Node";
import { Player, Track } from "./Player";
import { Queue } from "./Queue";
export declare abstract class TrackUtils {
    static trackPartial: TrackPartial[] | null;
    private static manager;
    /**
     * Initializes the TrackUtils class with the given manager.
     * @param manager The manager instance to use.
     * @hidden
     */
    static init(manager: Synthra): void;
    /**
     * Sets the partial properties for the Track class. If a Track has some of its properties removed by the partial,
     * it will be considered a partial Track.
     * @param {TrackPartial} partial The array of string property names to remove from the Track class.
     */
    static setTrackPartial(partial: TrackPartial[]): void;
    /**
     * Checks if the provided argument is a valid Track.
     * If provided an array then every element will be checked.
     * @param trackOrTracks The Track or array of Tracks to check.
     * @returns {boolean} Whether the provided argument is a valid Track.
     */
    static validate(trackOrTracks: unknown): boolean;
    /**
     * Builds a Track from the raw data from Lavalink and a optional requester.
     * @param data The raw data from Lavalink to build the Track from.
     * @param requester The user who requested the track, if any.
     * @returns The built Track.
     */
    static build<T = User | ClientUser>(data: TrackData, requester?: T): Track;
}
/** Gets or extends structures to extend the built in, or already extended, classes to add more functionality. */
export declare abstract class Structure {
    /**
     * Extends a class.
     * @param name
     * @param extender
     */
    static extend<K extends keyof Extendable, T extends Extendable[K]>(name: K, extender: (target: Extendable[K]) => T): T;
    /**
     * Get a structure from available structures by name.
     * @param name
     */
    static get<K extends keyof Extendable>(name: K): Extendable[K];
}
export type Sizes = "0" | "1" | "2" | "3" | "default" | "mqdefault" | "hqdefault" | "maxresdefault";
export declare enum LoadTypes {
    Track = "track",
    Playlist = "playlist",
    Search = "search",
    Empty = "empty",
    Error = "error"
}
export type LoadType = keyof typeof LoadTypes;
export declare enum StateTypes {
    Connected = "CONNECTED",
    Connecting = "CONNECTING",
    Disconnected = "DISCONNECTED",
    Disconnecting = "DISCONNECTING",
    Destroying = "DESTROYING"
}
export type State = keyof typeof StateTypes;
export type SponsorBlockSegmentEvents = SponsorBlockSegmentSkipped | SponsorBlockSegmentsLoaded | SponsorBlockChapterStarted | SponsorBlockChaptersLoaded;
export type SponsorBlockSegmentEventType = "SegmentSkipped" | "SegmentsLoaded" | "ChapterStarted" | "ChaptersLoaded";
export type PlayerEvents = TrackStartEvent | TrackEndEvent | TrackStuckEvent | TrackExceptionEvent | WebSocketClosedEvent | SponsorBlockSegmentEvents;
export type PlayerEventType = "TrackStartEvent" | "TrackEndEvent" | "TrackExceptionEvent" | "TrackStuckEvent" | "WebSocketClosedEvent" | "SegmentSkipped" | "SegmentsLoaded" | "ChaptersLoaded" | "ChapterStarted";
export declare enum TrackEndReasonTypes {
    Finished = "finished",
    LoadFailed = "loadFailed",
    Stopped = "stopped",
    Replaced = "replaced",
    Cleanup = "cleanup"
}
export type TrackEndReason = keyof typeof TrackEndReasonTypes;
export declare enum SeverityTypes {
    Common = "common",
    Suspicious = "suspicious",
    Fault = "fault"
}
export type Severity = keyof typeof SeverityTypes;
export interface TrackData {
    /** The track information. */
    encoded: string;
    /** The detailed information of the track. */
    info: TrackDataInfo;
    /** Additional track info provided by plugins. */
    pluginInfo: Record<string, string>;
}
export interface TrackDataInfo {
    identifier: string;
    isSeekable: boolean;
    author: string;
    length: number;
    isrc?: string;
    isStream: boolean;
    title: string;
    uri?: string;
    artworkUrl?: string;
    sourceName?: TrackSourceName;
}
export declare enum TrackSourceTypes {
    AppleMusic = "applemusic",
    Bandcamp = "bandcamp",
    Deezer = "deezer",
    Jiosaavn = "jiosaavn",
    SoundCloud = "soundcloud",
    Spotify = "spotify",
    Tidal = "tidal",
    VKMusic = "vkmusic",
    YouTube = "youtube"
}
export type TrackSourceName = keyof typeof TrackSourceTypes;
export interface Extendable {
    Player: typeof Player;
    Queue: typeof Queue;
    Node: typeof Node;
}
export interface VoiceState {
    op: "voiceUpdate";
    guildId: string;
    event: VoiceServer;
    sessionId?: string;
}
export interface VoiceServer {
    token: string;
    guild_id: string;
    endpoint: string;
}
export interface VoiceState {
    guild_id: string;
    user_id: string;
    session_id: string;
    channel_id: string;
}
export interface VoicePacket {
    t?: "VOICE_SERVER_UPDATE" | "VOICE_STATE_UPDATE";
    d: VoiceState | VoiceServer;
}
export interface NodeMessage extends NodeStats {
    type: PlayerEventType;
    op: "stats" | "playerUpdate" | "event";
    guildId: string;
}
export interface PlayerEvent {
    op: "event";
    type: PlayerEventType;
    guildId: string;
}
export interface Exception {
    message: string;
    severity: SeverityTypes;
    cause: string;
}
export interface TrackStartEvent extends PlayerEvent {
    type: "TrackStartEvent";
    track: TrackData;
}
export interface TrackEndEvent extends PlayerEvent {
    type: "TrackEndEvent";
    track: TrackData;
    reason: TrackEndReasonTypes;
}
export interface TrackExceptionEvent extends PlayerEvent {
    exception?: Exception;
    guildId: string;
    type: "TrackExceptionEvent";
}
export interface TrackStuckEvent extends PlayerEvent {
    type: "TrackStuckEvent";
    thresholdMs: number;
}
export interface WebSocketClosedEvent extends PlayerEvent {
    type: "WebSocketClosedEvent";
    code: number;
    reason: string;
    byRemote: boolean;
}
export interface SponsorBlockSegmentsLoaded extends PlayerEvent {
    type: "SegmentsLoaded";
    segments: {
        category: string;
        start: number;
        end: number;
    }[];
}
export interface SponsorBlockSegmentSkipped extends PlayerEvent {
    type: "SegmentSkipped";
    segment: {
        category: string;
        start: number;
        end: number;
    };
}
export interface SponsorBlockChapterStarted extends PlayerEvent {
    type: "ChapterStarted";
    /** The chapter which started */
    chapter: {
        /** The name of the chapter */
        name: string;
        start: number;
        end: number;
        duration: number;
    };
}
export interface SponsorBlockChaptersLoaded extends PlayerEvent {
    type: "ChaptersLoaded";
    /** All chapters loaded */
    chapters: {
        /** The name of the chapter */
        name: string;
        start: number;
        end: number;
        duration: number;
    }[];
}
export interface PlayerUpdate {
    op: "playerUpdate";
    /** The guild id of the player. */
    guildId: string;
    state: {
        /** Unix timestamp in milliseconds. */
        time: number;
        /** The position of the track in milliseconds. */
        position: number;
        /** Whether Lavalink is connected to the voice gateway. */
        connected: boolean;
        /** The ping of the node to the Discord voice server in milliseconds (-1 if not connected). */
        ping: number;
    };
}
