import * as plugins from '../../plugins.js';
import type { IIntegrationEntity, IIntegrationEvent, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
import type {
  IAirgradientCommand,
  IAirgradientDevice,
  IAirgradientDeviceConfig,
  IAirgradientEvent,
  IAirgradientMeasures,
  IAirgradientSnapshot,
  TAirgradientConfigField,
  TAirgradientDisplayPmStandard,
  TAirgradientPmStandard,
} from './airgradient.types.js';
import { airgradientDefaultPort } from './airgradient.types.js';

const airgradientDomain = 'airgradient';
const airgradientManufacturer = 'AirGradient';
const learningOffsetOptions = ['12', '60', '120', '360', '720'];
const abcDaysOptions = ['1', '8', '30', '90', '180', '0'];

interface IAirgradientSensorDescription {
  key: string;
  name: string;
  value: (measuresArg: IAirgradientMeasures) => unknown;
  unit?: string;
  deviceClass?: string;
  stateClass?: string;
  entityCategory?: string;
  enabledDefault?: boolean;
}

interface IAirgradientConfigSensorDescription {
  key: string;
  name: string;
  value: (configArg: IAirgradientDeviceConfig) => unknown;
  unit?: string;
  deviceClass?: string;
  entityCategory?: string;
  options?: string[];
}

interface IAirgradientWritableDescription {
  platform: TEntityPlatform;
  key: string;
  name: string;
  field: TAirgradientConfigField;
  value: (configArg: IAirgradientDeviceConfig) => unknown;
  options?: string[];
  min?: number;
  max?: number;
  step?: number;
  unit?: string;
  entityCategory?: string;
  localOnly?: boolean;
}

const measurementSensors: IAirgradientSensorDescription[] = [
  { key: 'pm01', name: 'PM1', value: (measuresArg) => measuresArg.pm01, unit: 'ug/m3', deviceClass: 'pm1', stateClass: 'measurement' },
  { key: 'pm02', name: 'PM2.5', value: (measuresArg) => measuresArg.pm02, unit: 'ug/m3', deviceClass: 'pm25', stateClass: 'measurement' },
  { key: 'pm10', name: 'PM10', value: (measuresArg) => measuresArg.pm10, unit: 'ug/m3', deviceClass: 'pm10', stateClass: 'measurement' },
  { key: 'temperature', name: 'Temperature', value: (measuresArg) => measuresArg.ambientTemperature, unit: 'C', deviceClass: 'temperature', stateClass: 'measurement' },
  { key: 'humidity', name: 'Humidity', value: (measuresArg) => measuresArg.relativeHumidity, unit: '%', deviceClass: 'humidity', stateClass: 'measurement' },
  { key: 'signal_strength', name: 'Signal strength', value: (measuresArg) => measuresArg.signalStrength, unit: 'dBm', deviceClass: 'signal_strength', stateClass: 'measurement', entityCategory: 'diagnostic', enabledDefault: false },
  { key: 'tvoc', name: 'VOC index', value: (measuresArg) => measuresArg.totalVolatileOrganicComponentIndex, stateClass: 'measurement' },
  { key: 'nitrogen_index', name: 'NOx index', value: (measuresArg) => measuresArg.nitrogenIndex, stateClass: 'measurement' },
  { key: 'co2', name: 'CO2', value: (measuresArg) => measuresArg.rco2, unit: 'ppm', deviceClass: 'co2', stateClass: 'measurement' },
  { key: 'pm003', name: 'PM0.3', value: (measuresArg) => measuresArg.pm003Count, unit: 'particles/dL', stateClass: 'measurement' },
  { key: 'nox_raw', name: 'Raw NOx', value: (measuresArg) => measuresArg.rawNitrogen, unit: 'ticks', stateClass: 'measurement', enabledDefault: false },
  { key: 'tvoc_raw', name: 'Raw VOC', value: (measuresArg) => measuresArg.rawTotalVolatileOrganicComponent, unit: 'ticks', stateClass: 'measurement', enabledDefault: false },
  { key: 'pm02_raw', name: 'Raw PM2.5', value: (measuresArg) => measuresArg.rawPm02, unit: 'ug/m3', deviceClass: 'pm25', stateClass: 'measurement', enabledDefault: false },
];

const configSensors: IAirgradientConfigSensorDescription[] = [
  { key: 'co2_automatic_baseline_calibration_days', name: 'Carbon dioxide automatic baseline calibration', value: (configArg) => configArg.co2AutomaticBaselineCalibrationDays, unit: 'd', deviceClass: 'duration', entityCategory: 'diagnostic' },
  { key: 'nox_learning_offset', name: 'NOx index learning offset', value: (configArg) => configArg.noxLearningOffset, unit: 'h', deviceClass: 'duration', entityCategory: 'diagnostic' },
  { key: 'tvoc_learning_offset', name: 'VOC index learning offset', value: (configArg) => configArg.tvocLearningOffset, unit: 'h', deviceClass: 'duration', entityCategory: 'diagnostic' },
];

const ledBarConfigSensors: IAirgradientConfigSensorDescription[] = [
  { key: 'led_bar_mode', name: 'LED bar mode', value: (configArg) => configArg.ledBarMode, deviceClass: 'enum', options: ['off', 'co2', 'pm'], entityCategory: 'diagnostic' },
  { key: 'led_bar_brightness', name: 'LED bar brightness', value: (configArg) => configArg.ledBarBrightness, unit: '%', entityCategory: 'diagnostic' },
];

const displayConfigSensors: IAirgradientConfigSensorDescription[] = [
  { key: 'display_temperature_unit', name: 'Display temperature unit', value: (configArg) => configArg.temperatureUnit, deviceClass: 'enum', options: ['c', 'f'], entityCategory: 'diagnostic' },
  { key: 'display_pm_standard', name: 'Display PM standard', value: (configArg) => displayPmStandard(configArg.pmStandard), deviceClass: 'enum', options: ['ugm3', 'us_aqi'], entityCategory: 'diagnostic' },
  { key: 'display_brightness', name: 'Display brightness', value: (configArg) => configArg.displayBrightness, unit: '%', entityCategory: 'diagnostic' },
];

const writableDescriptions: IAirgradientWritableDescription[] = [
  { platform: 'select', key: 'configuration_control', name: 'Configuration source', field: 'configurationControl', value: (configArg) => configArg.configurationControl === 'both' ? null : configArg.configurationControl, options: ['cloud', 'local'], entityCategory: 'config' },
  { platform: 'select', key: 'nox_index_learning_time_offset', name: 'NOx index learning offset', field: 'noxLearningOffset', value: (configArg) => optionValue(configArg.noxLearningOffset, learningOffsetOptions), options: learningOffsetOptions, entityCategory: 'config', localOnly: true },
  { platform: 'select', key: 'voc_index_learning_time_offset', name: 'VOC index learning offset', field: 'tvocLearningOffset', value: (configArg) => optionValue(configArg.tvocLearningOffset, learningOffsetOptions), options: learningOffsetOptions, entityCategory: 'config', localOnly: true },
  { platform: 'select', key: 'co2_automatic_baseline_calibration', name: 'CO2 automatic baseline duration', field: 'abcDays', value: (configArg) => optionValue(configArg.co2AutomaticBaselineCalibrationDays, abcDaysOptions), options: abcDaysOptions, entityCategory: 'config', localOnly: true },
  { platform: 'select', key: 'display_temperature_unit', name: 'Display temperature unit', field: 'temperatureUnit', value: (configArg) => configArg.temperatureUnit, options: ['c', 'f'], entityCategory: 'config', localOnly: true },
  { platform: 'select', key: 'display_pm_standard', name: 'Display PM standard', field: 'pmStandard', value: (configArg) => displayPmStandard(configArg.pmStandard), options: ['ugm3', 'us_aqi'], entityCategory: 'config', localOnly: true },
  { platform: 'select', key: 'led_bar_mode', name: 'LED bar mode', field: 'ledBarMode', value: (configArg) => configArg.ledBarMode, options: ['off', 'co2', 'pm'], entityCategory: 'config', localOnly: true },
  { platform: 'number', key: 'display_brightness', name: 'Display brightness', field: 'displayBrightness', value: (configArg) => configArg.displayBrightness, min: 0, max: 100, step: 1, unit: '%', entityCategory: 'config', localOnly: true },
  { platform: 'number', key: 'led_bar_brightness', name: 'LED bar brightness', field: 'ledBarBrightness', value: (configArg) => configArg.ledBarBrightness, min: 0, max: 100, step: 1, unit: '%', entityCategory: 'config', localOnly: true },
  { platform: 'switch', key: 'post_data_to_airgradient', name: 'Post data to AirGradient', field: 'postDataToAirGradient', value: (configArg) => configArg.postDataToAirGradient ? 'on' : 'off', entityCategory: 'config', localOnly: true },
  { platform: 'button', key: 'co2_calibration', name: 'Calibrate CO2 sensor', field: 'co2CalibrationRequested', value: () => 'idle', entityCategory: 'config', localOnly: true },
  { platform: 'button', key: 'led_bar_test', name: 'Test LED bar', field: 'ledBarTestRequested', value: () => 'idle', entityCategory: 'config', localOnly: true },
];

export class AirgradientMapper {
  public static toDevices(snapshotArg: IAirgradientSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
    return snapshotArg.devices.map((deviceArg) => this.toDevice(deviceArg, snapshotArg.connected, updatedAt));
  }

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

    for (const device of snapshotArg.devices) {
      const deviceId = this.deviceId(device);
      const name = this.deviceName(device);
      const available = snapshotArg.connected && device.online !== false;
      const measures = device.measures;
      const config = device.config;

      if (measures) {
        for (const sensor of measurementSensors) {
          const value = sensor.value(measures);
          if (value === undefined || value === null) {
            continue;
          }
          entities.push(this.entity('sensor', `${name} ${sensor.name}`, deviceId, this.uniqueId(device, sensor.key), value, usedIds, {
            deviceClass: sensor.deviceClass,
            stateClass: sensor.stateClass,
            unit: sensor.unit,
            entityCategory: sensor.entityCategory,
            enabledDefault: sensor.enabledDefault,
          }, available));
        }
      }

      if (config) {
        for (const sensor of this.configSensorDescriptions(device)) {
          entities.push(this.entity('sensor', `${name} ${sensor.name}`, deviceId, this.uniqueId(device, sensor.key), sensor.value(config) ?? 'unknown', usedIds, {
            deviceClass: sensor.deviceClass,
            unit: sensor.unit,
            entityCategory: sensor.entityCategory,
            options: sensor.options,
            enabledDefault: config.configurationControl !== 'local' ? false : undefined,
          }, available));
        }

        for (const description of this.writableDescriptionsForDevice(device)) {
          if (description.localOnly && config.configurationControl !== 'local') {
            continue;
          }
          entities.push(this.entity(description.platform, `${name} ${description.name}`, deviceId, this.uniqueId(device, description.key), description.value(config) ?? 'unknown', usedIds, {
            airgradientConfigField: description.field,
            options: description.options,
            min: description.min,
            max: description.max,
            step: description.step,
            unit: description.unit,
            entityCategory: description.entityCategory,
            writable: true,
          }, available));
        }
      }

      if (device.firmwareVersion || device.latestFirmwareVersion) {
        entities.push(this.entity('update', `${name} Firmware`, deviceId, this.uniqueId(device, 'update'), device.firmwareVersion || 'unknown', usedIds, {
          deviceClass: 'firmware',
          installedVersion: device.firmwareVersion,
          latestVersion: device.latestFirmwareVersion,
        }, available));
      }
    }

    return entities;
  }

  public static commandForService(snapshotArg: IAirgradientSnapshot, requestArg: IServiceCallRequest): IAirgradientCommand | undefined {
    if (requestArg.domain === airgradientDomain && ['refresh', 'reload'].includes(requestArg.service)) {
      return { type: 'refresh', service: requestArg.service };
    }

    if (requestArg.domain === airgradientDomain && requestArg.service === 'set_config') {
      const field = this.stringData(requestArg, 'field');
      const value = requestArg.data?.value;
      return this.commandForField(field, value, requestArg);
    }

    if (requestArg.domain === airgradientDomain && requestArg.service === 'request_co2_calibration') {
      return this.commandForField('co2CalibrationRequested', true, requestArg);
    }

    if (requestArg.domain === airgradientDomain && requestArg.service === 'request_led_bar_test') {
      return this.commandForField('ledBarTestRequested', true, requestArg);
    }

    const target = this.findTargetEntity(snapshotArg, requestArg);
    if (!target || target.attributes?.writable !== true || typeof target.attributes.airgradientConfigField !== 'string') {
      return undefined;
    }
    const field = target.attributes.airgradientConfigField;
    const value = this.valueForEntityCommand(target, requestArg);
    return this.commandForField(field, value, requestArg, target);
  }

  public static toIntegrationEvent(eventArg: IAirgradientEvent): IIntegrationEvent {
    return {
      type: eventArg.type === 'command_failed' || eventArg.type === 'error' ? 'error' : 'state_changed',
      integrationDomain: airgradientDomain,
      deviceId: eventArg.deviceId,
      entityId: eventArg.entityId,
      data: eventArg,
      timestamp: eventArg.timestamp || Date.now(),
    };
  }

  private static toDevice(deviceArg: IAirgradientDevice, connectedArg: boolean, 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: connectedArg && deviceArg.online !== false ? 'online' : 'offline', updatedAt: updatedAtArg },
    ];

    if (deviceArg.measures) {
      for (const sensor of measurementSensors) {
        const value = sensor.value(deviceArg.measures);
        if (value === undefined || value === null) {
          continue;
        }
        features.push({ id: sensor.key, capability: 'sensor', name: sensor.name, readable: true, writable: false, unit: sensor.unit });
        this.pushDeviceState(state, sensor.key, value, updatedAtArg);
      }
    }

    if (deviceArg.config) {
      for (const description of this.writableDescriptionsForDevice(deviceArg)) {
        const writable = description.localOnly ? deviceArg.config.configurationControl === 'local' : true;
        features.push({ id: description.key, capability: description.platform === 'number' || description.platform === 'select' ? 'sensor' : 'switch', name: description.name, readable: true, writable, unit: description.unit });
        this.pushDeviceState(state, description.key, description.value(deviceArg.config), updatedAtArg);
      }
    }

    return {
      id: this.deviceId(deviceArg),
      integrationDomain: airgradientDomain,
      name: this.deviceName(deviceArg),
      protocol: 'http',
      manufacturer: deviceArg.manufacturer || airgradientManufacturer,
      model: deviceArg.modelName || deviceArg.model || 'AirGradient monitor',
      online: connectedArg && deviceArg.online !== false,
      features,
      state,
      metadata: this.cleanAttributes({
        host: deviceArg.host,
        port: deviceArg.port || airgradientDefaultPort,
        serialNumber: deviceArg.serialNumber,
        firmwareVersion: deviceArg.firmwareVersion,
        latestFirmwareVersion: deviceArg.latestFirmwareVersion,
        modelId: deviceArg.model,
        ...deviceArg.metadata,
      }),
    };
  }

  private static configSensorDescriptions(deviceArg: IAirgradientDevice): IAirgradientConfigSensorDescription[] {
    const descriptions = [...configSensors];
    if (this.hasLedBar(deviceArg)) {
      descriptions.push(...ledBarConfigSensors);
    }
    if (this.hasDisplay(deviceArg)) {
      descriptions.push(...displayConfigSensors);
    }
    return descriptions;
  }

  private static writableDescriptionsForDevice(deviceArg: IAirgradientDevice): IAirgradientWritableDescription[] {
    return writableDescriptions.filter((descriptionArg) => {
      if (descriptionArg.key.startsWith('display_')) {
        return this.hasDisplay(deviceArg);
      }
      if (descriptionArg.key.startsWith('led_bar') || descriptionArg.key === 'led_bar_test') {
        return this.hasLedBar(deviceArg);
      }
      return true;
    });
  }

  private static valueForEntityCommand(entityArg: IIntegrationEntity, requestArg: IServiceCallRequest): unknown {
    const field = entityArg.attributes?.airgradientConfigField;
    if (entityArg.platform === 'switch') {
      if (requestArg.service === 'turn_on') {
        return true;
      }
      if (requestArg.service === 'turn_off') {
        return false;
      }
    }
    if (entityArg.platform === 'button' && requestArg.service === 'press') {
      return true;
    }
    if (entityArg.platform === 'number' && requestArg.service === 'set_value') {
      return this.numberData(requestArg, 'value');
    }
    if (entityArg.platform === 'select' && requestArg.service === 'select_option') {
      const option = this.stringData(requestArg, 'option');
      if (field === 'pmStandard') {
        return pmStandardFromDisplay(option);
      }
      if (field === 'noxLearningOffset' || field === 'tvocLearningOffset' || field === 'abcDays') {
        return option && /^\d+$/.test(option) ? Number(option) : undefined;
      }
      return option;
    }
    return undefined;
  }

  private static commandForField(fieldArg: unknown, valueArg: unknown, requestArg: IServiceCallRequest, entityArg?: IIntegrationEntity): IAirgradientCommand | undefined {
    if (!this.isConfigField(fieldArg)) {
      return undefined;
    }
    const normalizedValue = this.normalizeCommandValue(fieldArg, valueArg);
    if (normalizedValue === undefined) {
      return undefined;
    }
    return {
      type: 'set_config',
      service: requestArg.service,
      field: fieldArg,
      value: normalizedValue,
      payload: { [fieldArg]: normalizedValue },
      deviceId: entityArg?.deviceId || requestArg.target.deviceId,
      entityId: entityArg?.id || requestArg.target.entityId,
      target: requestArg.target,
    };
  }

  private static normalizeCommandValue(fieldArg: TAirgradientConfigField, valueArg: unknown): unknown {
    if (fieldArg === 'configurationControl') {
      return valueArg === 'cloud' || valueArg === 'local' ? valueArg : undefined;
    }
    if (fieldArg === 'pmStandard') {
      return valueArg === 'ugm3' || valueArg === 'us-aqi' ? valueArg : undefined;
    }
    if (fieldArg === 'temperatureUnit') {
      return valueArg === 'c' || valueArg === 'f' ? valueArg : undefined;
    }
    if (fieldArg === 'ledBarMode') {
      return valueArg === 'off' || valueArg === 'co2' || valueArg === 'pm' ? valueArg : undefined;
    }
    if (fieldArg === 'postDataToAirGradient' || fieldArg === 'co2CalibrationRequested' || fieldArg === 'ledBarTestRequested') {
      return typeof valueArg === 'boolean' ? valueArg : undefined;
    }
    if (fieldArg === 'displayBrightness' || fieldArg === 'ledBarBrightness') {
      return this.numberInRange(valueArg, 0, 100);
    }
    if (fieldArg === 'noxLearningOffset' || fieldArg === 'tvocLearningOffset') {
      const value = this.integerValue(valueArg);
      return value !== undefined && learningOffsetOptions.includes(String(value)) ? value : undefined;
    }
    if (fieldArg === 'abcDays') {
      const value = this.integerValue(valueArg);
      return value !== undefined && abcDaysOptions.includes(String(value)) ? value : undefined;
    }
    return undefined;
  }

  private static findTargetEntity(snapshotArg: IAirgradientSnapshot, requestArg: IServiceCallRequest): IIntegrationEntity | undefined {
    const entities = this.toEntities(snapshotArg);
    if (requestArg.target.entityId) {
      return entities.find((entityArg) => entityArg.id === requestArg.target.entityId || entityArg.uniqueId === requestArg.target.entityId);
    }
    if (requestArg.target.deviceId) {
      return entities.find((entityArg) => entityArg.deviceId === requestArg.target.deviceId && entityArg.platform === requestArg.domain)
        || entities.find((entityArg) => entityArg.deviceId === requestArg.target.deviceId && Boolean(entityArg.attributes?.writable));
    }
    return entities.find((entityArg) => entityArg.platform === requestArg.domain && Boolean(entityArg.attributes?.writable));
  }

  private static entity(platformArg: TEntityPlatform, nameArg: string, deviceIdArg: string, uniqueIdArg: string, stateArg: unknown, usedIdsArg: Map<string, number>, attributesArg: Record<string, unknown>, availableArg: boolean): IIntegrationEntity {
    const baseId = `${platformArg}.${this.slug(nameArg) || this.slug(uniqueIdArg)}`;
    const seen = usedIdsArg.get(baseId) || 0;
    usedIdsArg.set(baseId, seen + 1);
    return {
      id: seen ? `${baseId}_${seen + 1}` : baseId,
      uniqueId: uniqueIdArg,
      integrationDomain: airgradientDomain,
      deviceId: deviceIdArg,
      platform: platformArg,
      name: nameArg,
      state: stateArg,
      attributes: this.cleanAttributes(attributesArg),
      available: availableArg,
    };
  }

  private static deviceId(deviceArg: IAirgradientDevice): string {
    return `airgradient.device.${this.slug(deviceArg.serialNumber || deviceArg.id || deviceArg.host || this.deviceName(deviceArg))}`;
  }

  private static uniqueId(deviceArg: IAirgradientDevice, keyArg: string): string {
    return `airgradient_${this.slug(deviceArg.serialNumber || deviceArg.id || deviceArg.host || this.deviceName(deviceArg))}_${this.slug(keyArg)}`;
  }

  private static deviceName(deviceArg: IAirgradientDevice): string {
    return deviceArg.name || deviceArg.modelName || (deviceArg.model ? `${airgradientManufacturer} ${deviceArg.model}` : `${airgradientManufacturer} monitor`);
  }

  private static hasDisplay(deviceArg: IAirgradientDevice): boolean {
    return Boolean(deviceArg.model?.includes('I') || deviceArg.measures?.model?.includes('I'));
  }

  private static hasLedBar(deviceArg: IAirgradientDevice): boolean {
    return Boolean(deviceArg.model?.includes('L') || deviceArg.measures?.model?.includes('L'));
  }

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

  private static deviceStateValue(valueArg: unknown): plugins.shxInterfaces.data.TDeviceStateValue {
    if (typeof valueArg === 'string' || typeof valueArg === 'number' || typeof valueArg === 'boolean' || valueArg === null || this.isRecord(valueArg)) {
      return valueArg;
    }
    return valueArg === undefined ? null : String(valueArg);
  }

  private static numberData(requestArg: IServiceCallRequest, keyArg: string): number | undefined {
    return this.numberValue(requestArg.data?.[keyArg]);
  }

  private static stringData(requestArg: IServiceCallRequest, keyArg: string): string | undefined {
    const value = requestArg.data?.[keyArg];
    return typeof value === 'string' && value.trim() ? value.trim() : undefined;
  }

  private static numberInRange(valueArg: unknown, minArg: number, maxArg: number): number | undefined {
    const value = this.integerValue(valueArg);
    return value !== undefined && value >= minArg && value <= maxArg ? value : undefined;
  }

  private static integerValue(valueArg: unknown): number | undefined {
    const value = this.numberValue(valueArg);
    return value === undefined ? undefined : Math.trunc(value);
  }

  private static numberValue(valueArg: unknown): number | undefined {
    if (typeof valueArg === 'number' && Number.isFinite(valueArg)) {
      return valueArg;
    }
    if (typeof valueArg === 'string' && valueArg.trim() && Number.isFinite(Number(valueArg))) {
      return Number(valueArg);
    }
    return undefined;
  }

  private static isConfigField(valueArg: unknown): valueArg is TAirgradientConfigField {
    return typeof valueArg === 'string' && [
      'pmStandard',
      'temperatureUnit',
      'configurationControl',
      'ledBarMode',
      'co2CalibrationRequested',
      'ledBarTestRequested',
      'displayBrightness',
      'ledBarBrightness',
      'postDataToAirGradient',
      'abcDays',
      'noxLearningOffset',
      'tvocLearningOffset',
    ].includes(valueArg);
  }

  private static cleanAttributes(attributesArg: Record<string, unknown>): Record<string, unknown> {
    return Object.fromEntries(Object.entries(attributesArg).filter(([, valueArg]) => valueArg !== undefined));
  }

  private static isRecord(valueArg: unknown): valueArg is Record<string, unknown> {
    return typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg);
  }

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

const displayPmStandard = (valueArg: TAirgradientPmStandard | undefined): TAirgradientDisplayPmStandard | undefined => valueArg === 'us-aqi' ? 'us_aqi' : valueArg;
const pmStandardFromDisplay = (valueArg: string | undefined): TAirgradientPmStandard | undefined => valueArg === 'us_aqi' ? 'us-aqi' : valueArg === 'ugm3' ? 'ugm3' : undefined;
const optionValue = (valueArg: unknown, optionsArg: string[]): string | undefined => {
  const text = typeof valueArg === 'number' ? String(valueArg) : typeof valueArg === 'string' ? valueArg : undefined;
  return text && optionsArg.includes(text) ? text : undefined;
};
