import * as plugins from '../../plugins.js';
import type { IIntegrationEntity, IIntegrationEvent } from '../../core/types.js';
import type { IDeconzGroup, IDeconzLight, IDeconzSensor, IDeconzSnapshot, IDeconzWebsocketEvent } from './deconz.types.js';

interface IDeconzSensorEntityDescription {
  key: string;
  platform: 'binary_sensor' | 'sensor';
  stateKey?: string;
  configKey?: string;
  nameSuffix?: string;
  unit?: string;
  deviceClass?: string;
  value: (sensorArg: IDeconzSensor) => unknown;
}

const POWER_PLUG_TYPES = new Set([
  'on/off light',
  'on/off output',
  'on/off plug-in unit',
  'smart plug',
]);

const COVER_TYPES = new Set([
  'level controllable output',
  'window covering controller',
  'window covering device',
]);

const BINARY_SENSOR_DESCRIPTIONS: IDeconzSensorEntityDescription[] = [
  { key: 'alarm', platform: 'binary_sensor', stateKey: 'alarm', deviceClass: 'safety', value: (sensorArg) => sensorArg.state?.alarm },
  { key: 'carbon_monoxide', platform: 'binary_sensor', stateKey: 'carbonmonoxide', deviceClass: 'carbon_monoxide', value: (sensorArg) => sensorArg.state?.carbonmonoxide },
  { key: 'fire', platform: 'binary_sensor', stateKey: 'fire', deviceClass: 'smoke', value: (sensorArg) => sensorArg.state?.fire },
  { key: 'flag', platform: 'binary_sensor', stateKey: 'flag', value: (sensorArg) => sensorArg.state?.flag },
  { key: 'open', platform: 'binary_sensor', stateKey: 'open', deviceClass: 'opening', value: (sensorArg) => sensorArg.state?.open },
  { key: 'presence', platform: 'binary_sensor', stateKey: 'presence', deviceClass: 'motion', value: (sensorArg) => sensorArg.state?.presence },
  { key: 'vibration', platform: 'binary_sensor', stateKey: 'vibration', deviceClass: 'vibration', value: (sensorArg) => sensorArg.state?.vibration },
  { key: 'water', platform: 'binary_sensor', stateKey: 'water', deviceClass: 'moisture', value: (sensorArg) => sensorArg.state?.water },
  { key: 'tampered', platform: 'binary_sensor', configKey: 'tampered', nameSuffix: 'Tampered', deviceClass: 'tamper', value: (sensorArg) => sensorArg.config?.tampered },
  { key: 'low_battery', platform: 'binary_sensor', configKey: 'lowbattery', nameSuffix: 'Low Battery', deviceClass: 'battery', value: (sensorArg) => sensorArg.config?.lowbattery },
];

const SENSOR_DESCRIPTIONS: IDeconzSensorEntityDescription[] = [
  { key: 'air_quality', platform: 'sensor', stateKey: 'airquality', value: (sensorArg) => sensorArg.state?.airquality },
  { key: 'air_quality_ppb', platform: 'sensor', stateKey: 'airqualityppb', nameSuffix: 'PPB', unit: 'ppb', value: (sensorArg) => sensorArg.state?.airqualityppb },
  { key: 'battery', platform: 'sensor', configKey: 'battery', nameSuffix: 'Battery', unit: '%', deviceClass: 'battery', value: (sensorArg) => sensorArg.config?.battery ?? sensorArg.state?.battery },
  { key: 'button_event', platform: 'sensor', stateKey: 'buttonevent', nameSuffix: 'Button Event', value: (sensorArg) => sensorArg.state?.buttonevent },
  { key: 'consumption', platform: 'sensor', stateKey: 'consumption', unit: 'kWh', deviceClass: 'energy', value: (sensorArg) => DeconzMapper.scaleConsumption(sensorArg.state?.consumption) },
  { key: 'current', platform: 'sensor', stateKey: 'current', unit: 'A', value: (sensorArg) => sensorArg.state?.current },
  { key: 'humidity', platform: 'sensor', stateKey: 'humidity', unit: '%', deviceClass: 'humidity', value: (sensorArg) => DeconzMapper.scaleHundred(sensorArg.state?.humidity) },
  { key: 'light_level', platform: 'sensor', stateKey: 'lightlevel', unit: 'lx', deviceClass: 'illuminance', value: (sensorArg) => DeconzMapper.lightLevel(sensorArg) },
  { key: 'power', platform: 'sensor', stateKey: 'power', unit: 'W', deviceClass: 'power', value: (sensorArg) => sensorArg.state?.power },
  { key: 'pressure', platform: 'sensor', stateKey: 'pressure', unit: 'hPa', deviceClass: 'pressure', value: (sensorArg) => sensorArg.state?.pressure },
  { key: 'status', platform: 'sensor', stateKey: 'status', value: (sensorArg) => sensorArg.state?.status },
  { key: 'temperature', platform: 'sensor', stateKey: 'temperature', unit: 'C', deviceClass: 'temperature', value: (sensorArg) => DeconzMapper.scaleHundred(sensorArg.state?.temperature) },
  { key: 'voltage', platform: 'sensor', stateKey: 'voltage', unit: 'V', deviceClass: 'voltage', value: (sensorArg) => sensorArg.state?.voltage },
];

