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

export type TDlinkPowerState = 'ON' | 'OFF' | 'unknown';
export type TDlinkCommandType = 'switch_turn_on' | 'switch_turn_off' | 'set_state';
export type TDlinkEventType = 'snapshot_refreshed' | 'command_mapped' | 'command_succeeded' | 'command_failed' | 'state_changed';

export interface IDlinkDeviceSnapshot {
  id?: string;
  name?: string;
  host?: string;
  port?: number;
  macAddress?: string;
  manufacturer?: string;
  modelName?: string;
  useLegacyProtocol?: boolean;
  authenticated?: boolean;
  available?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IDlinkSwitchSnapshot {
  state: TDlinkPowerState;
  available: boolean;
  temperature?: number | null;
  temperatureRaw?: string;
  currentConsumption?: number | null;
  currentConsumptionRaw?: string;
  totalConsumption?: number | null;
  totalConsumptionRaw?: string;
  attributes?: Record<string, unknown>;
}

export interface IDlinkSnapshot {
  connected: boolean;
  device: IDlinkDeviceSnapshot;
  switch: IDlinkSwitchSnapshot;
  updatedAt?: string;
  events: IDlinkEvent[];
  metadata?: Record<string, unknown>;
}

export interface IDlinkCommand {
  type: TDlinkCommandType;
  method: 'hnap.SetSocketSettings' | 'native_client' | 'executor';
  state: Exclude<TDlinkPowerState, 'unknown'>;
  service: string;
  target?: IServiceCallRequest['target'];
  data?: Record<string, unknown>;
  deviceId?: string;
  entityId?: string;
  host?: string;
  transmitted?: boolean;
  metadata?: Record<string, unknown>;
}

export interface IDlinkCommandResult extends IServiceCallResult {
  transmitted?: boolean;
  state?: TDlinkPowerState;
}

export interface IDlinkEvent {
  type: TDlinkEventType;
  command?: IDlinkCommand;
  deviceId?: string;
  entityId?: string;
  data?: unknown;
  error?: string;
  timestamp: number;
}

export interface IDlinkNativeClient {
  authenticate?(): Promise<boolean>;
  getSnapshot?(): Promise<IDlinkSnapshot | Partial<IDlinkSnapshot>>;
  getModelName?(): Promise<string | undefined>;
  getState?(): Promise<TDlinkPowerState | string | boolean | undefined>;
  setState?(stateArg: Exclude<TDlinkPowerState, 'unknown'>): Promise<IDlinkCommandResult | string | boolean | void>;
  getTemperature?(): Promise<number | string | null | undefined>;
  getCurrentConsumption?(): Promise<number | string | null | undefined>;
  getTotalConsumption?(): Promise<number | string | null | undefined>;
}

export interface IDlinkTransport {
  execute(commandArg: IDlinkCommand): Promise<IDlinkCommandResult | unknown>;
  readSnapshot?(): Promise<IDlinkSnapshot | Partial<IDlinkSnapshot>>;
}

export interface IDlinkManualEntry {
  integrationDomain?: string;
  id?: string;
  host?: string;
  ip?: string;
  ipAddress?: string;
  address?: string;
  port?: number;
  name?: string;
  username?: string;
  password?: string;
  useLegacyProtocol?: boolean;
  use_legacy_protocol?: boolean;
  manufacturer?: string;
  model?: string;
  modelName?: string;
  mac?: string;
  macAddress?: string;
  snapshot?: IDlinkSnapshot;
  state?: TDlinkPowerState | boolean | string;
  temperature?: number | string | null;
  currentConsumption?: number | string | null;
  totalConsumption?: number | string | null;
  metadata?: Record<string, unknown>;
}

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

export interface IDlinkCandidateMetadata extends Record<string, unknown> {
  dlink?: boolean;
  discoveryProtocol?: 'dhcp' | 'manual';
  hostname?: string;
  host?: string;
  username?: string;
  useLegacyProtocol?: boolean;
  snapshot?: IDlinkSnapshot;
  nativeHttpImplemented?: boolean;
}

export interface IDlinkConfig extends IDlinkManualEntry {
  username?: string;
  password?: string;
  useLegacyProtocol?: boolean;
  port?: number;
  timeoutMs?: number;
  nativeHttpEnabled?: boolean;
  connected?: boolean;
  snapshot?: IDlinkSnapshot;
  nativeClient?: IDlinkNativeClient;
  commandExecutor?: (commandArg: IDlinkCommand) => Promise<IDlinkCommandResult | unknown>;
  transport?: IDlinkTransport;
}

export type IHomeAssistantDlinkConfig = IDlinkConfig;
