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

export type TAirosSnapshotSource = 'snapshot' | 'manual' | 'client' | 'http' | 'transport' | 'runtime';
export type TAirosCommandAction = 'refresh' | 'reboot' | 'download_update' | 'install_update' | 'firmware_update_check';
export type TAirosEventType = 'snapshot_refreshed' | 'command_mapped' | 'command_succeeded' | 'command_failed' | 'state_changed';
export type TAirosWirelessRole = 'access_point' | 'station' | 'unknown';
export type TAirosWirelessMode = 'point_to_point' | 'point_to_multipoint' | 'unknown';

export interface IAirosValueMap {
  [key: string]: unknown;
}

export interface IAirosRawInterface extends IAirosValueMap {
  ifname?: string;
  hwaddr?: string;
  enabled?: boolean;
  status?: IAirosValueMap;
  mtu?: number | null;
}

export interface IAirosRawStatus extends IAirosValueMap {
  host?: IAirosValueMap;
  services?: IAirosValueMap;
  wireless?: IAirosValueMap;
  interfaces?: IAirosRawInterface[];
  portfw?: boolean;
  derived?: Partial<IAirosDerivedSnapshot>;
}

export interface IAirosFirmwareStatus extends IAirosValueMap {
  update?: boolean;
  version?: string;
  changelog?: string;
  url?: string;
  progress?: number;
  ok?: boolean;
  code?: number;
}

export interface IAirosDerivedSnapshot {
  mac?: string;
  macInterface?: string;
  fwMajor?: number;
  sku?: string;
  role?: TAirosWirelessRole;
  mode?: TAirosWirelessMode;
  station?: boolean;
  accessPoint?: boolean;
  ptp?: boolean;
  ptmp?: boolean;
}

