export const dsmrDomain = 'dsmr';
export const dsmrDefaultDsmrVersion = '2.2';
export const dsmrDefaultNetworkPort = 2001;
export const dsmrDefaultTimeoutMs = 30000;
export const dsmrDefaultPrecision = 3;

export type TDsmrConnectionType = 'serial' | 'network';
export type TDsmrProtocol = 'dsmr_protocol' | 'rfxtrx_dsmr_protocol';
export type TDsmrVersion = '2.2' | '4' | '5' | '5B' | '5L' | '5S' | 'Q3D' | '5EONHU';
export type TDsmrDeviceType = 'electricity' | 'gas' | 'water' | 'heat';
export type TDsmrSnapshotSource = 'manual' | 'snapshot' | 'status' | 'telegram' | 'network' | 'serial';
export type TDsmrStateClass = 'measurement' | 'total' | 'total_increasing';
export type TDsmrEventType = 'snapshot_refreshed' | 'telegram_received' | 'refresh_failed' | 'connection_status';
export type TDsmrSensorValue = string | number | boolean | null;

export interface IDsmrConfig {
  id?: string;
  name?: string;
  connectionType?: TDsmrConnectionType;
  type?: TDsmrConnectionType | 'Serial' | 'Network';
  host?: string;
  port?: number | string;
  serialPort?: string;
  device?: string;
  path?: string;
  dsmrVersion?: TDsmrVersion | string;
  dsmr_version?: TDsmrVersion | string;
  protocol?: TDsmrProtocol | string;
  serialId?: string | null;
  serial_id?: string | null;
  serialIdGas?: string | null;
  serial_id_gas?: string | null;
  timeBetweenUpdate?: number;
  time_between_update?: number;
  connected?: boolean;
  timeoutMs?: number;
  liveRead?: boolean;
  snapshot?: IDsmrSnapshot;
  status?: IDsmrStatusSnapshot;
  telegram?: string | IDsmrSnapshot;
  telegrams?: string[];
  telegramProvider?: () => Promise<string | IDsmrSnapshot | IDsmrStatusSnapshot | undefined>;
}

export interface IHomeAssistantDsmrConfig extends IDsmrConfig {}

export interface IDsmrConnectionInfo {
  id: string;
  name: string;
  connectionType: TDsmrConnectionType;
  host?: string;
  port?: number | string;
  serialPort?: string;
  protocol: TDsmrProtocol;
  dsmrVersion: TDsmrVersion | string;
}

export interface IDsmrMeterInfo extends IDsmrConnectionInfo {
  serialId?: string | null;
  serialIdGas?: string | null;
  manufacturer?: string;
  model?: string;
}

export interface IDsmrSensorDescription {
  key: string;
  name: string;
  obisReference: string;
  obisCodes?: string[];
  obisCodePatterns?: RegExp[];
  dsmrVersions?: string[];
  deviceType: TDsmrDeviceType;
  deviceClass?: string;
  stateClass?: TDsmrStateClass;
  entityCategory?: 'diagnostic';
  enabledByDefault?: boolean;
  defaultUnit?: string;
  translateTariff?: boolean;
}

export interface IDsmrTelegramObjectGroup {
  raw: string;
  value: string;
  unit?: string;
}

export interface IDsmrTelegramObject {
  obisCode: string;
  obisReference?: string;
  channel?: number;
  raw: string;
  groups: IDsmrTelegramObjectGroup[];
  value?: string;
  unit?: string;
}

export interface IDsmrMbusDeviceSnapshot {
  channel: number;
  deviceType?: number;
  serialId?: string;
  reading?: IDsmrSensorState;
}

export interface IDsmrSensorState {
  key: string;
  name: string;
  obisReference: string;
  obisCode?: string;
  deviceType: TDsmrDeviceType;
  value: TDsmrSensorValue;
  rawValue?: string;
  unit?: string;
  deviceClass?: string;
  stateClass?: TDsmrStateClass;
  entityCategory?: 'diagnostic';
  enabledByDefault?: boolean;
  available: boolean;
  channel?: number;
  serialId?: string | null;
  updatedAt?: string;
  attributes?: Record<string, unknown>;
}

export interface IDsmrTelegramData {
  header?: string;
  checksum?: string;
  raw: string;
  objects: IDsmrTelegramObject[];
}

export interface IDsmrSnapshot {
  meter: IDsmrMeterInfo;
  sensors: IDsmrSensorState[];
  mbusDevices?: IDsmrMbusDeviceSnapshot[];
  telegram?: IDsmrTelegramData;
  connected: boolean;
  source: TDsmrSnapshotSource;
  updatedAt: string;
  raw?: Record<string, unknown>;
}

export interface IDsmrStatusValueObject {
  value?: TDsmrSensorValue | undefined;
  unit?: string;
  rawValue?: string;
  available?: boolean;
  updatedAt?: string;
  attributes?: Record<string, unknown>;
}

export interface IDsmrStatusSnapshot {
  meter?: Partial<IDsmrMeterInfo>;
  sensors?: IDsmrSensorState[];
  values?: Record<string, TDsmrSensorValue | IDsmrStatusValueObject | undefined>;
  connected?: boolean;
  updatedAt?: string;
  raw?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface IDsmrRefreshResult {
  success: boolean;
  snapshot?: IDsmrSnapshot;
  error?: string;
  data?: unknown;
}

export interface IDsmrEvent {
  type: TDsmrEventType;
  snapshot?: IDsmrSnapshot;
  sensor?: IDsmrSensorState;
  data?: unknown;
  error?: string;
  timestamp: number;
}

export interface IDsmrManualEntry {
  id?: string;
  name?: string;
  host?: string;
  port?: number | string;
  serialPort?: string;
  device?: string;
  path?: string;
  type?: TDsmrConnectionType | 'serial' | 'network';
  protocol?: string;
  dsmrVersion?: string;
  manufacturer?: string;
  model?: string;
  serialNumber?: string;
  metadata?: Record<string, unknown>;
}
