export const bondDomain = 'bond';
export const bondDisplayName = 'Bond';
export const bondDefaultPort = 80;
export const bondDefaultTimeoutMs = 10000;
export const bondZeroconfType = '_bond._tcp.local.';
export const bondDhcpHostnamePrefix = 'bond-';
export const bondDhcpMacPrefixes = ['3C6A2C1', 'F44E38'] as const;

export type TBondSnapshotSource = 'http' | 'client' | 'manual' | 'snapshot' | 'runtime' | 'executor';

export const bondDeviceTypes = {
  ceilingFan: 'CF',
  motorizedShades: 'MS',
  fireplace: 'FP',
  airConditioner: 'AC',
  garageDoor: 'GD',
  bidet: 'BD',
  light: 'LT',
  genericDevice: 'GX',
} as const;

export const bondActions = {
  stop: 'Stop',
  turnOn: 'TurnOn',
  turnOff: 'TurnOff',
  togglePower: 'TogglePower',
  setTimer: 'SetTimer',
  switchMode: 'SwitchMode',
  setStateBelief: 'state',
  turnLightOn: 'TurnLightOn',
  turnLightOff: 'TurnLightOff',
  toggleLight: 'ToggleLight',
  setBrightness: 'SetBrightness',
  increaseBrightness: 'IncreaseBrightness',
  decreaseBrightness: 'DecreaseBrightness',
  startDimmer: 'StartDimmer',
  turnUpLightOn: 'TurnUpLightOn',
  turnDownLightOn: 'TurnDownLightOn',
  turnUpLightOff: 'TurnUpLightOff',
  turnDownLightOff: 'TurnDownLightOff',
  toggleUpLight: 'ToggleUpLight',
  toggleDownLight: 'ToggleDownLight',
  startUpLightDimmer: 'StartUpLightDimmer',
  startDownLightDimmer: 'StartDownLightDimmer',
  startIncreasingBrightness: 'StartIncreasingBrightness',
  startDecreasingBrightness: 'StartDecreasingBrightness',
  setUpLightBrightness: 'SetUpLightBrightness',
  setDownLightBrightness: 'SetDownLightBrightness',
  increaseUpLightBrightness: 'IncreaseUpLightBrightness',
  decreaseUpLightBrightness: 'DecreaseUpLightBrightness',
  increaseDownLightBrightness: 'IncreaseDownLightBrightness',
  decreaseDownLightBrightness: 'DecreaseDownLightBrightness',
  cycleUpLightBrightness: 'CycleUpLightBrightness',
  cycleDownLightBrightness: 'CycleDownLightBrightness',
  cycleBrightness: 'CycleBrightness',
  breezeOff: 'BreezeOff',
  breezeOn: 'BreezeOn',
  decreaseSpeed: 'DecreaseSpeed',
  increaseSpeed: 'IncreaseSpeed',
  setBreeze: 'SetBreeze',
  setDirection: 'SetDirection',
  setSpeed: 'SetSpeed',
  toggleDirection: 'ToggleDirection',
  toggleLightTemp: 'ToggleLightTemp',
  increaseTemperature: 'IncreaseTemperature',
  decreaseTemperature: 'DecreaseTemperature',
  setFpFan: 'SetFpFan',
  turnFpFanOn: 'TurnFpFanOn',
  turnFpFanOff: 'TurnFpFanOff',
  increaseFlame: 'IncreaseFlame',
  decreaseFlame: 'DecreaseFlame',
  setFlame: 'SetFlame',
  close: 'Close',
  closeNext: 'CloseNext',
  decreasePosition: 'DecreasePosition',
  hold: 'Hold',
  increasePosition: 'IncreasePosition',
  open: 'Open',
  openNext: 'OpenNext',
  preset: 'Preset',
  setPosition: 'SetPosition',
  tiltClose: 'TiltClose',
  tiltOpen: 'TiltOpen',
  toggleOpen: 'ToggleOpen',
} as const;

export type TBondAction = typeof bondActions[keyof typeof bondActions] | string;
export type TBondDeviceType = typeof bondDeviceTypes[keyof typeof bondDeviceTypes] | string;

export interface IBondVersionInfo {
  bondid?: string;
  target?: string;
  model?: string;
  make?: string;
  fw_ver?: string;
  mcu_ver?: string;
  [key: string]: unknown;
}

