import type { IServiceCallRequest, TEntityPlatform } from '../../core/types.js';

export const wizDefaultPort = 38899;

export type TWizBulbType = 'rgb' | 'tw' | 'dw' | 'socket' | 'fan' | 'unknown' | string;
export type TWizDiscoveryProtocol = 'mdns' | 'udp' | 'manual';

export interface IWizConfig {
  host?: string;
  port?: number;
  mac?: string;
  name?: string;
  deviceInfo?: IWizDeviceInfo;
  pilot?: IWizPilotState;
  snapshot?: IWizSnapshot;
  devices?: IWizSnapshotDevice[];
  manualEntries?: IWizManualEntry[];
  events?: IWizEvent[];
  timeoutMs?: number;
  commandExecutor?: TWizCommandExecutor;
  [key: string]: unknown;
}

export interface IHomeAssistantWizConfig extends IWizConfig {}

export interface IWizDeviceFeatures {
  light?: boolean;
  switch?: boolean;
  brightness?: boolean;
  color?: boolean;
  colorTemp?: boolean;
  effect?: boolean;
  fan?: boolean;
  fanReverse?: boolean;
  fanBreezeMode?: boolean;
  power?: boolean;
  occupancy?: boolean;
  button?: boolean;
  dualHead?: boolean;
  [key: string]: unknown;
}

export interface IWizKelvinRange {
  min?: number;
  max?: number;
}

export interface IWizDeviceInfo {
  id?: string;
  mac?: string;
  host?: string;
  port?: number;
  name?: string;
  manufacturer?: string;
  model?: string;
  moduleName?: string;
  fwVersion?: string;
  typeId?: number | string;
  bulbType?: TWizBulbType;
  isSocket?: boolean;
  whiteChannels?: number;
  kelvinRange?: IWizKelvinRange;
  fanSpeedRange?: number;
  powerMonitoring?: boolean;
  features?: IWizDeviceFeatures;
  [key: string]: unknown;
}

export interface IWizPilotState {
  mac?: string;
  rssi?: number;
  src?: string;
  state?: boolean;
  sceneId?: number;
  schdPsetId?: number;
  temp?: number;
  dimming?: number;
  r?: number;
  g?: number;
  b?: number;
  c?: number;
  w?: number;
  speed?: number;
  ratio?: number;
  pc?: number;
  fanState?: number;
  fanMode?: number;
  fanSpeed?: number;
  fanRevrs?: number;
  [key: string]: unknown;
}

export interface IWizPilotPatch {
  state?: boolean;
  sceneId?: number;
  temp?: number;
  dimming?: number;
  r?: number;
  g?: number;
  b?: number;
  c?: number;
  w?: number;
  speed?: number;
  ratio?: number;
  fanState?: number;
  fanMode?: number;
  fanSpeed?: number;
  fanRevrs?: number;
  [key: string]: unknown;
}

export interface IWizSensorRecord {
  key: string;
  name?: string;
  platform?: 'sensor' | 'binary_sensor';
  value?: unknown;
  unit?: string;
  deviceClass?: string;
  writable?: boolean;
  available?: boolean;
  [key: string]: unknown;
}

export interface IWizButtonRecord {
  key: string;
  name?: string;
  value?: unknown;
  lastPressedAt?: string | number;
  available?: boolean;
  [key: string]: unknown;
}

export interface IWizEntityRecord {
  platform: TEntityPlatform;
  key?: string;
  entityId?: string;
  uniqueId?: string;
  name?: string;
  state?: unknown;
  attributes?: Record<string, unknown>;
  available?: boolean;
  writable?: boolean;
  [key: string]: unknown;
}

export interface IWizSnapshotDevice {
  id?: string;
  host?: string;
  port?: number;
  mac?: string;
  name?: string;
  available?: boolean;
  deviceInfo?: IWizDeviceInfo;
  pilot?: IWizPilotState;
  sensors?: IWizSensorRecord[];
  buttons?: IWizButtonRecord[];
  entities?: IWizEntityRecord[];
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IWizSnapshot {
  connected: boolean;
  host?: string;
  port?: number;
  devices: IWizSnapshotDevice[];
  events: IWizEvent[];
}

export interface IWizEvent {
  type: 'pilot' | 'command_mapped' | 'command_failed' | 'udp_response' | 'error' | string;
  timestamp?: number;
  deviceId?: string;
  entityId?: string;
  command?: IWizClientCommand;
  data?: unknown;
  [key: string]: unknown;
}

export interface IWizClientCommand {
  type: string;
  service: string;
  deviceId?: string;
  entityId?: string;
  payload: IWizPilotPatch;
  target?: IServiceCallRequest['target'];
  [key: string]: unknown;
}

export interface IWizCommandResult {
  success: boolean;
  error?: string;
  data?: unknown;
}

export type TWizCommandExecutor = (
  commandArg: IWizClientCommand
) => Promise<IWizCommandResult | unknown> | IWizCommandResult | unknown;

export interface IWizUdpCommand<TParams extends Record<string, unknown> = Record<string, unknown>> {
  method: string;
  params?: TParams;
  id?: number | string;
  env?: string;
}

export interface IWizUdpError {
  code?: number;
  message?: string;
  data?: unknown;
}

export interface IWizUdpResponse<TResult = unknown> {
  method?: string;
  env?: string;
  id?: number | string;
  result?: TResult;
  params?: TResult;
  error?: IWizUdpError;
  [key: string]: unknown;
}

export interface IWizMdnsRecord {
  type?: string;
  name?: string;
  host?: string;
  hostname?: string;
  addresses?: string[];
  port?: number;
  txt?: Record<string, string | undefined>;
  properties?: Record<string, string | undefined>;
  [key: string]: unknown;
}

export interface IWizUdpDiscoveryRecord {
  host?: string;
  address?: string;
  ip?: string;
  ip_address?: string;
  port?: number;
  mac?: string;
  mac_address?: string;
  name?: string;
  method?: string;
  result?: Record<string, unknown>;
  response?: IWizUdpResponse<Record<string, unknown>>;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IWizManualEntry {
  host?: string;
  port?: number;
  id?: string;
  mac?: string;
  macAddress?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  deviceInfo?: IWizDeviceInfo;
  pilot?: IWizPilotState;
  snapshot?: IWizSnapshot;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}
