export type TYamahaMusiccastZoneId = string;

export type TYamahaMusiccastPowerState = 'on' | 'standby' | 'toggle' | string;

export type TYamahaMusiccastMediaState = 'off' | 'on' | 'playing' | 'paused' | 'idle' | string;

export type TYamahaMusiccastPlaybackState =
  | 'play'
  | 'stop'
  | 'pause'
  | 'play_pause'
  | 'previous'
  | 'next'
  | 'fast_reverse_start'
  | 'fast_reverse_end'
  | 'fast_forward_start'
  | 'fast_forward_end'
  | string;

export type TYamahaMusiccastCapabilityType = 'switch' | 'select' | 'number';

export type TYamahaMusiccastCapabilityCategory = 'regular' | 'config' | 'diagnostic';

export type TYamahaMusiccastCommand =
  | 'turn_on'
  | 'turn_off'
  | 'volume_up'
  | 'volume_down'
  | 'set_volume'
  | 'mute'
  | 'select_source'
  | 'select_sound_mode'
  | 'play'
  | 'pause'
  | 'stop'
  | 'play_pause'
  | 'previous_track'
  | 'next_track'
  | 'set_repeat'
  | 'set_shuffle'
  | 'set_switch'
  | 'select_option'
  | 'set_number'
  | 'raw_get';

export interface IYamahaMusiccastConfig {
  host?: string;
  port?: number;
  name?: string;
  model?: string;
  serialNumber?: string;
  systemId?: string;
  deviceId?: string;
  manufacturer?: string;
  upnpDescription?: string;
  requestTimeoutMs?: number;
  inputNames?: Record<string, string>;
  zoneNames?: Record<string, string>;
  deviceInfo?: IYamahaMusiccastDeviceInfo;
  networkStatus?: IYamahaMusiccastNetworkStatus;
  funcStatus?: IYamahaMusiccastFuncStatus;
  features?: IYamahaMusiccastFeatures;
  zones?: IYamahaMusiccastZoneState[];
  netusb?: IYamahaMusiccastNetusbPlayInfo;
  tuner?: IYamahaMusiccastTunerPlayInfo;
  distribution?: IYamahaMusiccastDistributionInfo;
  capabilities?: IYamahaMusiccastCapability[];
  snapshot?: IYamahaMusiccastSnapshot;
}

export interface IHomeAssistantYamahaMusiccastConfig extends IYamahaMusiccastConfig {}

export interface IYamahaMusiccastDeviceInfo {
  response_code?: number;
  model_name?: string;
  destination?: string;
  device_id?: string;
  system_id?: string;
  system_version?: string | number;
  api_version?: string | number;
  netmodule_generation?: number;
  netmodule_version?: string;
  netmodule_checksum?: string;
  serial_number?: string;
  category_code?: number;
  operation_mode?: string;
  update_error_code?: string;
  net_module_num?: number;
  update_data_type?: number;
  [key: string]: unknown;
}

export interface IYamahaMusiccastNetworkStatus {
  response_code?: number;
  network_name?: string;
  connection?: string;
  dhcp?: boolean;
  ip_address?: string;
  subnet_mask?: string;
  default_gateway?: string;
  dns_server_1?: string;
  dns_server_2?: string;
  wireless_lan?: Record<string, unknown>;
  musiccast_network?: Record<string, unknown>;
  mac_address?: Record<string, string | undefined>;
  airplay_pin?: string;
  ipv6?: Record<string, unknown>;
  each_module_ip_list?: string[];
  [key: string]: unknown;
}

export interface IYamahaMusiccastFuncStatus {
  response_code?: number;
  headphone?: boolean;
  hdmi_out_1?: boolean;
  hdmi_out_2?: boolean;
  party_mode?: boolean;
  party_enable?: boolean;
  speaker_a?: boolean;
  speaker_b?: boolean;
  dimmer?: number;
  [key: string]: unknown;
}

