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

export const asuswrtDomain = 'asuswrt';
export const asuswrtDefaultHttpPort = 80;
export const asuswrtDefaultHttpsPort = 8443;
export const asuswrtDefaultSshPort = 22;
export const asuswrtDefaultTelnetPort = 23;
export const asuswrtDefaultInterface = 'eth0';
export const asuswrtDefaultDnsmasqPath = '/var/lib/misc';
export const asuswrtDefaultConsiderHomeSeconds = 180;

export type TAsuswrtProtocol = 'http' | 'https' | 'ssh' | 'telnet';
export type TAsuswrtMode = 'router' | 'ap';
export type TAsuswrtSnapshotSource = 'snapshot' | 'manual' | 'provider' | 'runtime';
export type TAsuswrtCommandType = 'router.reboot' | 'client.action';
export type TAsuswrtRouterAction = 'reboot';
export type TAsuswrtClientAction = 'reconnect' | 'disconnect' | 'block' | 'unblock';
export type TAsuswrtAction = TAsuswrtRouterAction | TAsuswrtClientAction;

export interface IAsuswrtConfig {
  host?: string;
  port?: number;
  protocol?: TAsuswrtProtocol;
  username?: string;
  password?: string;
  sshKey?: string;
  mode?: TAsuswrtMode;
  interface?: string;
  dnsmasq?: string;
  requireIp?: boolean;
  trackUnknown?: boolean;
  considerHomeSeconds?: number;
  connected?: boolean;
  uniqueId?: string;
  name?: string;
  snapshot?: IAsuswrtSnapshot;
  router?: IAsuswrtRouterInfo;
  devices?: IAsuswrtClientDevice[];
  clients?: IAsuswrtClientDevice[];
  interfaces?: IAsuswrtInterfaceStats[];
  sensors?: IAsuswrtSensorMap;
  actions?: IAsuswrtActionDescriptor[];
  manualEntries?: IAsuswrtManualEntry[];
  events?: IAsuswrtEvent[];
  snapshotProvider?: TAsuswrtSnapshotProvider;
  commandExecutor?: TAsuswrtCommandExecutor;
  nativeClient?: IAsuswrtNativeClient;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IHomeAssistantAsuswrtConfig extends IAsuswrtConfig {}

export interface IAsuswrtRouterInfo {
  id?: string;
  host?: string;
  port?: number;
  name?: string;
  model?: string;
  modelId?: string;
  serialNumber?: string;
  firmware?: string;
  macAddress?: string;
  labelMac?: string;
  configurationUrl?: string;
  mode?: TAsuswrtMode;
  protocol?: TAsuswrtProtocol;
  manufacturer?: string;
  actions?: TAsuswrtRouterAction[];
  metadata?: Record<string, unknown>;
}

export interface IAsuswrtClientDevice {
  id?: string;
  mac?: string;
  macAddress?: string;
  name?: string;
  hostname?: string;
  ip?: string;
  ipAddress?: string;
  connected?: boolean;
  connectedTo?: string;
  node?: string;
  interface?: string;
  lastActivity?: string | number | Date;
  manufacturer?: string;
  model?: string;
  actions?: TAsuswrtClientAction[];
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAsuswrtInterfaceStats {
  id?: string;
  name: string;
  label?: string;
  connected?: boolean;
  macAddress?: string;
  ipAddress?: string;
  rxBytes?: number;
  txBytes?: number;
  rxRate?: number;
  txRate?: number;
  downloadBytes?: number;
  uploadBytes?: number;
  downloadRate?: number;
  uploadRate?: number;
  metadata?: Record<string, unknown>;
}

export interface IAsuswrtSensorMap {
  sensor_connected_device?: number;
  sensor_rx_bytes?: number;
  sensor_tx_bytes?: number;
  sensor_rx_rates?: number;
  sensor_tx_rates?: number;
  sensor_load_avg1?: number;
  sensor_load_avg5?: number;
  sensor_load_avg15?: number;
  '2.4GHz'?: number;
  '5.0GHz'?: number;
  CPU?: number;
  '5.0GHz_2'?: number;
  '6.0GHz'?: number;
  mem_usage_perc?: number;
  mem_free?: number;
  mem_used?: number;
  sensor_last_boot?: string | number;
  sensor_uptime?: number;
  cpu_total_usage?: number;
  cpu1_usage?: number;
  cpu2_usage?: number;
  cpu3_usage?: number;
  cpu4_usage?: number;
  cpu5_usage?: number;
  cpu6_usage?: number;
  cpu7_usage?: number;
  cpu8_usage?: number;
  [key: string]: string | number | boolean | null | undefined;
}

export interface IAsuswrtActionDescriptor {
  target: 'router' | 'client';
  action: TAsuswrtAction;
  service?: string;
  mac?: string;
  entityId?: string;
  deviceId?: string;
  label?: string;
  metadata?: Record<string, unknown>;
}

export interface IAsuswrtSnapshot {
  connected: boolean;
  source?: TAsuswrtSnapshotSource;
  updatedAt?: string;
  router: IAsuswrtRouterInfo;
  devices: IAsuswrtClientDevice[];
  interfaces: IAsuswrtInterfaceStats[];
  sensors: IAsuswrtSensorMap;
  actions?: IAsuswrtActionDescriptor[];
  events?: IAsuswrtEvent[];
  error?: string;
  metadata?: Record<string, unknown>;
}

export interface IAsuswrtManualEntry {
  id?: string;
  host?: string;
  port?: number;
  protocol?: TAsuswrtProtocol;
  mode?: TAsuswrtMode;
  name?: string;
  manufacturer?: string;
  model?: string;
  macAddress?: string;
  router?: IAsuswrtRouterInfo;
  devices?: IAsuswrtClientDevice[];
  clients?: IAsuswrtClientDevice[];
  interfaces?: IAsuswrtInterfaceStats[];
  sensors?: IAsuswrtSensorMap;
  actions?: IAsuswrtActionDescriptor[];
  snapshot?: IAsuswrtSnapshot;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAsuswrtManualDiscoveryRecord extends IAsuswrtManualEntry {
  integrationDomain?: string;
}

export interface IAsuswrtCommand {
  type: TAsuswrtCommandType;
  service: string;
  action: TAsuswrtAction;
  target: {
    entityId?: string;
    deviceId?: string;
  };
  protocol?: TAsuswrtProtocol;
  routerId?: string;
  mac?: string;
  entityId?: string;
  deviceId?: string;
  payload?: Record<string, unknown>;
}

export interface IAsuswrtCommandResult extends IServiceCallResult {}

export interface IAsuswrtEvent {
  type: string;
  timestamp?: number;
  deviceId?: string;
  entityId?: string;
  command?: IAsuswrtCommand;
  snapshot?: IAsuswrtSnapshot;
  error?: string;
  data?: unknown;
  [key: string]: unknown;
}

export interface IAsuswrtNativeClient {
  getSnapshot(): Promise<IAsuswrtSnapshot> | IAsuswrtSnapshot;
  executeCommand?(commandArg: IAsuswrtCommand): Promise<IAsuswrtCommandResult | unknown> | IAsuswrtCommandResult | unknown;
  destroy?(): Promise<void> | void;
}

export type TAsuswrtSnapshotProvider = () => Promise<IAsuswrtSnapshot | undefined> | IAsuswrtSnapshot | undefined;
export type TAsuswrtCommandExecutor = (
  commandArg: IAsuswrtCommand
) => Promise<IAsuswrtCommandResult | unknown> | IAsuswrtCommandResult | unknown;
