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

export type TZhaRadioType = 'ezsp' | 'znp' | 'deconz' | 'xbee' | 'zigate' | 'efr32' | 'ti_cc' | string;
export type TZhaFlowControl = 'hardware' | 'software' | 'none' | null;
export type TZhaClusterType = 'in' | 'out' | 'client' | 'server' | string;
export type TZhaEntityPlatform = TEntityPlatform | 'lock' | 'alarm_control_panel' | 'device_tracker' | 'siren' | 'valve' | string;

export interface IZhaConfig {
  radio?: IZhaRadioConfig;
  device?: IZhaRadioDeviceSettings;
  radioType?: TZhaRadioType;
  radio_type?: TZhaRadioType;
  usbPath?: string;
  usb_path?: string;
  databasePath?: string;
  database?: string;
  enableQuirks?: boolean;
  enable_quirks?: boolean;
  customQuirksPath?: string;
  custom_quirks_path?: string;
  zigpy?: Record<string, unknown>;
  zigpy_config?: Record<string, unknown>;
  deviceConfig?: Record<string, unknown>;
  device_config?: Record<string, unknown>;
  snapshot?: IZhaSnapshot;
  devices?: IZhaDevice[];
  entities?: IZhaEntityDescriptor[];
  groups?: IZhaGroup[];
  network?: IZhaNetworkInfo;
  coordinator?: IZhaCoordinatorInfo;
  events?: IZhaEvent[];
  commandExecutor?: TZhaCommandExecutor;
  [key: string]: unknown;
}

export interface IHomeAssistantZhaConfig extends IZhaConfig {}

export interface IZhaRadioConfig {
  path?: string;
  devicePath?: string;
  radioType?: TZhaRadioType;
  baudrate?: number;
  flowControl?: TZhaFlowControl;
  host?: string;
  port?: number;
  socketUrl?: string;
  serialNumber?: string;
  manufacturer?: string;
  model?: string;
  txPower?: number;
  [key: string]: unknown;
}

export interface IZhaRadioDeviceSettings {
  path?: string;
  baudrate?: number;
  flow_control?: TZhaFlowControl;
  flowControl?: TZhaFlowControl;
  [key: string]: unknown;
}

export interface IZhaUsbRecord {
  vid?: string;
  pid?: string;
  manufacturer?: string;
  description?: string;
  path?: string;
  device?: string;
  serialNumber?: string;
  serial_number?: string;
  product?: string;
  [key: string]: unknown;
}

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

export interface IZhaManualEntry {
  path?: string;
  radioPath?: string;
  devicePath?: string;
  usbPath?: string;
  socketUrl?: string;
  host?: string;
  port?: number;
  id?: string;
  name?: string;
  model?: string;
  manufacturer?: string;
  radioType?: TZhaRadioType;
  baudrate?: number;
  flowControl?: TZhaFlowControl;
  snapshot?: IZhaSnapshot;
  metadata?: Record<string, unknown>;
}

export interface IZhaSnapshot {
  connected: boolean;
  radio?: IZhaRadioConfig;
  network?: IZhaNetworkInfo;
  coordinator?: IZhaCoordinatorInfo;
  devices: IZhaDevice[];
  entities: IZhaEntityDescriptor[];
  groups: IZhaGroup[];
  events: IZhaEvent[];
}

