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

export type TXiaomiMiioDeviceKind =
  | 'vacuum'
  | 'fan'
  | 'light'
  | 'switch'
  | 'sensor'
  | 'cover'
  | 'humidifier'
  | 'gateway'
  | 'unknown'
  | string;

export type TXiaomiMiioEntityPlatform = TEntityPlatform | 'vacuum' | 'humidifier' | string;

export interface IXiaomiMiioConfig {
  host?: string;
  port?: number;
  token?: string;
  model?: string;
  name?: string;
  deviceId?: string;
  macAddress?: string;
  kind?: TXiaomiMiioDeviceKind;
  device?: IXiaomiMiioDeviceState;
  devices?: IXiaomiMiioDeviceState[];
  entities?: IXiaomiMiioEntityDescriptor[];
  state?: IXiaomiMiioStateRecord;
  properties?: IXiaomiMiioProperty[];
  snapshot?: IXiaomiMiioSnapshot;
  events?: IXiaomiMiioEvent[];
  commandExecutor?: TXiaomiMiioCommandExecutor;
  [key: string]: unknown;
}

export interface IHomeAssistantXiaomiMiioConfig extends IXiaomiMiioConfig {}

export interface IXiaomiMiioDeviceInfo {
  id?: string;
  did?: string | number;
  name?: string;
  model?: string;
  manufacturer?: string;
  host?: string;
  port?: number;
  macAddress?: string;
  firmwareVersion?: string;
  hardwareVersion?: string;
  serialNumber?: string;
  kind?: TXiaomiMiioDeviceKind;
  tokenConfigured?: boolean;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IXiaomiMiioDeviceState extends IXiaomiMiioDeviceInfo {
  available?: boolean;
  online?: boolean;
  updatedAt?: string;
  state?: IXiaomiMiioStateRecord;
  properties?: IXiaomiMiioProperty[];
  entities?: IXiaomiMiioEntityDescriptor[];
  children?: IXiaomiMiioDeviceState[];
}

export type IXiaomiMiioStateRecord = Record<string, unknown>;

export interface IXiaomiMiioProperty {
  key: string;
  value?: unknown;
  name?: string;
  unit?: string;
  readable?: boolean;
  writable?: boolean;
  platform?: TXiaomiMiioEntityPlatform;
  kind?: TXiaomiMiioDeviceKind;
  deviceClass?: string;
  category?: string;
  siid?: number;
  piid?: number;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IXiaomiMiioEntityDescriptor {
  id?: string;
  entityId?: string;
  uniqueId?: string;
  unique_id?: string;
  deviceId?: string;
  device_id?: string;
  platform?: TXiaomiMiioEntityPlatform;
  kind?: TXiaomiMiioDeviceKind;
  name?: string;
  state?: unknown;
  value?: unknown;
  propertyKey?: string;
  property_key?: string;
  attributes?: Record<string, unknown>;
  available?: boolean;
  writable?: boolean;
  unit?: string;
  deviceClass?: string;
  device_class?: string;
  [key: string]: unknown;
}

export interface IXiaomiMiioSnapshot {
  connected: boolean;
  configured: boolean;
  host?: string;
  port?: number;
  tokenConfigured?: boolean;
  device?: IXiaomiMiioDeviceState;
  devices: IXiaomiMiioDeviceState[];
  entities: IXiaomiMiioEntityDescriptor[];
  events: IXiaomiMiioEvent[];
  transport?: IXiaomiMiioTransportInfo;
  metadata?: Record<string, unknown>;
}

export interface IXiaomiMiioTransportInfo {
  host?: string;
  port?: number;
  protocol: 'miio-udp' | 'snapshot' | 'manual' | string;
  tokenConfigured: boolean;
  encryptedUdpImplemented: boolean;
}

export interface IXiaomiMiioEvent {
  type: string;
  timestamp?: number;
  deviceId?: string;
  entityId?: string;
  uniqueId?: string;
  command?: IXiaomiMiioClientCommand;
  data?: unknown;
  [key: string]: unknown;
}

export interface IXiaomiMiioClientCommand {
  type: string;
  service: string;
  method?: string;
  params?: unknown[] | Record<string, unknown>;
  platform?: TXiaomiMiioEntityPlatform;
  kind?: TXiaomiMiioDeviceKind;
  deviceId?: string;
  entityId?: string;
  uniqueId?: string;
  propertyKey?: string;
  value?: unknown;
  target?: {
    entityId?: string;
    deviceId?: string;
  };
  payload: Record<string, unknown>;
}

export interface IXiaomiMiioCommandResult extends IServiceCallResult {}

export type TXiaomiMiioCommandExecutor = (
  commandArg: IXiaomiMiioClientCommand
) => Promise<IXiaomiMiioCommandResult | unknown> | IXiaomiMiioCommandResult | unknown;

export interface IXiaomiMiioMdnsRecord {
  type?: string;
  serviceType?: 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 IXiaomiMiioDhcpRecord {
  host?: string;
  ipAddress?: string;
  address?: string;
  hostname?: string;
  hostName?: string;
  macAddress?: string;
  mac?: string;
  manufacturer?: string;
  model?: string;
  vendorClassIdentifier?: string;
  options?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IXiaomiMiioManualEntry {
  host?: string;
  port?: number;
  token?: string;
  model?: string;
  name?: string;
  id?: string;
  macAddress?: string;
  deviceId?: string;
  snapshot?: IXiaomiMiioSnapshot;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}