export interface IYamahaMusiccastFeatures {
  response_code?: number;
  system?: IYamahaMusiccastSystemFeatures;
  zone?: IYamahaMusiccastZoneFeatures[];
  tuner?: Record<string, unknown>;
  netusb?: Record<string, unknown>;
  distribution?: Record<string, unknown>;
  ccs?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IYamahaMusiccastSystemFeatures {
  func_list?: string[];
  zone_num?: number;
  input_list?: IYamahaMusiccastInputFeature[];
  web_control_url?: string;
  party_volume_list?: string[];
  hdmi_standby_through_list?: string[];
  range_step?: IYamahaMusiccastRangeStep[];
  [key: string]: unknown;
}

export interface IYamahaMusiccastInputFeature {
  id: string;
  distribution_enable?: boolean;
  rename_enable?: boolean;
  account_enable?: boolean;
  play_info_type?: 'netusb' | 'tuner' | 'cd' | 'none' | string;
  [key: string]: unknown;
}

export interface IYamahaMusiccastZoneFeatures {
  id: TYamahaMusiccastZoneId;
  zone_b?: boolean;
  func_list?: string[];
  input_list?: string[];
  sound_program_list?: string[];
  surr_decoder_type_list?: string[];
  tone_control_mode_list?: string[];
  equalizer_mode_list?: string[];
  link_control_list?: string[];
  link_audio_delay_list?: string[];
  link_audio_quality_list?: string[];
  range_step?: IYamahaMusiccastRangeStep[];
  scene_num?: number;
  cursor_list?: string[];
  menu_list?: string[];
  actual_volume_mode_list?: string[];
  ccs_supported?: string[];
  [key: string]: unknown;
}

export interface IYamahaMusiccastRangeStep {
  id: string;
  min: number;
  max: number;
  step: number;
}

export interface IYamahaMusiccastZoneStatus {
  response_code?: number;
  power?: TYamahaMusiccastPowerState;
  sleep?: number;
  volume?: number;
  mute?: boolean;
  max_volume?: number;
  min_volume?: number;
  input?: string;
  input_text?: string;
  distribution_enable?: boolean;
  sound_program?: string;
  surr_decoder_type?: string;
  pure_direct?: boolean;
  enhancer?: boolean;
  tone_control?: {
    mode?: string;
    bass?: number;
    treble?: number;
  };
  equalizer?: {
    mode?: string;
    low?: number;
    mid?: number;
    high?: number;
  };
  balance?: number;
  dialogue_level?: number;
  dialogue_lift?: number;
  dts_dialogue_control?: number;
  subwoofer_volume?: number;
  link_control?: string;
  link_audio_delay?: string;
  link_audio_quality?: string;
  actual_volume?: {
    mode?: string;
    value?: number;
    unit?: string;
  };
  party_enable?: boolean;
  extra_bass?: boolean;
  bass_extension?: boolean;
  adaptive_drc?: boolean;
  clear_voice?: boolean;
  surround_3d?: boolean;
  '3d_surround'?: boolean;
  mono?: boolean;
  disable_flags?: number;
  [key: string]: unknown;
}

export interface IYamahaMusiccastZoneState {
  zone: TYamahaMusiccastZoneId;
  name?: string;
  power?: TYamahaMusiccastPowerState;
  state?: TYamahaMusiccastMediaState;
  available?: boolean;
  sleep?: number;
  volume?: number;
  minVolume?: number;
  maxVolume?: number;
  volumeLevel?: number;
  muted?: boolean;
  input?: string;
  inputText?: string;
  inputList?: string[];
  sourceMap?: Record<string, string>;
  soundProgram?: string;
  soundProgramList?: string[];
  surrDecoderType?: string;
  surrDecoderTypeList?: string[];
  toneControlModeList?: string[];
  equalizerModeList?: string[];
  linkControlList?: string[];
  linkAudioDelayList?: string[];
  linkAudioQualityList?: string[];
  rangeStep?: IYamahaMusiccastRangeStep[];
  features?: string[];
  status?: IYamahaMusiccastZoneStatus;
  signalInfo?: Record<string, unknown>;
  actualVolume?: {
    mode?: string;
    value?: number;
    unit?: string;
  };
  toneControl?: {
    mode?: string;
    bass?: number;
    treble?: number;
  };
  equalizer?: {
    mode?: string;
    low?: number;
    mid?: number;
    high?: number;
  };
  balance?: number;
  dialogueLevel?: number;
  dialogueLift?: number;
  dtsDialogueControl?: number;
  subwooferVolume?: number;
  linkControl?: string;
  linkAudioDelay?: string;
  linkAudioQuality?: string;
  extraBass?: boolean;
  bassExtension?: boolean;
  enhancer?: boolean;
  pureDirect?: boolean;
  adaptiveDrc?: boolean;
  clearVoice?: boolean;
  surround3d?: boolean;
  mono?: boolean;
  capabilities?: IYamahaMusiccastCapability[];
}

export interface IYamahaMusiccastCapability {
  id: string;
  name: string;
  type: TYamahaMusiccastCapabilityType;
  zoneId?: TYamahaMusiccastZoneId;
  category?: TYamahaMusiccastCapabilityCategory;
  current?: string | number | boolean | null;
  options?: Record<string, string> | string[];
  range?: IYamahaMusiccastRangeStep;
  command?: TYamahaMusiccastCommand;
}

export interface IYamahaMusiccastNetusbPlayInfo {
  response_code?: number;
  input?: string;
  playback?: TYamahaMusiccastPlaybackState;
  repeat?: string;
  shuffle?: string;
  play_time?: number;
  total_time?: number;
  artist?: string;
  album?: string;
  track?: string;
  albumart_url?: string;
  albumart_id?: number;
  repeat_available?: string[];
  shuffle_available?: string[];
  [key: string]: unknown;
}

export interface IYamahaMusiccastTunerPlayInfo {
  response_code?: number;
  band?: string;
  auto_scan?: boolean;
  am?: Record<string, unknown>;
  fm?: Record<string, unknown>;
  dab?: Record<string, unknown>;
  rds?: {
    program_type?: string;
    program_service?: string;
    radio_text_a?: string;
    radio_text_b?: string;
  };
  [key: string]: unknown;
}

export interface IYamahaMusiccastDistributionInfo {
  response_code?: number;
  group_id?: string;
  group_name?: string;
  role?: string;
  server_zone?: string;
  client_list?: string[];
  build_disable?: string[];
  audio_dropout?: boolean;
  [key: string]: unknown;
}

export interface IYamahaMusiccastSnapshot {
  deviceInfo: IYamahaMusiccastDeviceInfo;
  networkStatus?: IYamahaMusiccastNetworkStatus;
  funcStatus?: IYamahaMusiccastFuncStatus;
  features?: IYamahaMusiccastFeatures;
  zones: IYamahaMusiccastZoneState[];
  inputNames?: Record<string, string>;
  netusb?: IYamahaMusiccastNetusbPlayInfo;
  tuner?: IYamahaMusiccastTunerPlayInfo;
  distribution?: IYamahaMusiccastDistributionInfo;
  capabilities?: IYamahaMusiccastCapability[];
  lastUpdated?: string;
}

export interface IYamahaMusiccastCommandRequest {
  command: TYamahaMusiccastCommand;
  zone?: TYamahaMusiccastZoneId;
  source?: string;
  soundMode?: string;
  volumeLevel?: number;
  volume?: number;
  muted?: boolean;
  playback?: TYamahaMusiccastPlaybackState;
  repeat?: string;
  shuffle?: boolean | string;
  capabilityId?: string;
  value?: string | number | boolean;
  option?: string;
  path?: string;
}

export interface IYamahaMusiccastMdnsRecord {
  name?: string;
  type?: string;
  host?: string;
  port?: number;
  txt?: Record<string, string | undefined>;
}

export interface IYamahaMusiccastSsdpRecord {
  st?: string;
  usn?: string;
  location?: string;
  headers?: Record<string, string | undefined>;
  upnp?: Record<string, string | undefined>;
}

export interface IYamahaMusiccastManualEntry {
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  systemId?: string;
  deviceId?: string;
  metadata?: Record<string, unknown>;
}