export interface IZhaNetworkInfo {
  panId?: number | string;
  pan_id?: number | string;
  extendedPanId?: string;
  extended_pan_id?: string;
  channel?: number;
  channels?: number[];
  networkKey?: string;
  network_key?: string;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IZhaCoordinatorInfo {
  ieee?: string;
  manufacturer?: string;
  model?: string;
  version?: string;
  radioType?: TZhaRadioType;
  path?: string;
  [key: string]: unknown;
}

export interface IZhaDevice {
  ieee?: string;
  nwk?: number | string;
  name?: string;
  manufacturer?: string;
  model?: string;
  available?: boolean;
  isActiveCoordinator?: boolean;
  active_coordinator?: boolean;
  lqi?: number;
  rssi?: number;
  lastSeen?: string | number;
  last_seen?: string | number;
  powerSource?: string;
  power_source?: string;
  deviceType?: string;
  device_type?: string;
  quirkApplied?: boolean;
  quirk_applied?: boolean;
  quirkClass?: string;
  quirk_class?: string;
  manufacturerCode?: number;
  manufacturer_code?: number;
  endpoints?: IZhaEndpoint[] | Record<string, IZhaEndpoint>;
  entities?: IZhaEntityDescriptor[];
  signature?: Record<string, unknown>;
  exposesFeatures?: unknown;
  exposes_features?: unknown;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IZhaEndpoint {
  id?: number;
  endpointId?: number;
  endpoint_id?: number;
  profileId?: number;
  profile_id?: number;
  deviceType?: string | number;
  device_type?: string | number;
  name?: string;
  inClusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  in_clusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  inputClusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  outClusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  out_clusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  outputClusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  clusters?: IZhaCluster[] | Record<string, IZhaCluster>;
  [key: string]: unknown;
}

export interface IZhaCluster {
  id?: number;
  clusterId?: number;
  cluster_id?: number;
  endpointId?: number;
  endpoint_id?: number;
  type?: TZhaClusterType;
  clusterType?: TZhaClusterType;
  cluster_type?: TZhaClusterType;
  name?: string;
  attributes?: IZhaAttribute[] | Record<string, IZhaAttribute | unknown>;
  commands?: IZhaCommand[] | Record<string, IZhaCommand>;
  serverCommands?: IZhaCommand[] | Record<string, IZhaCommand>;
  server_commands?: IZhaCommand[] | Record<string, IZhaCommand>;
  clientCommands?: IZhaCommand[] | Record<string, IZhaCommand>;
  client_commands?: IZhaCommand[] | Record<string, IZhaCommand>;
  [key: string]: unknown;
}

export interface IZhaAttribute {
  id?: number | string;
  attributeId?: number | string;
  attribute_id?: number | string;
  name?: string;
  value?: unknown;
  type?: string;
  unit?: string;
  manufacturer?: number | string;
  [key: string]: unknown;
}

export interface IZhaCommand {
  id?: number | string;
  commandId?: number | string;
  command_id?: number | string;
  name?: string;
  type?: string;
  schema?: unknown;
  args?: unknown[];
  params?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IZhaEntityDescriptor {
  platform?: TZhaEntityPlatform;
  entityId?: string;
  entity_id?: string;
  uniqueId?: string;
  unique_id?: string;
  deviceId?: string;
  device_id?: string;
  deviceIeee?: string;
  ieee?: string;
  endpointId?: number;
  endpoint_id?: number;
  clusterId?: number;
  cluster_id?: number;
  clusterType?: TZhaClusterType;
  cluster_type?: TZhaClusterType;
  name?: string;
  originalName?: string;
  original_name?: string;
  fallbackName?: string;
  fallback_name?: string;
  state?: unknown;
  nativeValue?: unknown;
  native_value?: unknown;
  value?: unknown;
  isOn?: boolean;
  is_on?: boolean;
  isLocked?: boolean;
  is_locked?: boolean;
  isClosed?: boolean;
  is_closed?: boolean;
  available?: boolean;
  deviceClass?: string;
  device_class?: string;
  unit?: string;
  unitOfMeasurement?: string;
  unit_of_measurement?: string;
  currentCoverPosition?: number;
  current_cover_position?: number;
  currentTemperature?: number;
  current_temperature?: number;
  targetTemperature?: number;
  target_temperature?: number;
  hvacMode?: string;
  hvac_mode?: string;
  attributes?: Record<string, unknown>;
  infoObject?: Record<string, unknown>;
  info_object?: Record<string, unknown>;
  raw?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IZhaGroup {
  groupId?: number;
  group_id?: number;
  name?: string;
  members?: IZhaGroupMember[];
  entities?: IZhaEntityDescriptor[];
  [key: string]: unknown;
}

export interface IZhaGroupMember {
  ieee?: string;
  endpointId?: number;
  endpoint_id?: number;
  device?: IZhaDevice;
  [key: string]: unknown;
}

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

export interface IZhaClientCommand {
  type: string;
  service: string;
  platform?: TZhaEntityPlatform;
  ieee?: string;
  endpointId?: number;
  clusterId?: number;
  clusterType?: TZhaClusterType;
  command?: number | string;
  commandType?: string;
  attribute?: number | string;
  value?: unknown;
  args?: unknown[];
  params?: Record<string, unknown>;
  groupId?: number;
  entityId?: string;
  uniqueId?: string;
  payload: Record<string, unknown>;
  target?: {
    entityId?: string;
    deviceId?: string;
  };
}

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

export type TZhaCommandExecutor = (
  commandArg: IZhaClientCommand
) => Promise<IZhaCommandResult | unknown> | IZhaCommandResult | unknown;
