export const harmanKardonAvrDomain = 'harman_kardon_avr';
export const harmanKardonAvrDefaultName = 'Harman Kardon AVR';
export const harmanKardonAvrDefaultPort = 10025;
export const harmanKardonAvrDefaultTimeoutMs = 1500;
export const harmanKardonAvrDefaultZone = 'Main Zone';

export const harmanKardonAvrDefaultSources = [
  'Disc',
  'STB',
  'Cable Sat',
  'Media Server',
  'DVR',
  'Radio',
  'TV',
  'USB',
  'Game',
  'Home Network',
  'AUX',
];

export const harmanKardonAvrCommandMap = {
  turn_off: 'power-off',
  turn_on: 'power-on',
  sleep: 'sleep',
  volume_up: 'volume-up',
  volume_down: 'volume-down',
  mute_toggle: 'mute-toggle',
  play: 'play',
  pause: 'pause',
  next_track: 'next',
  previous_track: 'previous',
  select_source: 'source-selection',
  heartbeat: 'heart-alive',
} as const;

export type THarmanKardonAvrSnapshotSource = 'tcp' | 'snapshot' | 'manual' | 'client' | 'executor' | 'runtime';

export type THarmanKardonAvrPowerState = 'ON' | 'OFF' | 'STANDBY' | string;

export type THarmanKardonAvrMediaState = 'on' | 'off' | 'unknown' | 'unavailable' | string;

export type THarmanKardonAvrCommand =
  | 'turn_on'
  | 'turn_off'
  | 'volume_up'
  | 'volume_down'
  | 'mute'
  | 'mute_toggle'
  | 'select_source'
  | 'play'
  | 'pause'
  | 'next_track'
  | 'previous_track'
  | 'sleep'
  | 'heartbeat'
  | 'raw';

export interface IHarmanKardonAvrConfig {
  host?: string;
  port?: number;
  name?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  zone?: string;
  timeoutMs?: number;
  responseIdleMs?: number;
  sources?: string[];
  state?: IHarmanKardonAvrMediaPlayerState;
  snapshot?: IHarmanKardonAvrSnapshot;
  client?: IHarmanKardonAvrClientLike;
  commandExecutor?: IHarmanKardonAvrCommandExecutor;
}

export interface IHomeAssistantHarmanKardonAvrConfig extends IHarmanKardonAvrConfig {}

export interface IHarmanKardonAvrClientLike {
  getSnapshot?(): Promise<IHarmanKardonAvrSnapshot>;
  snapshot?(): Promise<IHarmanKardonAvrSnapshot>;
  execute?(requestArg: IHarmanKardonAvrCommandRequest): Promise<unknown>;
}

export interface IHarmanKardonAvrCommandExecutor {
  execute(requestArg: IHarmanKardonAvrRawCommandRequest): Promise<unknown>;
}

export interface IHarmanKardonAvrDeviceInfo {
  host?: string;
  port?: number;
  name?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  zone?: string;
}

export interface IHarmanKardonAvrMediaPlayerState {
  power?: THarmanKardonAvrPowerState;
  state?: THarmanKardonAvrMediaState;
  muted?: boolean;
  source?: string;
  sourceList?: string[];
  supportedFeatures?: string[];
  lastCommand?: THarmanKardonAvrCommand;
}

export interface IHarmanKardonAvrSnapshot {
  deviceInfo: IHarmanKardonAvrDeviceInfo;
  state: IHarmanKardonAvrMediaPlayerState;
  online: boolean;
  available: boolean;
  source: THarmanKardonAvrSnapshotSource;
  lastUpdated?: string;
  rawResponse?: string[];
  error?: string;
}

export interface IHarmanKardonAvrCommandRequest {
  command: THarmanKardonAvrCommand;
  source?: string;
  muted?: boolean;
  rawCommand?: string;
  parameter?: string;
}

export interface IHarmanKardonAvrRawCommandRequest {
  command: 'raw';
  rawCommand: string;
  parameter?: string;
  host?: string;
  port: number;
  zone: string;
  timeoutMs: number;
  body: string;
  httpRequest: string;
}

export interface IHarmanKardonAvrCommandResult {
  command: THarmanKardonAvrCommand;
  rawCommand?: string;
  parameter?: string;
  skipped?: boolean;
  response?: unknown;
  snapshot?: IHarmanKardonAvrSnapshot;
}

export interface IHarmanKardonAvrManualEntry {
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  zone?: string;
  sources?: string[];
  state?: IHarmanKardonAvrMediaPlayerState;
  snapshot?: IHarmanKardonAvrSnapshot;
  client?: IHarmanKardonAvrClientLike;
  commandExecutor?: IHarmanKardonAvrCommandExecutor;
  metadata?: Record<string, unknown>;
}