export interface IAirosDeviceSnapshot {
  id?: string;
  name?: string;
  host?: string;
  port?: number;
  ssl?: boolean;
  verifySsl?: boolean;
  configurationUrl?: string;
  macAddress?: string;
  manufacturer?: string;
  modelName?: string;
  modelId?: string;
  firmwareVersion?: string;
  firmwareMajor?: number;
  authenticated?: boolean;
  available?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IAirosHostSnapshot {
  hostname?: string;
  uptime?: number;
  cpuLoad?: number | null;
  netRole?: string;
  temperature?: number | null;
  totalRam?: number;
  freeRam?: number;
  attributes?: Record<string, unknown>;
}

export interface IAirosServicesSnapshot {
  dhcpClient?: boolean;
  dhcpServer?: boolean;
  dhcp6Server?: boolean;
  pppoe?: boolean;
  portForwarding?: boolean;
  attributes?: Record<string, unknown>;
}

export interface IAirosWirelessSnapshot {
  essid?: string;
  frequency?: number;
  distance?: number;
  antennaGain?: number | null;
  mode?: TAirosWirelessMode;
  role?: TAirosWirelessRole;
  rawMode?: string;
  pollingDownloadCapacity?: number | null;
  pollingUploadCapacity?: number | null;
  throughputTx?: number | null;
  throughputRx?: number | null;
  attributes?: Record<string, unknown>;
}

export interface IAirosSnapshot {
  connected: boolean;
  source: TAirosSnapshotSource;
  device: IAirosDeviceSnapshot;
  host: IAirosHostSnapshot;
  services: IAirosServicesSnapshot;
  wireless: IAirosWirelessSnapshot;
  firmware?: IAirosFirmwareStatus;
  derived: IAirosDerivedSnapshot;
  rawStatus?: IAirosRawStatus;
  updatedAt?: string;
  events: IAirosEvent[];
  metadata?: Record<string, unknown>;
  error?: string;
}

export interface IAirosCommand {
  action: TAirosCommandAction;
  method: 'refresh' | 'reboot.cgi' | 'api/fw/download' | 'fwflash.cgi' | 'api/fw/update-check' | 'executor' | 'native_client';
  service: string;
  target?: IServiceCallRequest['target'];
  data?: Record<string, unknown>;
  deviceId?: string;
  entityId?: string;
  host?: string;
  transmitted?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IAirosCommandResult extends IServiceCallResult {
  transmitted?: boolean;
  action?: TAirosCommandAction;
}

export interface IAirosEvent {
  type: TAirosEventType;
  command?: IAirosCommand;
  deviceId?: string;
  entityId?: string;
  data?: unknown;
  error?: string;
  timestamp: number;
}

export interface IAirosNativeClient {
  login?(): Promise<boolean | void>;
  getSnapshot?(): Promise<IAirosSnapshot | Partial<IAirosSnapshot>>;
  getRawStatus?(): Promise<IAirosRawStatus>;
  rawStatus?(): Promise<IAirosRawStatus>;
  status?(): Promise<IAirosRawStatus>;
  updateCheck?(forceArg?: boolean): Promise<IAirosFirmwareStatus>;
  update_check?(forceArg?: boolean): Promise<IAirosFirmwareStatus>;
  reboot?(): Promise<IAirosCommandResult | boolean | IAirosValueMap | void>;
  download?(): Promise<IAirosCommandResult | IAirosValueMap | void>;
  install?(): Promise<IAirosCommandResult | IAirosValueMap | void>;
  destroy?(): Promise<void>;
}

export interface IAirosTransport {
  execute(commandArg: IAirosCommand): Promise<IAirosCommandResult | unknown>;
  readSnapshot?(): Promise<IAirosSnapshot | Partial<IAirosSnapshot>>;
}

export type TAirosCommandExecutor = ((commandArg: IAirosCommand) => Promise<IAirosCommandResult | unknown>) | {
  execute(commandArg: IAirosCommand): Promise<IAirosCommandResult | unknown>;
};

export interface IAirosManualEntry {
  integrationDomain?: string;
  id?: string;
  host?: string;
  ip?: string;
  ipAddress?: string;
  address?: string;
  port?: number;
  name?: string;
  username?: string;
  password?: string;
  ssl?: boolean;
  useSsl?: boolean;
  verifySsl?: boolean;
  verify_ssl?: boolean;
  advanced_settings?: {
    ssl?: boolean;
    verify_ssl?: boolean;
    verifySsl?: boolean;
  };
  manufacturer?: string;
  model?: string;
  modelName?: string;
  mac?: string;
  macAddress?: string;
  snapshot?: IAirosSnapshot;
  rawStatus?: IAirosRawStatus;
  firmwareStatus?: IAirosFirmwareStatus;
  metadata?: Record<string, unknown>;
}

export interface IAirosDhcpRecord {
  integrationDomain?: string;
  host?: string;
  ip?: string;
  ipAddress?: string;
  address?: string;
  hostname?: string;
  hostName?: string;
  manufacturer?: string;
  model?: string;
  mac?: string;
  macAddress?: string;
  macaddress?: string;
  registeredDevice?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IAirosLocalDiscoveryRecord {
  integrationDomain?: string;
  host?: string;
  ip?: string;
  ipAddress?: string;
  ip_address?: string;
  hostname?: string | null;
  model?: string | null;
  fullModelName?: string | null;
  full_model_name?: string | null;
  firmwareVersion?: string | null;
  firmware_version?: string | null;
  uptimeSeconds?: number | null;
  uptime_seconds?: number | null;
  ssid?: string | null;
  mac?: string;
  macAddress?: string | null;
  mac_address?: string | null;
  manufacturer?: string;
  metadata?: Record<string, unknown>;
}

export interface IAirosCandidateMetadata extends Record<string, unknown> {
  airos?: boolean;
  discoveryProtocol?: 'dhcp-registered-device' | 'airos-udp-broadcast' | 'manual';
  hostname?: string;
  firmwareVersion?: string;
  fullModelName?: string;
  ssid?: string;
  username?: string;
  ssl?: boolean;
  verifySsl?: boolean;
  snapshot?: IAirosSnapshot;
  rawStatus?: IAirosRawStatus;
  nativeHttpImplemented?: boolean;
}

export interface IAirosConfig extends IAirosManualEntry {
  username?: string;
  password?: string;
  port?: number;
  timeoutMs?: number;
  nativeHttpEnabled?: boolean;
  connected?: boolean;
  snapshot?: IAirosSnapshot;
  rawStatus?: IAirosRawStatus;
  firmwareStatus?: IAirosFirmwareStatus;
  nativeClient?: IAirosNativeClient;
  commandExecutor?: TAirosCommandExecutor;
  transport?: IAirosTransport;
}

export type IHomeAssistantAirosConfig = IAirosConfig;
