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

export const devoloHomeNetworkDomain = 'devolo_home_network';
export const devoloHomeNetworkDefaultPort = 80;
export const devoloHomeNetworkMdnsType = '_dvl-deviceapi._tcp.local.';

export type TDevoloSnapshotSource = 'manual' | 'snapshot' | 'provider' | 'runtime';
export type TDevoloFeature = 'led' | 'restart' | 'update' | 'wifi1' | string;
export type TDevoloActionName =
  | 'identify'
  | 'pairing'
  | 'restart'
  | 'start_wps'
  | 'set_leds'
  | 'set_guest_wifi'
  | 'install_firmware';
export type TDevoloCommandType =
  | 'plc.identify'
  | 'plc.pair_device'
  | 'device.restart'
  | 'wifi.start_wps'
  | 'device.set_leds'
  | 'wifi.set_guest_access'
  | 'firmware.install';

export interface IDevoloDeviceInfo {
  id?: string;
  host?: string;
  ipAddress?: string;
  port?: number;
  name?: string;
  hostname?: string;
  product?: string;
  model?: string;
  mtNumber?: string;
  serialNumber?: string;
  macAddress?: string;
  firmwareVersion?: string;
  features?: TDevoloFeature[];
  deviceApi?: boolean;
  plcnetApi?: boolean;
  configurationUrl?: string;
  metadata?: Record<string, unknown>;
}

export interface IDevoloPlcDevice {
  id?: string;
  macAddress?: string;
  mac_address?: string;
  name?: string;
  userDeviceName?: string;
  user_device_name?: string;
  product?: string;
  model?: string;
  serialNumber?: string;
  firmwareVersion?: string;
  topology?: 'LOCAL' | 'REMOTE' | 'local' | 'remote' | string;
  attachedToRouter?: boolean;
  attached_to_router?: boolean;
  ipAddress?: string;
  metadata?: Record<string, unknown>;
}

export interface IDevoloPlcLink {
  id?: string;
  fromMac?: string;
  toMac?: string;
  macAddressFrom?: string;
  macAddressTo?: string;
  mac_address_from?: string;
  mac_address_to?: string;
  rxRate?: number;
  txRate?: number;
  rx_rate?: number;
  tx_rate?: number;
  quality?: string | number;
  metadata?: Record<string, unknown>;
}

export interface IDevoloWifiStation {
  id?: string;
  macAddress?: string;
  mac_address?: string;
  name?: string;
  hostname?: string;
  ipAddress?: string;
  ip?: string;
  connected?: boolean;
  vapType?: string | number;
  vap_type?: string | number;
  band?: string | number;
  ssid?: string;
  rssi?: number;
  signal?: number;
  metadata?: Record<string, unknown>;
}

export interface IDevoloNeighborWifiNetwork {
  id?: string;
  ssid?: string;
  bssid?: string;
  macAddress?: string;
  band?: string | number;
  channel?: number;
  rssi?: number;
  signal?: number;
  encryption?: string;
  metadata?: Record<string, unknown>;
}

