export const forkedDaapdDefaultPort = 3689;
export const forkedDaapdDefaultTimeoutMs = 5000;
export const forkedDaapdDefaultUnmuteVolume = 0.6;
export const forkedDaapdDefaultMaxPlaylists = 10;
export const forkedDaapdSourceNameClear = 'Clear queue';
export const forkedDaapdSourceNameDefault = 'Default (no pipe)';

export type TForkedDaapdProtocol = 'http';
export type TForkedDaapdSnapshotSource = 'snapshot' | 'http' | 'executor' | 'websocket' | 'runtime';
export type TForkedDaapdPlayerState = 'play' | 'pause' | 'stop' | (string & {});
export type TForkedDaapdRepeatMode = 'off' | 'all' | 'single' | (string & {});
export type TForkedDaapdCommand =
  | 'play'
  | 'pause'
  | 'stop'
  | 'next_track'
  | 'previous_track'
  | 'seek'
  | 'set_volume'
  | 'mute'
  | 'shuffle'
  | 'repeat'
  | 'clear_queue'
  | 'play_media'
  | 'select_source'
  | 'turn_on'
  | 'turn_off'
  | 'set_output'
  | 'set_enabled_outputs'
  | 'raw_request';

export interface IForkedDaapdConfig {
  host?: string;
  port?: number;
  password?: string;
  name?: string;
  uniqueId?: string;
  timeoutMs?: number;
  maxPlaylists?: number;
  snapshot?: IForkedDaapdSnapshot;
  commandExecutor?: IForkedDaapdCommandExecutor;
}

export interface IHomeAssistantForkedDaapdConfig extends IForkedDaapdConfig {}

export interface IForkedDaapdCommandExecutor {
  execute(requestArg: IForkedDaapdRawCommandRequest): Promise<IForkedDaapdCommandExecutorResult | unknown>;
}

export interface IForkedDaapdRawCommandRequest {
  method: 'GET' | 'PUT' | 'POST' | 'DELETE';
  endpoint: string;
  url?: string;
  host?: string;
  port: number;
  protocol: TForkedDaapdProtocol;
  params?: Record<string, string | number | boolean | undefined>;
  body?: unknown;
  password?: string;
  expectJson?: boolean;
}

export interface IForkedDaapdCommandExecutorResult {
  ok?: boolean;
  success?: boolean;
  status?: number;
  response?: string;
  data?: unknown;
}

export interface IForkedDaapdCommandRequest {
  command: TForkedDaapdCommand;
  outputId?: string;
  outputIds?: string[];
  selected?: boolean;
  volumeLevel?: number;
  volume?: number;
  muted?: boolean;
  shuffle?: boolean;
  repeat?: TForkedDaapdRepeatMode;
  position?: number;
  positionMs?: number;
  mediaId?: string;
  mediaType?: string;
  uri?: string;
  source?: string;
  clear?: boolean;
  playback?: 'start' | 'stop' | string;
  method?: IForkedDaapdRawCommandRequest['method'];
  endpoint?: string;
  params?: Record<string, string | number | boolean | undefined>;
  body?: unknown;
  expectJson?: boolean;
}

export interface IForkedDaapdServerConfig {
  library_name?: string;
  websocket_port?: number;
  version?: string;
  [key: string]: unknown;
}

export interface IForkedDaapdServerInfo {
  id: string;
  name: string;
  host?: string;
  port?: number;
  protocol: TForkedDaapdProtocol;
  libraryName?: string;
  websocketPort?: number;
  version?: string;
  config?: IForkedDaapdServerConfig;
}

export interface IForkedDaapdPlayerStatus {
  state: TForkedDaapdPlayerState;
  repeat: TForkedDaapdRepeatMode;
  consume: boolean;
  shuffle: boolean;
  volume: number;
  item_id: number;
  item_length_ms: number;
  item_progress_ms: number;
  [key: string]: unknown;
}

export interface IForkedDaapdQueueItem {
  id: number | string;
  position?: number;
  track_id?: number | string;
  title?: string;
  artist?: string;
  album?: string;
  album_artist?: string;
  albumartist?: string;
  genre?: string;
  track_number?: number;
  length_ms?: number;
  media_kind?: string;
  data_kind?: string;
  path?: string;
  uri?: string;
  artwork_url?: string;
  [key: string]: unknown;
}

export interface IForkedDaapdQueueStatus {
  version: number;
  count: number;
  items: IForkedDaapdQueueItem[];
  [key: string]: unknown;
}

export interface IForkedDaapdOutput {
  id: string;
  name: string;
  type?: string;
  selected: boolean;
  volume: number;
  has_password?: boolean;
  requires_auth?: boolean;
  needs_auth_key?: boolean;
  offset_ms?: number;
  format?: string;
  supported_formats?: string[];
  [key: string]: unknown;
}

export interface IForkedDaapdLibraryItem {
  id?: number | string;
  name?: string;
  title?: string;
  uri?: string;
  data_kind?: string;
  artwork_url?: string;
  [key: string]: unknown;
}

export interface IForkedDaapdLibrarySnapshot {
  playlists: IForkedDaapdLibraryItem[];
  pipes: IForkedDaapdLibraryItem[];
}

export interface IForkedDaapdSnapshot {
  server: IForkedDaapdServerInfo;
  player: IForkedDaapdPlayerStatus;
  queue: IForkedDaapdQueueStatus;
  outputs: IForkedDaapdOutput[];
  library: IForkedDaapdLibrarySnapshot;
  online: boolean;
  updatedAt?: string;
  source?: TForkedDaapdSnapshotSource;
  maxPlaylists?: number;
  error?: string;
  raw?: Record<string, unknown>;
}

export interface IForkedDaapdMdnsRecord {
  type?: string;
  serviceType?: string;
  name?: string;
  host?: string;
  hostname?: string;
  port?: number;
  addresses?: string[];
  txt?: Record<string, unknown>;
  properties?: Record<string, unknown>;
}

export interface IForkedDaapdManualEntry {
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  password?: string;
  uniqueId?: string;
  metadata?: Record<string, unknown>;
}
