export type TDeconzProtocol = 'http' | 'https';

export type TDeconzResource = 'config' | 'groups' | 'lights' | 'scenes' | 'sensors';

export type TDeconzWebsocketEventName = 'added' | 'changed' | 'deleted' | 'scene-called';

export type TDeconzCommandMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';

export type TDeconzStateValue = string | number | boolean | null | undefined | number[] | string[] | Record<string, unknown>;

export interface IDeconzConfig {
  host?: string;
  port?: number;
  apiKey?: string;
  protocol?: TDeconzProtocol;
  bridgeId?: string;
  websocketPort?: number;
  enableWebSocket?: boolean;
  snapshot?: IDeconzSnapshot;
}

export interface IDeconzGatewayConfig {
  apiversion?: string;
  bridgeid?: string;
  devicename?: string;
  fwversion?: string;
  ipaddress?: string;
  mac?: string;
  modelid?: string;
  name?: string;
  swversion?: string;
  uuid?: string;
  websocketnotifyall?: boolean;
  websocketport?: number;
  [key: string]: unknown;
}

export interface IDeconzLightState {
  alert?: string;
  bri?: number;
  colormode?: string;
  ct?: number;
  effect?: string;
  hue?: number;
  lift?: number | 'stop';
  on?: boolean;
  open?: boolean;
  reachable?: boolean;
  sat?: number;
  speed?: number;
  stop?: boolean;
  tilt?: number;
  xy?: [number, number] | number[];
  [key: string]: TDeconzStateValue;
}

export interface IDeconzLight {
  id?: string;
  colorcapabilities?: number;
  ctmax?: number;
  ctmin?: number;
  etag?: string;
  hascolor?: boolean;
  lastannounced?: string;
  lastseen?: string;
  manufacturername?: string;
  modelid?: string;
  name?: string;
  state?: IDeconzLightState;
  swversion?: string;
  type?: string;
  uniqueid?: string;
  [key: string]: unknown;
}

export interface IDeconzGroupState {
  all_on?: boolean;
  any_on?: boolean;
  [key: string]: TDeconzStateValue;
}

export interface IDeconzSceneReference {
  id: string;
  name?: string;
}

export interface IDeconzGroup {
  id?: string;
  action?: IDeconzLightState;
  devicemembership?: string[];
  etag?: string;
  hidden?: boolean;
  lights?: string[];
  lightsequence?: string[];
  multideviceids?: string[];
  name?: string;
  scenes?: IDeconzSceneReference[] | Record<string, IDeconzSceneReference>;
  state?: IDeconzGroupState;
  type?: string;
  class?: string;
  [key: string]: unknown;
}

export interface IDeconzSensorState {
  airquality?: string;
  airqualityppb?: number;
  alarm?: boolean;
  battery?: number;
  buttonevent?: number | null;
  carbonmonoxide?: boolean;
  consumption?: number;
  current?: number;
  dark?: boolean;
  daylight?: boolean;
  fire?: boolean;
  flag?: boolean;
  gesture?: number;
  humidity?: number;
  lastupdated?: string;
  lightlevel?: number;
  lux?: number;
  open?: boolean;
  power?: number;
  presence?: boolean;
  pressure?: number;
  status?: number;
  temperature?: number;
  vibration?: boolean;
  voltage?: number;
  water?: boolean;
  [key: string]: TDeconzStateValue;
}

export interface IDeconzSensorConfig {
  battery?: number | null;
  coolsetpoint?: number;
  fanmode?: string;
  heatsetpoint?: number;
  locked?: boolean;
  lowbattery?: boolean;
  mode?: string;
  offset?: number;
  on?: boolean;
  preset?: string;
  reachable?: boolean;
  tampered?: boolean;
  temperature?: number;
  valve?: number;
  [key: string]: TDeconzStateValue;
}

export interface IDeconzSensor {
  id?: string;
  config?: IDeconzSensorConfig;
  ep?: number;
  etag?: string;
  lastseen?: string;
  manufacturername?: string;
  mode?: number;
  modelid?: string;
  name?: string;
  state?: IDeconzSensorState;
  swversion?: string;
  type?: string;
  uniqueid?: string;
  [key: string]: unknown;
}

export interface IDeconzSceneLightState {
  id?: string;
  bri?: number;
  ct?: number;
  hue?: number;
  on?: boolean;
  sat?: number;
  transitiontime?: number;
  x?: number;
  y?: number;
  xy?: [number, number] | number[];
  [key: string]: TDeconzStateValue;
}

export interface IDeconzScene {
  id?: string;
  groupId?: string;
  lights?: string[] | IDeconzSceneLightState[];
  name?: string;
  state?: number;
  [key: string]: unknown;
}

export interface IDeconzSnapshot {
  config?: IDeconzGatewayConfig;
  groups: Record<string, IDeconzGroup>;
  lights: Record<string, IDeconzLight>;
  sensors: Record<string, IDeconzSensor>;
  scenes?: Record<string, IDeconzScene>;
  [key: string]: unknown;
}

export interface IDeconzLightStatePatch extends Partial<IDeconzLightState> {}

export interface IDeconzGroupActionPatch extends Partial<IDeconzLightState> {}

export interface IDeconzSensorConfigPatch extends Partial<IDeconzSensorConfig> {}

export interface IDeconzSensorStatePatch extends Partial<IDeconzSensorState> {}

export interface IDeconzCommand {
  method: TDeconzCommandMethod;
  path: string;
  data?: Record<string, unknown>;
  resource?: TDeconzResource;
  resourceId?: string;
}

export interface IDeconzWebsocketEvent {
  t?: 'event';
  e: TDeconzWebsocketEventName;
  r: 'groups' | 'lights' | 'scenes' | 'sensors';
  id?: string;
  gid?: string;
  scid?: string;
  uniqueid?: string;
  name?: string;
  config?: IDeconzSensorConfig;
  state?: IDeconzGroupState | IDeconzLightState | IDeconzSensorState;
  group?: IDeconzGroup;
  light?: IDeconzLight;
  sensor?: IDeconzSensor;
  scene?: IDeconzScene;
  [key: string]: unknown;
}

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

export interface IDeconzSsdpRecord {
  ssdpLocation?: string;
  location?: string;
  manufacturer?: string;
  manufacturerURL?: string;
  modelName?: string;
  modelNumber?: string;
  friendlyName?: string;
  serialNumber?: string;
  upnp?: Record<string, string | undefined>;
}

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

export interface IDeconzDiscoveryRecord {
  id?: string;
  internalipaddress?: string;
  internalport?: string | number;
  macaddress?: string;
  name?: string;
}
