export type THarmonyJsonValue = string | number | boolean | null | THarmonyJsonValue[] | { [key: string]: THarmonyJsonValue | undefined };

export type THarmonyCommandAction =
  | 'connect'
  | 'start_activity'
  | 'power_off'
  | 'send_command'
  | 'change_channel';

export type THarmonyCommandReason =
  | 'connect'
  | 'remote_turn_on'
  | 'remote_turn_off'
  | 'remote_send_command'
  | 'select_activity'
  | 'select_option'
  | 'change_channel';

export interface IHarmonyDeviceInfo {
  id?: string;
  name?: string;
  host?: string;
  port?: number;
  remoteId?: string;
  hubId?: string;
  manufacturer?: string;
  model?: string;
  softwareVersion?: string;
  firmwareVersion?: string;
  timeStampHash?: string;
}

export interface IHarmonyActivity {
  id: string;
  label: string;
  isPowerOff?: boolean;
  raw?: Record<string, unknown>;
}

export interface IHarmonyDeviceCommand {
  name: string;
  action?: string;
  label?: string;
  raw?: Record<string, unknown>;
}

export interface IHarmonyDeviceCommandGroup {
  name: string;
  commands: IHarmonyDeviceCommand[];
}

export interface IHarmonyDevice {
  id: string;
  label: string;
  manufacturer?: string;
  model?: string;
  commandGroups?: IHarmonyDeviceCommandGroup[];
  commands?: IHarmonyDeviceCommand[];
  raw?: Record<string, unknown>;
}

export interface IHarmonyState {
  available?: boolean;
  currentActivityId?: string;
  currentActivity?: string;
  activityStarting?: string | null;
  lastActivity?: string | null;
  rawState?: string;
}

export interface IHarmonySnapshot {
  deviceInfo: IHarmonyDeviceInfo;
  state: IHarmonyState;
  activities: IHarmonyActivity[];
  devices: IHarmonyDevice[];
  hubConfig?: THarmonyJsonValue;
  updatedAt?: string;
}

export interface IHarmonyRemoteCommandStep {
  deviceId: string;
  device: string;
  command: string;
  holdSecs?: number;
}

export interface IHarmonyCommand {
  action: THarmonyCommandAction;
  reason?: THarmonyCommandReason;
  activityId?: string;
  activity?: string;
  deviceId?: string;
  device?: string;
  command?: string;
  commands?: string[];
  sequence?: IHarmonyRemoteCommandStep[];
  numRepeats?: number;
  delaySecs?: number;
  holdSecs?: number;
  channel?: number;
}

export interface IHarmonyCommandContext {
  config: IHarmonyConfig;
  snapshot: IHarmonySnapshot;
}

export type THarmonyCommandExecutor =
  | ((commandArg: IHarmonyCommand, contextArg: IHarmonyCommandContext) => Promise<void> | void)
  | {
      execute(commandArg: IHarmonyCommand, contextArg: IHarmonyCommandContext): Promise<void> | void;
    };

export interface IHarmonyClientAdapter {
  getSnapshot?(): Promise<IHarmonySnapshot> | IHarmonySnapshot;
  execute?(commandArg: IHarmonyCommand, contextArg: IHarmonyCommandContext): Promise<void> | void;
  destroy?(): Promise<void> | void;
}

export interface IHarmonyConfig {
  host?: string;
  port?: number;
  name?: string;
  deviceName?: string;
  remoteId?: string;
  hubId?: string;
  manufacturer?: string;
  model?: string;
  defaultActivity?: string;
  activity?: string;
  delaySecs?: number;
  delay_secs?: number;
  holdSecs?: number;
  hold_secs?: number;
  numRepeats?: number;
  num_repeats?: number;
  currentActivity?: string;
  currentActivityId?: string | number;
  lastActivity?: string;
  activities?: IHarmonyActivity[] | Array<Record<string, unknown>>;
  devices?: IHarmonyDevice[] | Array<Record<string, unknown>>;
  deviceInfo?: IHarmonyDeviceInfo;
  state?: IHarmonyState;
  hubConfig?: THarmonyJsonValue | Record<string, unknown>;
  snapshot?: IHarmonySnapshot;
  executor?: THarmonyCommandExecutor;
  client?: IHarmonyClientAdapter;
  discovery?: {
    source?: string;
    metadata?: Record<string, unknown>;
  };
}

export interface IHarmonySsdpRecord {
  deviceType?: string;
  device_type?: string;
  st?: string;
  nt?: string;
  usn?: string;
  udn?: string;
  location?: string;
  ssdp_location?: string;
  host?: string;
  name?: string;
  friendlyName?: string;
  friendly_name?: string;
  manufacturer?: string;
  modelName?: string;
  model_name?: string;
  serialNumber?: string;
  upnp?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
}

export interface IHarmonyManualEntry {
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  deviceName?: string;
  remoteId?: string;
  hubId?: string;
  manufacturer?: string;
  model?: string;
  metadata?: Record<string, unknown>;
}

export type IHomeAssistantHarmonyConfig = IHarmonyConfig;
