export const mpdDefaultPort = 6600;

export type TMpdTransport = 'tcp' | 'snapshot';

export type TMpdPlaybackState = 'play' | 'pause' | 'stop' | 'unknown' | (string & {});

export type TMpdSnapshotSource = 'manual' | 'snapshot' | 'tcp' | 'runtime';

export type TMpdServiceCommand =
  | 'play'
  | 'pause'
  | 'stop'
  | 'next'
  | 'previous'
  | 'set_volume'
  | 'volume'
  | 'volume_set'
  | 'source'
  | 'select_source'
  | 'output'
  | 'enable_output'
  | 'disable_output'
  | 'toggle_output'
  | 'set_output'
  | 'snapshot'
  | 'restore'
  | 'command';

export interface IMpdConfig {
  host?: string;
  port?: number;
  password?: string;
  timeoutMs?: number;
  name?: string;
  serverId?: string;
  transport?: TMpdTransport;
  snapshot?: IMpdSnapshot;
}

export interface IHomeAssistantMpdConfig extends IMpdConfig {}

export interface IMpdServerInfo {
  id?: string;
  host?: string;
  port?: number;
  name?: string;
  protocolVersion?: string;
  commands?: TMpdCommand[];
  authenticated?: boolean;
}

export interface IMpdStatus {
  partition?: string;
  volume?: string | number;
  repeat?: string | number;
  random?: string | number;
  single?: string | number;
  consume?: string | number;
  playlist?: string | number;
  playlistlength?: string | number;
  state?: TMpdPlaybackState;
  song?: string | number;
  songid?: string | number;
  nextsong?: string | number;
  nextsongid?: string | number;
  time?: string;
  elapsed?: string | number;
  duration?: string | number;
  bitrate?: string | number;
  xfade?: string | number;
  mixrampdb?: string | number;
  mixrampdelay?: string | number;
  audio?: string;
  updating_db?: string | number;
  error?: string;
  lastloadedplaylist?: string;
  [key: string]: unknown;
}

export interface IMpdCurrentSong {
  file?: string;
  artist?: string | string[];
  artistsort?: string | string[];
  album?: string;
  albumsort?: string;
  albumartist?: string | string[];
  albumartistsort?: string | string[];
  title?: string;
  titlesort?: string;
  track?: string | number;
  name?: string;
  genre?: string | string[];
  date?: string;
  originaldate?: string;
  composer?: string | string[];
  performer?: string | string[];
  disc?: string | number;
  time?: string | number;
  duration?: string | number;
  pos?: string | number;
  id?: string | number;
  [key: string]: unknown;
}

export interface IMpdOutput {
  outputid: string | number;
  outputname: string;
  plugin?: string;
  outputenabled: boolean | string | number;
  attributes?: Record<string, string>;
  [key: string]: unknown;
}

export interface IMpdStoredPlaylist {
  playlist: string;
  lastModified?: string;
  [key: string]: unknown;
}

export interface IMpdStats {
  artists?: string | number;
  albums?: string | number;
  songs?: string | number;
  uptime?: string | number;
  db_playtime?: string | number;
  db_update?: string | number;
  playtime?: string | number;
  [key: string]: unknown;
}

export type TMpdCommand =
  | 'add'
  | 'clear'
  | 'commands'
  | 'currentsong'
  | 'disableoutput'
  | 'enableoutput'
  | 'listplaylists'
  | 'next'
  | 'outputs'
  | 'password'
  | 'pause'
  | 'play'
  | 'previous'
  | 'setvol'
  | 'status'
  | 'stop'
  | 'toggleoutput'
  | string;

export interface IMpdCommandRequest {
  command: TMpdCommand;
  args?: Array<string | number | boolean>;
}

export interface IMpdResponseLine {
  key: string;
  value: string;
}

export interface IMpdCommandResponse {
  command: TMpdCommand;
  rawLines: string[];
  lines: IMpdResponseLine[];
  protocolVersion?: string;
}

export interface IMpdSnapshot {
  server: IMpdServerInfo;
  status: IMpdStatus;
  currentSong?: IMpdCurrentSong;
  outputs: IMpdOutput[];
  commands: TMpdCommand[];
  playlists: IMpdStoredPlaylist[];
  stats?: IMpdStats;
  online: boolean;
  updatedAt?: string;
  source?: TMpdSnapshotSource;
}

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

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

export interface IMpdDiscoveryRecord {
  source: 'mdns' | 'manual';
  host?: string;
  port?: number;
  name?: string;
  id?: string;
  mdnsType?: string;
}
