export const openthermGwDomain = 'opentherm_gw';
export const openthermGwDefaultTcpPort = 23;
export const openthermGwDefaultTimeoutMs = 5000;

export type TOpenthermGwDataSource = 'gateway' | 'boiler' | 'thermostat';
export type TOpenthermGwSnapshotSource = 'manual' | 'snapshot' | 'tcp' | 'runtime';
export type TOpenthermGwEventType = 'status' | 'command' | 'error';
export type TOpenthermGwHvacAction = 'heating' | 'cooling' | 'idle' | 'off';
export type TOpenthermGwHvacMode = 'heat' | 'cool' | 'off';
export type TOpenthermGwWaterHeaterMode = 'auto' | 'heat' | 'off' | 'unknown';
export type TOpenthermGwStatusValue = string | number | boolean | null | undefined;
export type TOpenthermGwCommandValue = string | number | boolean;

export type TOpenthermGwCommandCode =
  | 'TT'
  | 'TC'
  | 'OT'
  | 'SC'
  | 'HW'
  | 'PR'
  | 'PS'
  | 'GW'
  | 'LA'
  | 'LB'
  | 'LC'
  | 'LD'
  | 'LE'
  | 'LF'
  | 'GA'
  | 'GB'
  | 'SB'
  | 'TS'
  | 'SH'
  | 'SW'
  | 'MM'
  | 'CS'
  | 'C2'
  | 'CH'
  | 'H2'
  | string;

export interface IOpenthermGwConfig {
  id?: string;
  name?: string;
  host?: string;
  port?: number;
  device?: string;
  timeoutMs?: number;
  temporaryOverrideMode?: boolean;
  snapshot?: IOpenthermGwSnapshot;
  status?: IOpenthermGwStatus;
}

export interface IHomeAssistantOpenthermGwConfig extends IOpenthermGwConfig {}

export interface IOpenthermGwGatewayInfo {
  id: string;
  name: string;
  host?: string;
  port?: number;
  device?: string;
  firmwareVersion?: string;
}

export interface IOpenthermGwStatus {
  gateway: IOpenthermGwGatewayStatus;
  boiler: IOpenthermGwDeviceStatus;
  thermostat: IOpenthermGwDeviceStatus;
}

export interface IOpenthermGwGatewayStatus {
  otgw_mode?: TOpenthermGwStatusValue;
  otgw_dhw_ovrd?: TOpenthermGwStatusValue;
  otgw_about?: TOpenthermGwStatusValue;
  otgw_build?: TOpenthermGwStatusValue;
  otgw_clockmhz?: TOpenthermGwStatusValue;
  otgw_led_a?: TOpenthermGwStatusValue;
  otgw_led_b?: TOpenthermGwStatusValue;
  otgw_led_c?: TOpenthermGwStatusValue;
  otgw_led_d?: TOpenthermGwStatusValue;
  otgw_led_e?: TOpenthermGwStatusValue;
  otgw_led_f?: TOpenthermGwStatusValue;
  otgw_gpio_a?: TOpenthermGwStatusValue;
  otgw_gpio_b?: TOpenthermGwStatusValue;
  otgw_gpio_a_state?: TOpenthermGwStatusValue;
  otgw_gpio_b_state?: TOpenthermGwStatusValue;
  otgw_reset_cause?: TOpenthermGwStatusValue;
  otgw_setback_temp?: TOpenthermGwStatusValue;
  otgw_setpoint_ovrd_mode?: TOpenthermGwStatusValue;
  otgw_smart_pwr?: TOpenthermGwStatusValue;
  otgw_temp_sensor?: TOpenthermGwStatusValue;
  otgw_thermostat_detect?: TOpenthermGwStatusValue;
  otgw_ignore_transitions?: TOpenthermGwStatusValue;
  otgw_ovrd_high_byte?: TOpenthermGwStatusValue;
  otgw_vref?: TOpenthermGwStatusValue;
  central_heating_1_override?: TOpenthermGwStatusValue;
  central_heating_2_override?: TOpenthermGwStatusValue;
  [key: string]: TOpenthermGwStatusValue;
}