export interface IBondBridgeInfo {
  name?: string;
  location?: string;
  bluelight?: number;
  [key: string]: unknown;
}

export interface IBondDeviceAttributes {
  name?: string;
  type?: TBondDeviceType;
  location?: string;
  template?: string;
  actions?: string[];
  [key: string]: unknown;
}

export interface IBondDeviceProperties {
  max_speed?: number;
  trust_state?: boolean;
  branding_profile?: string;
  [key: string]: unknown;
}

export interface IBondDeviceState {
  power?: number | boolean;
  light?: number | boolean;
  up_light?: number | boolean;
  down_light?: number | boolean;
  brightness?: number;
  flame?: number;
  speed?: number;
  direction?: number;
  breeze?: unknown[];
  open?: number | boolean;
  position?: number;
  [key: string]: unknown;
}

export interface IBondDeviceRaw {
  deviceId: string;
  attrs?: IBondDeviceAttributes;
  props?: IBondDeviceProperties;
  state?: IBondDeviceState;
}

export interface IBondRawData {
  version?: IBondVersionInfo;
  bridge?: IBondBridgeInfo;
  deviceIndex?: Record<string, unknown>;
  devices?: IBondDeviceRaw[];
  fetchedAt?: string;
}

export interface IBondHubSnapshot {
  id: string;
  name: string;
  host?: string;
  port?: number;
  manufacturer: string;
  model?: string;
  target?: string;
  firmware?: string;
  hardware?: string;
  location?: string;
  isBridge: boolean;
  version: IBondVersionInfo;
  bridge?: IBondBridgeInfo;
}

export interface IBondDeviceSnapshot {
  deviceId: string;
  name: string;
  type: TBondDeviceType;
  location?: string;
  template?: string;
  brandingProfile?: string;
  trustState: boolean;
  supportedActions: string[];
  attrs: IBondDeviceAttributes;
  props: IBondDeviceProperties;
  state: IBondDeviceState;
}

export interface IBondCapabilities {
  localControl: boolean;
  pushUpdates: boolean;
  fan: boolean;
  cover: boolean;
  light: boolean;
  fireplace: boolean;
  switch: boolean;
  buttons: boolean;
}

export interface IBondSnapshot {
  hub: IBondHubSnapshot;
  devices: IBondDeviceSnapshot[];
  capabilities: IBondCapabilities;
  rawData?: IBondRawData;
  online: boolean;
  updatedAt: string;
  source: TBondSnapshotSource;
  error?: string;
}

export interface IBondCommandRequest {
  deviceId: string;
  action: TBondAction;
  argument?: unknown;
  statePatch?: Record<string, unknown>;
  service?: string;
  target?: Record<string, unknown>;
  data?: Record<string, unknown>;
}

export interface IBondCommandExecutor {
  execute(requestArg: IBondCommandRequest): Promise<unknown>;
}

export interface IBondClientLike {
  getSnapshot?: () => Promise<IBondSnapshot | Partial<IBondRawData>>;
  getRawData?: () => Promise<Partial<IBondRawData>>;
  execute?: (requestArg: IBondCommandRequest) => Promise<unknown>;
  destroy?: () => Promise<void>;
}

export interface IBondConfig {
  host?: string;
  url?: string;
  port?: number;
  accessToken?: string;
  token?: string;
  timeoutMs?: number;
  name?: string;
  manufacturer?: string;
  model?: string;
  uniqueId?: string;
  bondId?: string;
  snapshot?: IBondSnapshot;
  rawData?: Partial<IBondRawData>;
  client?: IBondClientLike;
  commandExecutor?: IBondCommandExecutor;
  online?: boolean;
}

export interface IHomeAssistantBondConfig extends IBondConfig {}

export interface IBondManualEntry extends IBondConfig {
  id?: string;
  metadata?: Record<string, unknown>;
}

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

export interface IBondDhcpRecord {
  hostname?: string;
  hostName?: string;
  ip?: string;
  address?: string;
  macaddress?: string;
  macAddress?: string;
  metadata?: Record<string, unknown>;
}

export interface IBondHttpRefreshResult {
  success: boolean;
  snapshot?: IBondSnapshot;
  error?: string;
  data?: unknown;
}