export interface IDevoloGuestWifiState {
  enabled?: boolean;
  ssid?: string;
  key?: string;
  password?: string;
  band?: string | number;
  duration?: number;
  available?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IDevoloSwitchState {
  enabled?: boolean;
  available?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IDevoloSwitchMap {
  switch_leds?: IDevoloSwitchState | boolean;
  leds?: IDevoloSwitchState | boolean;
  switch_guest_wifi?: IDevoloGuestWifiState | IDevoloSwitchState | boolean;
  guestWifi?: IDevoloGuestWifiState | IDevoloSwitchState | boolean;
  [key: string]: unknown;
}

export interface IDevoloFirmwareUpdate {
  installedVersion?: string;
  currentVersion?: string;
  latestVersion?: string;
  newFirmwareVersion?: string;
  available?: boolean;
  inProgress?: boolean;
  releaseUrl?: string;
  metadata?: Record<string, unknown>;
}

export interface IDevoloSensorMap {
  connected_plc_devices?: number;
  connected_wifi_clients?: number;
  neighboring_wifi_networks?: number;
  plc_rx_rate?: number;
  plc_tx_rate?: number;
  last_restart?: string | number;
  uptimeSeconds?: number;
  [key: string]: unknown;
}

export interface IDevoloActionDescriptor {
  action: TDevoloActionName;
  type: TDevoloCommandType;
  target: 'device' | 'plcnet' | 'wifi' | 'firmware';
  platform?: TEntityPlatform;
  entityId?: string;
  deviceId?: string;
  available?: boolean;
  requiresPassword?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IDevoloEvent {
  type: string;
  timestamp?: number;
  deviceId?: string;
  entityId?: string;
  action?: TDevoloActionName;
  command?: IDevoloCommand;
  data?: unknown;
  error?: string;
  [key: string]: unknown;
}

export interface IDevoloSnapshot {
  connected: boolean;
  source?: TDevoloSnapshotSource;
  updatedAt?: string;
  device: IDevoloDeviceInfo;
  plcDevices: IDevoloPlcDevice[];
  plcLinks: IDevoloPlcLink[];
  wifiStations: IDevoloWifiStation[];
  neighboringWifiNetworks: IDevoloNeighborWifiNetwork[];
  firmware?: IDevoloFirmwareUpdate;
  sensors: IDevoloSensorMap;
  switches: {
    leds?: IDevoloSwitchState;
    guestWifi?: IDevoloGuestWifiState;
  };
  actions: IDevoloActionDescriptor[];
  events: IDevoloEvent[];
  error?: string;
  metadata?: Record<string, unknown>;
}

export interface IDevoloManualEntry {
  id?: string;
  host?: string;
  ipAddress?: string;
  port?: number;
  name?: string;
  hostname?: string;
  product?: string;
  model?: string;
  mtNumber?: string;
  serialNumber?: string;
  macAddress?: string;
  firmwareVersion?: string;
  features?: TDevoloFeature[];
  device?: IDevoloDeviceInfo;
  snapshot?: IDevoloSnapshot;
  plcDevices?: IDevoloPlcDevice[];
  devices?: IDevoloPlcDevice[];
  plcLinks?: IDevoloPlcLink[];
  links?: IDevoloPlcLink[];
  dataRates?: IDevoloPlcLink[];
  wifiStations?: IDevoloWifiStation[];
  stations?: IDevoloWifiStation[];
  clients?: IDevoloWifiStation[];
  neighboringWifiNetworks?: IDevoloNeighborWifiNetwork[];
  neighbors?: IDevoloNeighborWifiNetwork[];
  firmware?: IDevoloFirmwareUpdate;
  sensors?: IDevoloSensorMap;
  switches?: IDevoloSwitchMap;
  actions?: IDevoloActionDescriptor[];
  metadata?: Record<string, unknown>;
  integrationDomain?: string;
  [key: string]: unknown;
}

export interface IDevoloConfig {
  host?: string;
  ipAddress?: string;
  port?: number;
  password?: string;
  name?: string;
  hostname?: string;
  product?: string;
  model?: string;
  mtNumber?: string;
  serialNumber?: string;
  macAddress?: string;
  firmwareVersion?: string;
  features?: TDevoloFeature[];
  connected?: boolean;
  deviceApi?: boolean;
  plcnetApi?: boolean;
  snapshot?: IDevoloSnapshot;
  snapshotProvider?: () => Promise<IDevoloSnapshot | undefined> | IDevoloSnapshot | undefined;
  device?: IDevoloDeviceInfo;
  manualEntries?: IDevoloManualEntry[];
  plcDevices?: IDevoloPlcDevice[];
  devices?: IDevoloPlcDevice[];
  plcLinks?: IDevoloPlcLink[];
  links?: IDevoloPlcLink[];
  dataRates?: IDevoloPlcLink[];
  wifiStations?: IDevoloWifiStation[];
  stations?: IDevoloWifiStation[];
  clients?: IDevoloWifiStation[];
  neighboringWifiNetworks?: IDevoloNeighborWifiNetwork[];
  neighbors?: IDevoloNeighborWifiNetwork[];
  firmware?: IDevoloFirmwareUpdate;
  sensors?: IDevoloSensorMap;
  switches?: IDevoloSwitchMap;
  events?: IDevoloEvent[];
  actions?: IDevoloActionDescriptor[];
  commandExecutor?: TDevoloCommandExecutor;
  nativeClient?: IDevoloNativeClient;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IDevoloCommand {
  type: TDevoloCommandType;
  action: TDevoloActionName;
  service: string;
  target: {
    entityId?: string;
    deviceId?: string;
  };
  deviceId?: string;
  entityId?: string;
  enabled?: boolean;
  requiresPassword?: boolean;
  payload: Record<string, unknown>;
}

export interface IDevoloCommandResult extends IServiceCallResult {}

export type TDevoloCommandExecutor = (
  commandArg: IDevoloCommand
) => Promise<IDevoloCommandResult | unknown> | IDevoloCommandResult | unknown;

export interface IDevoloNativeClient {
  getSnapshot?: () => Promise<IDevoloSnapshot> | IDevoloSnapshot;
  executeCommand?: TDevoloCommandExecutor;
  validate?: (configArg: IDevoloConfig) => Promise<IDevoloDeviceInfo | undefined> | IDevoloDeviceInfo | undefined;
  destroy?: () => Promise<void> | void;
}

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

export interface IDevoloManualDiscoveryRecord extends IDevoloManualEntry {
  manufacturer?: string;
  brand?: string;
}

export interface IHomeAssistantDevoloHomeNetworkConfig extends IDevoloConfig {}
