export const directvDomain = 'directv';
export const directvDefaultPort = 8080;
export const directvDefaultDevice = '0';
export const directvDefaultName = 'DirecTV Receiver';
export const directvDefaultTimeoutMs = 8000;
export const directvSsdpDeviceType = 'urn:schemas-upnp-org:device:MediaServer:1';
export const directvSsdpManufacturer = 'DIRECTV';

export const directvRemoteKeys = [
  'power',
  'poweron',
  'poweroff',
  'format',
  'pause',
  'rew',
  'replay',
  'stop',
  'advance',
  'ffwd',
  'record',
  'play',
  'guide',
  'active',
  'list',
  'exit',
  'back',
  'menu',
  'info',
  'up',
  'down',
  'left',
  'right',
  'select',
  'red',
  'green',
  'yellow',
  'blue',
  'chanup',
  'chandown',
  'prev',
  '0',
  '1',
  '2',
  '3',
  '4',
  '5',
  '6',
  '7',
  '8',
  '9',
  'dash',
  'enter',
] as const;

export type TDirectvRemoteKey = typeof directvRemoteKeys[number];
export type TDirectvSnapshotSource = 'snapshot' | 'client' | 'http' | 'executor' | 'runtime';
export type TDirectvProgramType = 'movie' | 'music' | 'tvshow';
export type TDirectvLocationStatus = 'active' | 'standby' | 'unavailable' | 'unauthorized';

export interface IDirectvConfig {
  host?: string;
  port?: number;
  name?: string;
  receiverId?: string;
  uniqueId?: string;
  timeoutMs?: number;
  locations?: IDirectvLocation[];
  snapshot?: IDirectvSnapshot;
  client?: IDirectvClientLike;
  commandExecutor?: IDirectvCommandExecutor;
}

export interface IHomeAssistantDirectvConfig extends IDirectvConfig {}

export interface IDirectvClientLike {
  getSnapshot?: () => Promise<IDirectvSnapshot>;
  snapshot?: () => Promise<IDirectvSnapshot>;
  sendRemoteKey?: (keyArg: string, clientArg?: string) => Promise<unknown>;
  remote?: (keyArg: string, clientArg?: string) => Promise<unknown>;
  tune?: (channelArg: string, clientArg?: string) => Promise<unknown>;
}

export interface IDirectvCommandExecutor {
  execute(requestArg: IDirectvRawRequest): Promise<unknown>;
}

export interface IDirectvRawRequest {
  endpoint: string;
  params: Record<string, string | number | boolean | undefined>;
  url: string;
  host?: string;
  port: number;
  method: 'GET';
}

export interface IDirectvDeviceInfo {
  brand: string;
  receiverId: string;
  version: string;
  host?: string;
  port?: number;
  name?: string;
}

export interface IDirectvLocation {
  client: boolean;
  name: string;
  address: string;
}

export interface IDirectvProgram {
  channel: string;
  channelName?: string;
  ondemand: boolean;
  recorded: boolean;
  recording: boolean;
  viewed: boolean;
  programId?: number;
  programType: TDirectvProgramType;
  duration: number;
  title?: string;
  episodeTitle?: string;
  musicTitle?: string;
  musicAlbum?: string;
  musicArtist?: string;
  partial: boolean;
  payperview: boolean;
  position: number;
  purchased: boolean;
  rating?: string;
  startTime?: string;
  uniqueId?: number;
}

export interface IDirectvLocationState {
  address: string;
  available: boolean;
  authorized: boolean;
  standby: boolean;
  status: TDirectvLocationStatus;
  program?: IDirectvProgram;
  paused?: boolean;
  positionUpdatedAt?: string;
  updatedAt?: string;
  error?: string;
}

export interface IDirectvSnapshot {
  device: IDirectvDeviceInfo;
  locations: IDirectvLocation[];
  states: IDirectvLocationState[];
  online: boolean;
  updatedAt?: string;
  source?: TDirectvSnapshotSource;
  error?: string;
}

export interface IDirectvDeviceUpdate {
  info: IDirectvDeviceInfo;
  locations: IDirectvLocation[];
}

export interface IDirectvGetVersionResponse {
  receiverId?: string;
  stbSoftwareVersion?: string;
  [key: string]: unknown;
}

export interface IDirectvGetLocationsResponse {
  locations?: IDirectvLocationResponse[];
  [key: string]: unknown;
}

export interface IDirectvLocationResponse {
  clientAddr?: string;
  locationName?: string;
  [key: string]: unknown;
}

export interface IDirectvModeResponse {
  mode?: number | string;
  [key: string]: unknown;
}

export interface IDirectvProgramResponse {
  major?: number | string;
  minor?: number | string;
  callsign?: string;
  isVod?: boolean;
  isPartial?: boolean;
  isPpv?: boolean;
  isPurchased?: boolean;
  isRecording?: boolean;
  isViewed?: boolean;
  uniqueId?: number | string;
  programId?: number | string;
  duration?: number | string;
  title?: string;
  episodeTitle?: string;
  music?: {
    title?: string;
    cd?: string;
    by?: string;
    [key: string]: unknown;
  };
  offset?: number | string;
  rating?: string;
  startTime?: number | string;
  [key: string]: unknown;
}

export interface IDirectvSsdpRecord {
  st?: string;
  nt?: string;
  usn?: string;
  location?: string;
  deviceType?: string;
  manufacturer?: string;
  serialNumber?: string;
  headers?: Record<string, string | undefined>;
  upnp?: {
    deviceType?: string;
    friendlyName?: string;
    manufacturer?: string;
    modelName?: string;
    serialNumber?: string;
    serial?: string;
    [key: string]: unknown;
  };
  [key: string]: unknown;
}

export interface IDirectvManualEntry {
  host?: string;
  port?: number;
  id?: string;
  receiverId?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  url?: string;
  location?: string;
  metadata?: Record<string, unknown>;
}