export class DeconzMapper {
  public static toDevices(snapshotArg: IDeconzSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = new Date().toISOString();
    const devices: plugins.shxInterfaces.data.IDeviceDefinition[] = [];
    const bridgeId = this.bridgeId(snapshotArg);

    devices.push({
      id: this.gatewayDeviceId(snapshotArg),
      integrationDomain: 'deconz',
      name: snapshotArg.config?.name || snapshotArg.config?.devicename || 'deCONZ Gateway',
      protocol: 'zigbee',
      manufacturer: 'dresden elektronik',
      model: snapshotArg.config?.devicename || snapshotArg.config?.modelid || 'deCONZ',
      online: snapshotArg.config?.rfconnected !== false,
      features: [
        { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
      ],
      state: [
        { featureId: 'connectivity', value: snapshotArg.config?.rfconnected === false ? 'offline' : 'online', updatedAt },
      ],
      metadata: {
        bridgeId,
        apiVersion: snapshotArg.config?.apiversion,
        softwareVersion: snapshotArg.config?.swversion,
        websocketPort: snapshotArg.config?.websocketport,
      },
    });

    for (const [lightId, light] of Object.entries(snapshotArg.lights)) {
      devices.push(this.lightToDevice(lightId, light, updatedAt));
    }

    for (const [groupId, group] of Object.entries(snapshotArg.groups)) {
      if (!group.lights?.length) {
        continue;
      }
      devices.push(this.groupToDevice(bridgeId, groupId, group, updatedAt));
    }

    for (const [sensorId, sensor] of Object.entries(snapshotArg.sensors)) {
      devices.push(this.sensorToDevice(sensorId, sensor, updatedAt));
    }

    return devices;
  }

  public static toEntities(snapshotArg: IDeconzSnapshot): IIntegrationEntity[] {
    const entities: IIntegrationEntity[] = [];
    const usedIds = new Map<string, number>();
    const bridgeId = this.bridgeId(snapshotArg);

    for (const [lightId, light] of Object.entries(snapshotArg.lights)) {
      entities.push(this.lightToEntity(lightId, light, usedIds));
    }

    for (const [groupId, group] of Object.entries(snapshotArg.groups)) {
      if (!group.lights?.length) {
        continue;
      }
      entities.push(this.groupToEntity(bridgeId, groupId, group, usedIds));
    }

    for (const [sensorId, sensor] of Object.entries(snapshotArg.sensors)) {
      if (this.isThermostat(sensor)) {
        entities.push(this.climateToEntity(sensorId, sensor, usedIds));
      }

      for (const description of [...BINARY_SENSOR_DESCRIPTIONS, ...SENSOR_DESCRIPTIONS]) {
        if (this.isThermostat(sensor) && description.key === 'temperature') {
          continue;
        }
        const value = description.value(sensor);
        if (value === undefined || value === null) {
          continue;
        }
        entities.push(this.sensorToEntity(sensorId, sensor, description, value, usedIds));
      }
    }

    return entities;
  }

  public static toIntegrationEvent(eventArg: IDeconzWebsocketEvent): IIntegrationEvent {
    return {
      type: eventArg.e === 'added' ? 'device_added' : eventArg.e === 'deleted' ? 'device_removed' : 'state_changed',
      integrationDomain: 'deconz',
      data: eventArg,
      timestamp: Date.now(),
    };
  }

  public static scaleHundred(valueArg: unknown): number | undefined {
    if (typeof valueArg !== 'number') {
      return undefined;
    }
    return Math.abs(valueArg) > 200 ? valueArg / 100 : valueArg;
  }

  public static scaleConsumption(valueArg: unknown): number | undefined {
    if (typeof valueArg !== 'number') {
      return undefined;
    }
    return Math.abs(valueArg) >= 1000 ? valueArg / 1000 : valueArg;
  }

  public static lightLevel(sensorArg: IDeconzSensor): number | undefined {
    if (typeof sensorArg.state?.lux === 'number') {
      return sensorArg.state.lux;
    }
    if (typeof sensorArg.state?.lightlevel !== 'number') {
      return undefined;
    }
    return Math.round(Math.pow(10, (sensorArg.state.lightlevel - 1) / 10000));
  }

  private static lightToDevice(lightIdArg: string, lightArg: IDeconzLight, updatedAtArg: string): plugins.shxInterfaces.data.IDeviceDefinition {
    const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
      { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
    ];
    const state: plugins.shxInterfaces.data.IDeviceState[] = [
      { featureId: 'connectivity', value: this.isLightAvailable(lightArg) ? 'online' : 'offline', updatedAt: updatedAtArg },
    ];

    if (this.isCoverLight(lightArg)) {
      features.push({ id: 'position', capability: 'cover', name: 'Position', readable: true, writable: true, unit: '%' });
      this.pushDeviceState(state, 'position', this.coverPosition(lightArg), updatedAtArg);
    } else if (this.isSwitchLight(lightArg)) {
      features.push({ id: 'on', capability: 'switch', name: 'Power', readable: true, writable: true });
      this.pushDeviceState(state, 'on', lightArg.state?.on ?? false, updatedAtArg);
    } else {
      features.push({ id: 'on', capability: 'light', name: 'Power', readable: true, writable: true });
      this.pushDeviceState(state, 'on', lightArg.state?.on ?? false, updatedAtArg);
      if (typeof lightArg.state?.bri === 'number') {
        features.push({ id: 'brightness', capability: 'light', name: 'Brightness', readable: true, writable: true, unit: '%' });
        this.pushDeviceState(state, 'brightness', Math.round(lightArg.state.bri / 255 * 100), updatedAtArg);
      }
    }

    return {
      id: this.lightDeviceId(lightIdArg, lightArg),
      integrationDomain: 'deconz',
      name: lightArg.name || `deCONZ Light ${lightIdArg}`,
      protocol: 'zigbee',
      manufacturer: lightArg.manufacturername || 'Unknown',
      model: lightArg.modelid || lightArg.type,
      online: this.isLightAvailable(lightArg),
      features,
      state,
      metadata: {
        deconzId: lightIdArg,
        uniqueId: lightArg.uniqueid,
        type: lightArg.type,
        softwareVersion: lightArg.swversion,
      },
    };
  }

  private static groupToDevice(bridgeIdArg: string, groupIdArg: string, groupArg: IDeconzGroup, updatedAtArg: string): plugins.shxInterfaces.data.IDeviceDefinition {
    const state: plugins.shxInterfaces.data.IDeviceState[] = [
      { featureId: 'connectivity', value: 'online', updatedAt: updatedAtArg },
      { featureId: 'on', value: groupArg.state?.any_on ?? groupArg.action?.on ?? false, updatedAt: updatedAtArg },
    ];
    if (typeof groupArg.action?.bri === 'number') {
      state.push({ featureId: 'brightness', value: Math.round(groupArg.action.bri / 255 * 100), updatedAt: updatedAtArg });
    }

    return {
      id: this.groupDeviceId(bridgeIdArg, groupIdArg),
      integrationDomain: 'deconz',
      name: groupArg.name || `deCONZ Group ${groupIdArg}`,
      protocol: 'zigbee',
      manufacturer: 'dresden elektronik',
      model: 'deCONZ group',
      online: true,
      features: [
        { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
        { id: 'on', capability: 'light', name: 'Power', readable: true, writable: true },
        { id: 'brightness', capability: 'light', name: 'Brightness', readable: true, writable: true, unit: '%' },
      ],
      state,
      metadata: {
        bridgeId: bridgeIdArg,
        deconzId: groupIdArg,
        lights: groupArg.lights,
        type: groupArg.type,
      },
    };
  }

  private static sensorToDevice(sensorIdArg: string, sensorArg: IDeconzSensor, updatedAtArg: string): plugins.shxInterfaces.data.IDeviceDefinition {
    const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
      { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
    ];
    const state: plugins.shxInterfaces.data.IDeviceState[] = [
      { featureId: 'connectivity', value: this.isSensorAvailable(sensorArg) ? 'online' : 'offline', updatedAt: updatedAtArg },
    ];

    if (this.isThermostat(sensorArg)) {
      features.push({ id: 'target_temperature', capability: 'climate', name: 'Target Temperature', readable: true, writable: true, unit: 'C' });
      features.push({ id: 'current_temperature', capability: 'climate', name: 'Current Temperature', readable: true, writable: false, unit: 'C' });
      this.pushDeviceState(state, 'target_temperature', this.targetTemperature(sensorArg), updatedAtArg);
      this.pushDeviceState(state, 'current_temperature', this.scaleHundred(sensorArg.state?.temperature), updatedAtArg);
    }

    for (const description of [...BINARY_SENSOR_DESCRIPTIONS, ...SENSOR_DESCRIPTIONS]) {
      if (this.isThermostat(sensorArg) && description.key === 'temperature') {
        continue;
      }
      const value = description.value(sensorArg);
      if (value === undefined || value === null) {
        continue;
      }
      features.push({
        id: description.key,
        capability: 'sensor',
        name: this.entityName(sensorArg, description),
        readable: true,
        writable: Boolean(sensorArg.type?.startsWith('CLIP') && description.stateKey),
        unit: description.unit,
      });
      this.pushDeviceState(state, description.key, description.platform === 'binary_sensor' ? Boolean(value) : value, updatedAtArg);
    }

    return {
      id: this.sensorDeviceId(sensorIdArg, sensorArg),
      integrationDomain: 'deconz',
      name: sensorArg.name || `deCONZ Sensor ${sensorIdArg}`,
      protocol: 'zigbee',
      manufacturer: sensorArg.manufacturername || 'Unknown',
      model: sensorArg.modelid || sensorArg.type,
      online: this.isSensorAvailable(sensorArg),
      features,
      state,
      metadata: {
        deconzId: sensorIdArg,
        uniqueId: sensorArg.uniqueid,
        type: sensorArg.type,
        softwareVersion: sensorArg.swversion,
      },
    };
  }

  private static lightToEntity(lightIdArg: string, lightArg: IDeconzLight, usedIdsArg: Map<string, number>): IIntegrationEntity {
    const platform = this.isCoverLight(lightArg) ? 'cover' : this.isSwitchLight(lightArg) ? 'switch' : 'light';
    const resourcePath = `/lights/${lightIdArg}/state`;
    return {
      id: this.entityId(platform, lightArg.name || `deCONZ Light ${lightIdArg}`, usedIdsArg),
      uniqueId: `deconz_light_${this.slug(lightArg.uniqueid || lightIdArg)}`,
      integrationDomain: 'deconz',
      deviceId: this.lightDeviceId(lightIdArg, lightArg),
      platform,
      name: lightArg.name || `deCONZ Light ${lightIdArg}`,
      state: platform === 'cover' ? this.coverState(lightArg) : lightArg.state?.on ? 'on' : 'off',
      attributes: {
        deconzResource: 'lights',
        deconzId: lightIdArg,
        deconzPath: resourcePath,
        uniqueId: lightArg.uniqueid,
        type: lightArg.type,
        brightness: lightArg.state?.bri,
        colorMode: lightArg.state?.colormode,
        colorTemperature: lightArg.state?.ct,
        position: platform === 'cover' ? this.coverPosition(lightArg) : undefined,
        reachable: lightArg.state?.reachable,
      },
      available: this.isLightAvailable(lightArg),
    };
  }

  private static groupToEntity(bridgeIdArg: string, groupIdArg: string, groupArg: IDeconzGroup, usedIdsArg: Map<string, number>): IIntegrationEntity {
    return {
      id: this.entityId('light', groupArg.name || `deCONZ Group ${groupIdArg}`, usedIdsArg),
      uniqueId: `deconz_group_${this.slug(bridgeIdArg)}_${this.slug(groupIdArg)}`,
      integrationDomain: 'deconz',
      deviceId: this.groupDeviceId(bridgeIdArg, groupIdArg),
      platform: 'light',
      name: groupArg.name || `deCONZ Group ${groupIdArg}`,
      state: groupArg.state?.any_on || groupArg.action?.on ? 'on' : 'off',
      attributes: {
        deconzResource: 'groups',
        deconzId: groupIdArg,
        deconzPath: `/groups/${groupIdArg}/action`,
        isDeconzGroup: true,
        allOn: groupArg.state?.all_on,
        anyOn: groupArg.state?.any_on,
        brightness: groupArg.action?.bri,
        lights: groupArg.lights,
      },
      available: true,
    };
  }

  private static sensorToEntity(
    sensorIdArg: string,
    sensorArg: IDeconzSensor,
    descriptionArg: IDeconzSensorEntityDescription,
    valueArg: unknown,
    usedIdsArg: Map<string, number>
  ): IIntegrationEntity {
    const name = this.entityName(sensorArg, descriptionArg);
    return {
      id: this.entityId(descriptionArg.platform, name, usedIdsArg),
      uniqueId: `deconz_sensor_${this.slug(sensorArg.uniqueid || sensorIdArg)}_${descriptionArg.key}`,
      integrationDomain: 'deconz',
      deviceId: this.sensorDeviceId(sensorIdArg, sensorArg),
      platform: descriptionArg.platform,
      name,
      state: descriptionArg.platform === 'binary_sensor' ? (valueArg ? 'on' : 'off') : valueArg,
      attributes: {
        deconzResource: 'sensors',
        deconzId: sensorIdArg,
        deconzPath: descriptionArg.configKey ? `/sensors/${sensorIdArg}/config` : `/sensors/${sensorIdArg}/state`,
        deconzStateKey: descriptionArg.stateKey,
        deconzConfigKey: descriptionArg.configKey,
        deviceClass: descriptionArg.deviceClass,
        unit: descriptionArg.unit,
        type: sensorArg.type,
        uniqueId: sensorArg.uniqueid,
        lastUpdated: sensorArg.state?.lastupdated,
      },
      available: this.isSensorAvailable(sensorArg),
    };
  }

  private static climateToEntity(sensorIdArg: string, sensorArg: IDeconzSensor, usedIdsArg: Map<string, number>): IIntegrationEntity {
    return {
      id: this.entityId('climate', sensorArg.name || `deCONZ Thermostat ${sensorIdArg}`, usedIdsArg),
      uniqueId: `deconz_climate_${this.slug(sensorArg.uniqueid || sensorIdArg)}`,
      integrationDomain: 'deconz',
      deviceId: this.sensorDeviceId(sensorIdArg, sensorArg),
      platform: 'climate',
      name: sensorArg.name || `deCONZ Thermostat ${sensorIdArg}`,
      state: this.climateMode(sensorArg),
      attributes: {
        deconzResource: 'sensors',
        deconzId: sensorIdArg,
        deconzPath: `/sensors/${sensorIdArg}/config`,
        currentTemperature: this.scaleHundred(sensorArg.state?.temperature),
        targetTemperature: this.targetTemperature(sensorArg),
        fanMode: sensorArg.config?.fanmode,
        preset: sensorArg.config?.preset,
        locked: sensorArg.config?.locked,
        valve: sensorArg.config?.valve,
        mode: sensorArg.config?.mode,
      },
      available: this.isSensorAvailable(sensorArg),
    };
  }

  private static pushDeviceState(
    stateArg: plugins.shxInterfaces.data.IDeviceState[],
    featureIdArg: string,
    valueArg: unknown,
    updatedAtArg: string
  ): void {
    if (valueArg === undefined) {
      return;
    }
    stateArg.push({ featureId: featureIdArg, value: valueArg as plugins.shxInterfaces.data.TDeviceStateValue, updatedAt: updatedAtArg });
  }

  private static entityName(sensorArg: IDeconzSensor, descriptionArg: IDeconzSensorEntityDescription): string {
    const baseName = sensorArg.name || 'deCONZ Sensor';
    return descriptionArg.nameSuffix ? `${baseName} ${descriptionArg.nameSuffix}` : baseName;
  }

  private static isLightAvailable(lightArg: IDeconzLight): boolean {
    return lightArg.state?.reachable !== false;
  }

  private static isSensorAvailable(sensorArg: IDeconzSensor): boolean {
    return sensorArg.config?.reachable !== false && sensorArg.config?.on !== false;
  }

  private static isSwitchLight(lightArg: IDeconzLight): boolean {
    const type = lightArg.type?.toLowerCase() || '';
    return POWER_PLUG_TYPES.has(type) || type.includes('plug') || type.includes('outlet');
  }

  private static isCoverLight(lightArg: IDeconzLight): boolean {
    const type = lightArg.type?.toLowerCase() || '';
    return COVER_TYPES.has(type) || lightArg.state?.lift !== undefined || lightArg.state?.tilt !== undefined;
  }

  private static isThermostat(sensorArg: IDeconzSensor): boolean {
    const type = sensorArg.type?.toLowerCase() || '';
    return type.includes('thermostat')
      || sensorArg.config?.heatsetpoint !== undefined
      || sensorArg.config?.coolsetpoint !== undefined
      || sensorArg.config?.mode !== undefined && sensorArg.state?.temperature !== undefined;
  }

  private static coverState(lightArg: IDeconzLight): string {
    if (lightArg.state?.open === false || lightArg.state?.lift === 100) {
      return 'closed';
    }
    return 'open';
  }

  private static coverPosition(lightArg: IDeconzLight): number | undefined {
    if (typeof lightArg.state?.lift === 'number') {
      return this.clamp(100 - lightArg.state.lift, 0, 100);
    }
    if (typeof lightArg.state?.open === 'boolean') {
      return lightArg.state.open ? 100 : 0;
    }
    return undefined;
  }

  private static climateMode(sensorArg: IDeconzSensor): string {
    if (sensorArg.config?.mode) {
      return sensorArg.config.mode;
    }
    return sensorArg.config?.on === false ? 'off' : 'heat';
  }

  private static targetTemperature(sensorArg: IDeconzSensor): number | undefined {
    if (sensorArg.config?.mode === 'cool' && typeof sensorArg.config.coolsetpoint === 'number') {
      return this.scaleHundred(sensorArg.config.coolsetpoint);
    }
    if (typeof sensorArg.config?.heatsetpoint === 'number') {
      return this.scaleHundred(sensorArg.config.heatsetpoint);
    }
    if (typeof sensorArg.config?.coolsetpoint === 'number') {
      return this.scaleHundred(sensorArg.config.coolsetpoint);
    }
    return undefined;
  }

  private static gatewayDeviceId(snapshotArg: IDeconzSnapshot): string {
    return `deconz.gateway.${this.slug(this.bridgeId(snapshotArg))}`;
  }

  private static lightDeviceId(lightIdArg: string, lightArg: IDeconzLight): string {
    return `deconz.light.${this.slug(this.serialFromUniqueId(lightArg.uniqueid) || lightArg.uniqueid || lightIdArg)}`;
  }

  private static groupDeviceId(bridgeIdArg: string, groupIdArg: string): string {
    return `deconz.group.${this.slug(bridgeIdArg)}_${this.slug(groupIdArg)}`;
  }

  private static sensorDeviceId(sensorIdArg: string, sensorArg: IDeconzSensor): string {
    return `deconz.sensor.${this.slug(this.serialFromUniqueId(sensorArg.uniqueid) || sensorArg.uniqueid || sensorIdArg)}`;
  }

  private static bridgeId(snapshotArg: IDeconzSnapshot): string {
    return snapshotArg.config?.bridgeid || snapshotArg.config?.uuid || 'unknown';
  }

  private static serialFromUniqueId(uniqueIdArg?: string): string | undefined {
    return uniqueIdArg?.split('-')[0];
  }

  private static entityId(platformArg: string, nameArg: string, usedIdsArg: Map<string, number>): string {
    const base = `${platformArg}.${this.slug(nameArg)}`;
    const count = usedIdsArg.get(base) || 0;
    usedIdsArg.set(base, count + 1);
    return count === 0 ? base : `${base}_${count + 1}`;
  }

  private static slug(valueArg: string): string {
    return valueArg.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '') || 'deconz';
  }

  private static clamp(valueArg: number, minArg: number, maxArg: number): number {
    return Math.min(maxArg, Math.max(minArg, valueArg));
  }
}
