export const motionEyeDefaultPort = 8765;
export const motionEyeDefaultTimeoutMs = 10000;
export const motionEyeDefaultAdminUsername = 'admin';
export const motionEyeDefaultSurveillanceUsername = 'user';

export const motionEyeKnownActions = [
  'snapshot',
  'record_start',
  'record_stop',
  'lock',
  'unlock',
  'light_on',
  'light_off',
  'alarm_on',
  'alarm_off',
  'up',
  'right',
  'down',
  'left',
  'zoom_in',
  'zoom_out',
  'preset1',
  'preset2',
  'preset3',
  'preset4',
  'preset5',
  'preset6',
  'preset7',
  'preset8',
  'preset9',
] as const;

export type TMotionEyeProtocol = 'http' | 'https';
export type TMotionEyeAuthMode = 'basic' | 'digest' | string;
export type TMotionEyeHttpMethod = 'GET' | 'POST';
export type TMotionEyeCommandType =
  | 'refresh'
  | 'stream_source'
  | 'snapshot_image'
  | 'action'
  | 'set_switch'
  | 'set_text_overlay'
  | 'media_list';
export type TMotionEyeMediaKind = 'images' | 'movies';

export interface IMotionEyeConfig {
  protocol?: TMotionEyeProtocol;
  host?: string;
  port?: number;
  url?: string;
  adminUsername?: string;
  adminPassword?: string;
  surveillanceUsername?: string;
  surveillancePassword?: string;
  timeoutMs?: number;
  name?: string;
  uniqueId?: string;
  manufacturer?: string;
  model?: string;
  streamUrlTemplate?: string;
  connected?: boolean;
  deviceInfo?: IMotionEyeDeviceInfo;
  cameras?: IMotionEyeCamera[];
  rawCameras?: IMotionEyeRawCamera[];
  sensors?: IMotionEyeSensor[];
  switches?: IMotionEyeSwitch[];
  manifest?: Record<string, unknown>;
  serverConfig?: Record<string, unknown>;
  snapshot?: IMotionEyeSnapshot;
}

export interface IHomeAssistantMotioneyeConfig extends IMotionEyeConfig {}
export interface IHomeAssistantMotionEyeConfig extends IMotionEyeConfig {}

export interface IMotionEyeDeviceInfo {
  id?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  host?: string;
  port?: number;
  protocol?: TMotionEyeProtocol;
  url?: string;
  online?: boolean;
}

export interface IMotionEyeRawCamera {
  id?: number | string;
  name?: string;
  host?: string;
  streaming_port?: number | string;
  streaming_auth_mode?: TMotionEyeAuthMode;
  video_streaming?: boolean;
  motion_detection?: boolean;
  text_overlay?: boolean;
  still_images?: boolean;
  movies?: boolean;
  upload_enabled?: boolean;
  actions?: string[];
  root_directory?: string;
  [key: string]: unknown;
}

export interface IMotionEyeCamera {
  id: string;
  numericId?: number;
  name: string;
  host?: string;
  streamingPort?: number;
  streamingAuthMode?: TMotionEyeAuthMode;
  mjpegUrl?: string;
  snapshotUrl?: string;
  isStreaming: boolean;
  motionDetectionEnabled: boolean;
  textOverlayEnabled?: boolean;
  stillImagesEnabled?: boolean;
  moviesEnabled?: boolean;
  uploadEnabled?: boolean;
  actions: string[];
  rootDirectory?: string;
  available?: boolean;
  raw?: IMotionEyeRawCamera;
  attributes?: Record<string, unknown>;
}

export interface IMotionEyeSensor<TValue = unknown> {
  key: string;
  name: string;
  cameraId?: string;
  value: TValue;
  unit?: string;
  deviceClass?: string;
  entityCategory?: string;
  available?: boolean;
  attributes?: Record<string, unknown>;
}

export interface IMotionEyeSwitch {
  key: string;
  name: string;
  cameraId: string;
  isOn: boolean;
  entityCategory?: string;
  available?: boolean;
  attributes?: Record<string, unknown>;
}

export interface IMotionEyeSnapshot {
  deviceInfo: IMotionEyeDeviceInfo;
  cameras: IMotionEyeCamera[];
  sensors: IMotionEyeSensor[];
  switches: IMotionEyeSwitch[];
  rawCameras: IMotionEyeRawCamera[];
  connected: boolean;
  updatedAt?: string;
  manifest?: Record<string, unknown>;
  serverConfig?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
}

export interface IMotionEyeHttpCommand {
  label: string;
  method: TMotionEyeHttpMethod;
  path: string;
  admin: boolean;
  data?: Record<string, unknown>;
}

export interface IMotionEyeCommandResponse {
  ok: boolean;
  label: string;
  method: TMotionEyeHttpMethod;
  path: string;
  status: number;
  response?: unknown;
}

export interface IMotionEyeClientCommand {
  type: TMotionEyeCommandType;
  service: string;
  target?: {
    entityId?: string;
    deviceId?: string;
  };
  data?: Record<string, unknown>;
  cameraId?: string;
  action?: string;
  key?: string;
  enabled?: boolean;
  leftText?: string;
  rightText?: string;
  customLeftText?: string;
  customRightText?: string;
  mediaKind?: TMotionEyeMediaKind;
  prefix?: string;
  filename?: string;
  httpCommands?: IMotionEyeHttpCommand[];
}

export interface IMotionEyeSnapshotImage {
  contentType: string;
  data: Uint8Array;
}

export interface IMotionEyeManualEntry {
  host?: string;
  port?: number;
  url?: string;
  protocol?: TMotionEyeProtocol;
  adminUsername?: string;
  adminPassword?: string;
  surveillanceUsername?: string;
  surveillancePassword?: string;
  id?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  metadata?: Record<string, unknown>;
}

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

export interface IMotionEyeSwitchDescription {
  key: string;
  name: string;
  entityCategory?: string;
}

export const motionEyeSwitchDescriptions: IMotionEyeSwitchDescription[] = [
  { key: 'motion_detection', name: 'Motion detection', entityCategory: 'config' },
  { key: 'text_overlay', name: 'Text overlay', entityCategory: 'config' },
  { key: 'video_streaming', name: 'Video streaming', entityCategory: 'config' },
  { key: 'still_images', name: 'Still images', entityCategory: 'config' },
  { key: 'movies', name: 'Movies', entityCategory: 'config' },
  { key: 'upload_enabled', name: 'Upload enabled', entityCategory: 'config' },
];