export interface IOpenthermGwDeviceStatus {
  master_ch_enabled?: TOpenthermGwStatusValue;
  master_dhw_enabled?: TOpenthermGwStatusValue;
  master_cooling_enabled?: TOpenthermGwStatusValue;
  master_otc_enabled?: TOpenthermGwStatusValue;
  master_ch2_enabled?: TOpenthermGwStatusValue;
  slave_fault_indication?: TOpenthermGwStatusValue;
  slave_ch_active?: TOpenthermGwStatusValue;
  slave_dhw_active?: TOpenthermGwStatusValue;
  slave_flame_on?: TOpenthermGwStatusValue;
  slave_cooling_active?: TOpenthermGwStatusValue;
  slave_ch2_active?: TOpenthermGwStatusValue;
  slave_diagnostic_indication?: TOpenthermGwStatusValue;
  control_setpoint?: TOpenthermGwStatusValue;
  control_setpoint_2?: TOpenthermGwStatusValue;
  room_setpoint?: TOpenthermGwStatusValue;
  room_setpoint_2?: TOpenthermGwStatusValue;
  room_setpoint_ovrd?: TOpenthermGwStatusValue;
  room_temp?: TOpenthermGwStatusValue;
  outside_temp?: TOpenthermGwStatusValue;
  ch_water_temp?: TOpenthermGwStatusValue;
  ch_water_temp_2?: TOpenthermGwStatusValue;
  dhw_temp?: TOpenthermGwStatusValue;
  dhw_temp_2?: TOpenthermGwStatusValue;
  dhw_setpoint?: TOpenthermGwStatusValue;
  max_ch_setpoint?: TOpenthermGwStatusValue;
  relative_mod_level?: TOpenthermGwStatusValue;
  ch_water_pressure?: TOpenthermGwStatusValue;
  dhw_flow_rate?: TOpenthermGwStatusValue;
  return_water_temp?: TOpenthermGwStatusValue;
  exhaust_temp?: TOpenthermGwStatusValue;
  slave_max_relative_modulation?: TOpenthermGwStatusValue;
  slave_max_capacity?: TOpenthermGwStatusValue;
  slave_min_mod_level?: TOpenthermGwStatusValue;
  slave_dhw_present?: TOpenthermGwStatusValue;
  slave_control_type?: TOpenthermGwStatusValue;
  slave_cooling_supported?: TOpenthermGwStatusValue;
  slave_dhw_config?: TOpenthermGwStatusValue;
  slave_master_low_off_pump?: TOpenthermGwStatusValue;
  slave_ch2_present?: TOpenthermGwStatusValue;
  slave_service_required?: TOpenthermGwStatusValue;
  slave_remote_reset?: TOpenthermGwStatusValue;
  slave_low_water_pressure?: TOpenthermGwStatusValue;
  slave_gas_fault?: TOpenthermGwStatusValue;
  slave_air_pressure_fault?: TOpenthermGwStatusValue;
  slave_water_overtemp?: TOpenthermGwStatusValue;
  remote_transfer_dhw?: TOpenthermGwStatusValue;
  remote_transfer_max_ch?: TOpenthermGwStatusValue;
  remote_rw_dhw?: TOpenthermGwStatusValue;
  remote_rw_max_ch?: TOpenthermGwStatusValue;
  slave_memberid?: TOpenthermGwStatusValue;
  master_memberid?: TOpenthermGwStatusValue;
  slave_oem_fault?: TOpenthermGwStatusValue;
  oem_diag?: TOpenthermGwStatusValue;
  burner_starts?: TOpenthermGwStatusValue;
  ch_pump_starts?: TOpenthermGwStatusValue;
  dhw_pump_starts?: TOpenthermGwStatusValue;
  dhw_burner_starts?: TOpenthermGwStatusValue;
  burner_hours?: TOpenthermGwStatusValue;
  ch_pump_hours?: TOpenthermGwStatusValue;
  dhw_pump_hours?: TOpenthermGwStatusValue;
  dhw_burner_hours?: TOpenthermGwStatusValue;
  master_ot_version?: TOpenthermGwStatusValue;
  slave_ot_version?: TOpenthermGwStatusValue;
  master_product_type?: TOpenthermGwStatusValue;
  master_product_version?: TOpenthermGwStatusValue;
  slave_product_type?: TOpenthermGwStatusValue;
  slave_product_version?: TOpenthermGwStatusValue;
  [key: string]: TOpenthermGwStatusValue;
}

export interface IOpenthermGwSensorDescription {
  key: string;
  source: TOpenthermGwDataSource;
  name: string;
  unit?: string;
  deviceClass?: string;
  stateClass?: 'measurement' | 'total';
}

export interface IOpenthermGwBinarySensorDescription {
  key: string;
  source: TOpenthermGwDataSource;
  name: string;
  deviceClass?: string;
}

export interface IOpenthermGwSwitchDescription {
  key: 'central_heating_1_override' | 'central_heating_2_override';
  name: string;
  circuit: 1 | 2;
}

export interface IOpenthermGwClimateState {
  currentTemperature?: number;
  targetTemperature?: number;
  hvacMode: TOpenthermGwHvacMode;
  hvacAction: TOpenthermGwHvacAction;
  presetMode: 'none' | 'away';
  minTemp: number;
  maxTemp: number;
  temperatureUnit: 'C';
}

export interface IOpenthermGwWaterHeaterState {
  currentTemperature?: number;
  targetTemperature?: number;
  operationMode: TOpenthermGwWaterHeaterMode;
  hotWaterActive?: boolean;
  temperatureUnit: 'C';
}

export interface IOpenthermGwCommandRequest {
  code: TOpenthermGwCommandCode;
  value: TOpenthermGwCommandValue;
  timeoutMs?: number;
}

export interface IOpenthermGwCommandResponse {
  code: TOpenthermGwCommandCode;
  value: string;
  accepted: boolean;
  commandLine: string;
  rawLines: string[];
  summaryLine?: string;
  errorCode?: string;
  updatedAt: string;
}

export interface IOpenthermGwEvent {
  type: TOpenthermGwEventType;
  gatewayId: string;
  timestamp: number;
  status?: IOpenthermGwStatus;
  command?: IOpenthermGwCommandResponse;
  error?: string;
}

export interface IOpenthermGwSnapshot {
  gateway: IOpenthermGwGatewayInfo;
  status: IOpenthermGwStatus;
  climate?: IOpenthermGwClimateState;
  waterHeater?: IOpenthermGwWaterHeaterState;
  commands?: IOpenthermGwCommandResponse[];
  events?: IOpenthermGwEvent[];
  online: boolean;
  source: TOpenthermGwSnapshotSource;
  updatedAt: string;
}

export interface IOpenthermGwManualDiscoveryInput {
  id?: string;
  host?: string;
  port?: number;
  device?: string;
  name?: string;
  manufacturer?: string;
  model?: string;
  metadata?: Record<string, unknown>;
}
