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

export const airgradientDefaultPort = 80;
export const airgradientMdnsType = '_airgradient._tcp.local';
export const airgradientMinFirmwareVersion = '3.1.1';

export type TAirgradientProtocol = 'http' | 'https';
export type TAirgradientConfigurationControl = 'cloud' | 'local' | 'both';
export type TAirgradientPmStandard = 'ugm3' | 'us-aqi';
export type TAirgradientDisplayPmStandard = 'ugm3' | 'us_aqi';
export type TAirgradientTemperatureUnit = 'c' | 'f';
export type TAirgradientLedBarMode = 'off' | 'co2' | 'pm';

export type TAirgradientConfigField =
  | 'pmStandard'
  | 'temperatureUnit'
  | 'configurationControl'
  | 'ledBarMode'
  | 'co2CalibrationRequested'
  | 'ledBarTestRequested'
  | 'displayBrightness'
  | 'ledBarBrightness'
  | 'postDataToAirGradient'
  | 'abcDays'
  | 'noxLearningOffset'
  | 'tvocLearningOffset';

export interface IAirgradientConfig {
  host?: string;
  port?: number;
  protocol?: TAirgradientProtocol;
  timeoutMs?: number;
  name?: string;
  uniqueId?: string;
  serialNumber?: string;
  model?: string;
  firmwareVersion?: string;
  latestFirmwareVersion?: string;
  connected?: boolean;
  measures?: IAirgradientMeasures;
  deviceConfig?: IAirgradientDeviceConfig;
  deviceInfo?: IAirgradientDeviceInfo;
  snapshot?: IAirgradientSnapshot;
  devices?: IAirgradientDevice[];
  manualEntries?: IAirgradientManualEntry[];
  events?: IAirgradientEvent[];
  checkFirmwareUpdate?: boolean;
  commandExecutor?: TAirgradientCommandExecutor;
  [key: string]: unknown;
}

export interface IHomeAssistantAirgradientConfig extends IAirgradientConfig {}

export interface IAirgradientDeviceInfo {
  id?: string;
  host?: string;
  port?: number;
  protocol?: TAirgradientProtocol;
  name?: string;
  manufacturer?: string;
  model?: string;
  modelName?: string;
  serialNumber?: string;
  firmwareVersion?: string;
  latestFirmwareVersion?: string;
  [key: string]: unknown;
}

export interface IAirgradientMeasures {
  signalStrength?: number;
  serialNumber?: string;
  bootTime?: number;
  firmwareVersion?: string;
  model?: string;
  rco2?: number | null;
  pm01?: number | null;
  pm02?: number | null;
  rawPm02?: number | null;
  compensatedPm02?: number | null;
  pm10?: number | null;
  totalVolatileOrganicComponentIndex?: number | null;
  rawTotalVolatileOrganicComponent?: number | null;
  pm003Count?: number | null;
  nitrogenIndex?: number | null;
  rawNitrogen?: number | null;
  ambientTemperature?: number | null;
  rawAmbientTemperature?: number | null;
  compensatedAmbientTemperature?: number | null;
  relativeHumidity?: number | null;
  rawRelativeHumidity?: number | null;
  compensatedRelativeHumidity?: number | null;
  raw?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAirgradientDeviceConfig {
  country?: string;
  pmStandard?: TAirgradientPmStandard;
  ledBarMode?: TAirgradientLedBarMode;
  co2AutomaticBaselineCalibrationDays?: number;
  temperatureUnit?: TAirgradientTemperatureUnit;
  configurationControl?: TAirgradientConfigurationControl;
  postDataToAirGradient?: boolean;
  ledBarBrightness?: number;
  displayBrightness?: number;
  noxLearningOffset?: number;
  tvocLearningOffset?: number;
  raw?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAirgradientDevice {
  id?: string;
  host?: string;
  port?: number;
  protocol?: TAirgradientProtocol;
  name?: string;
  manufacturer?: string;
  model?: string;
  modelName?: string;
  serialNumber?: string;
  firmwareVersion?: string;
  latestFirmwareVersion?: string;
  online?: boolean;
  measures?: IAirgradientMeasures;
  config?: IAirgradientDeviceConfig;
  attributes?: Record<string, unknown>;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IAirgradientSnapshot {
  connected: boolean;
  updatedAt: string;
  devices: IAirgradientDevice[];
  events: IAirgradientEvent[];
  raw?: Record<string, unknown>;
}

export type TAirgradientEventType =
  | 'snapshot_refreshed'
  | 'command_mapped'
  | 'command_executed'
  | 'command_failed'
  | 'error';

export interface IAirgradientEvent {
  type: TAirgradientEventType | string;
  timestamp: number;
  deviceId?: string;
  entityId?: string;
  command?: IAirgradientCommand;
  data?: unknown;
  [key: string]: unknown;
}

export type IAirgradientCommand = IAirgradientSetConfigCommand | IAirgradientRefreshCommand;

export interface IAirgradientSetConfigCommand {
  type: 'set_config';
  service: string;
  field: TAirgradientConfigField;
  value: unknown;
  payload: Partial<Record<TAirgradientConfigField, unknown>>;
  deviceId?: string;
  entityId?: string;
  target?: IServiceCallRequest['target'];
}

export interface IAirgradientRefreshCommand {
  type: 'refresh';
  service?: string;
}

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

export type TAirgradientCommandExecutor = (
  commandArg: IAirgradientCommand
) => Promise<IAirgradientCommandResult | unknown> | IAirgradientCommandResult | unknown;

export interface IAirgradientManualEntry {
  host?: string;
  port?: number;
  protocol?: TAirgradientProtocol;
  id?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  firmwareVersion?: string;
  latestFirmwareVersion?: string;
  measures?: IAirgradientMeasures;
  deviceConfig?: IAirgradientDeviceConfig;
  snapshot?: IAirgradientSnapshot;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

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