import * as plugins from '../../plugins.js';
import type { IIntegrationEntity, IIntegrationEvent, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
import type {
  IOpnsenseActionDescriptor,
  IOpnsenseArpEntry,
  IOpnsenseClientDevice,
  IOpnsenseCommand,
  IOpnsenseConfig,
  IOpnsenseEvent,
  IOpnsenseFirewallAlias,
  IOpnsenseFirewallRule,
  IOpnsenseFirewallSnapshot,
  IOpnsenseGatewayInfo,
  IOpnsenseInterfaceInfo,
  IOpnsenseManualEntry,
  IOpnsenseRouterInfo,
  IOpnsenseSensorMap,
  IOpnsenseServiceInfo,
  IOpnsenseSnapshot,
  IOpnsenseSwitchInfo,
  IOpnsenseSystemInfo,
  IOpnsenseTelemetryInfo,
  IOpnsenseVpnInstance,
  IOpnsenseVpnSnapshot,
} from './opnsense.types.js';
import { opnsenseDefaultPort, opnsenseDefaultVerifySsl, opnsenseDomain } from './opnsense.types.js';

type TSensorDescriptor = {
  key: string;
  name: string;
  unit?: string;
  deviceClass?: string;
  stateClass?: string;
  entityCategory?: string;
};

type TMergedManualData = {
  router?: IOpnsenseRouterInfo;
  devices: IOpnsenseClientDevice[];
  arpTable: IOpnsenseArpEntry[];
  interfaces: IOpnsenseInterfaceInfo[];
  gateways: IOpnsenseGatewayInfo[];
  firewall?: IOpnsenseFirewallSnapshot;
  system?: IOpnsenseSystemInfo;
  telemetry?: IOpnsenseTelemetryInfo;
  services: IOpnsenseServiceInfo[];
  vpn?: IOpnsenseVpnSnapshot;
  sensors?: IOpnsenseSensorMap;
  switches: IOpnsenseSwitchInfo[];
  actions: IOpnsenseActionDescriptor[];
  hasData: boolean;
};

type TOpnsenseNatRules = IOpnsenseFirewallRule[] | Record<string, IOpnsenseFirewallRule> | undefined;

const manufacturer = 'OPNsense';

const standardSensorDescriptors: TSensorDescriptor[] = [
  { key: 'connected_clients', name: 'Connected clients', unit: 'clients', stateClass: 'measurement' },
  { key: 'cpu_usage', name: 'CPU usage', unit: '%', stateClass: 'measurement', entityCategory: 'diagnostic' },
  { key: 'memory_usage', name: 'Memory usage', unit: '%', stateClass: 'measurement', entityCategory: 'diagnostic' },
  { key: 'pf_state_used', name: 'Firewall state table used', unit: 'states', stateClass: 'measurement', entityCategory: 'diagnostic' },
  { key: 'pf_state_used_percent', name: 'Firewall state table used', unit: '%', stateClass: 'measurement', entityCategory: 'diagnostic' },
  { key: 'mbuf_used_percent', name: 'Mbuf used', unit: '%', stateClass: 'measurement', entityCategory: 'diagnostic' },
  { key: 'uptime', name: 'Uptime', unit: 's', deviceClass: 'duration', stateClass: 'total', entityCategory: 'diagnostic' },
];

export class OpnsenseMapper {
  public static toSnapshot(configArg: IOpnsenseConfig, connectedArg?: boolean, eventsArg: IOpnsenseEvent[] = []): IOpnsenseSnapshot {
    const source = configArg.snapshot;
    const manualSnapshots = (configArg.manualEntries || [])
      .map((entryArg) => entryArg.snapshot)
      .filter((snapshotArg): snapshotArg is IOpnsenseSnapshot => Boolean(snapshotArg));
    const manualData = this.mergeManualEntries(configArg.manualEntries || []);
    const trackerInterfaces = this.trackerInterfaces(configArg, source);
    const router = this.routerInfo(configArg, source, manualSnapshots, manualData.router);
    const interfaces = this.uniqueInterfaces([
      ...(source?.interfaces || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.interfaces || []),
      ...(configArg.interfaces || []),
      ...manualData.interfaces,
    ]);
    const devices = this.uniqueClients([
      ...(source?.devices || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.devices || []),
      ...(configArg.devices || []),
      ...(configArg.clients || []),
      ...manualData.devices,
      ...this.devicesFromArp([...(configArg.arpTable || []), ...manualData.arpTable], trackerInterfaces),
    ]);
    const gateways = this.uniqueGateways([
      ...(source?.gateways || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.gateways || []),
      ...(configArg.gateways || []),
      ...manualData.gateways,
    ]);
    const firewall = this.firewallSnapshot(source?.firewall, ...manualSnapshots.map((snapshotArg) => snapshotArg.firewall), configArg.firewall, manualData.firewall);
    const system = this.objectMerge<IOpnsenseSystemInfo>(source?.system, ...manualSnapshots.map((snapshotArg) => snapshotArg.system), configArg.system, manualData.system);
    const telemetry = this.objectMerge<IOpnsenseTelemetryInfo>(source?.telemetry, ...manualSnapshots.map((snapshotArg) => snapshotArg.telemetry), configArg.telemetry, manualData.telemetry);
    const services = this.uniqueServices([
      ...(source?.services || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.services || []),
      ...(configArg.services || []),
      ...manualData.services,
    ]);
    const vpn = this.vpnSnapshot(source?.vpn, ...manualSnapshots.map((snapshotArg) => snapshotArg.vpn), configArg.vpn || configArg.vpns, manualData.vpn);
    const switches = this.uniqueSwitches([
      ...(source?.switches || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.switches || []),
      ...(configArg.switches || []),
      ...manualData.switches,
    ]);
    const sensors = this.sensorMap([
      source?.sensors,
      ...manualSnapshots.map((snapshotArg) => snapshotArg.sensors),
      configArg.sensors,
      manualData.sensors,
    ], devices, interfaces, gateways, services, system, telemetry, firewall, vpn);
    const actions = this.uniqueActions([
      ...(source?.actions || []),
      ...manualSnapshots.flatMap((snapshotArg) => snapshotArg.actions || []),
      ...(configArg.actions || []),
      ...manualData.actions,
      ...this.actionsFromRouter(router),
      ...this.actionsFromInterfaces(interfaces),
      ...this.actionsFromServices(services),
      ...this.actionsFromFirewall(firewall),
      ...this.actionsFromVpn(vpn),
      ...this.actionsFromSwitches(switches),
      ...this.actionsFromSystem(system),
    ]);
    const hasManualData = Boolean(
      source
      || manualSnapshots.length
      || configArg.router
      || configArg.devices?.length
      || configArg.clients?.length
      || configArg.arpTable?.length
      || configArg.interfaces?.length
      || configArg.gateways?.length
      || configArg.firewall
      || configArg.system
      || configArg.telemetry
      || configArg.services?.length
      || configArg.vpn
      || configArg.vpns
      || configArg.sensors
      || configArg.switches?.length
      || manualData.hasData
    );

    return {
      connected: connectedArg ?? configArg.connected ?? source?.connected ?? hasManualData,
      source: source?.source || (hasManualData ? 'manual' : 'runtime'),
      updatedAt: source?.updatedAt || new Date().toISOString(),
      router,
      devices,
      interfaces,
      gateways,
      firewall,
      system,
      telemetry,
      services,
      vpn,
      sensors,
      switches,
      actions,
      events: [...(source?.events || []), ...(configArg.events || []), ...eventsArg],
      error: source?.error,
      metadata: {
        ...source?.metadata,
        ...configArg.metadata,
        trackerInterfaces,
        homeAssistantLegacyTrackerMapping: true,
        liveHttpImplemented: false,
        commandExecutorConfigured: Boolean(configArg.commandExecutor || configArg.nativeClient?.executeCommand),
      },
    };
  }

  public static toDevices(snapshotArg: IOpnsenseSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
    const devices: plugins.shxInterfaces.data.IDeviceDefinition[] = [this.routerDevice(snapshotArg, updatedAt)];
    for (const client of snapshotArg.devices) {
      devices.push(this.clientDevice(client, snapshotArg, updatedAt));
    }
    return devices;
  }

  public static toEntities(snapshotArg: IOpnsenseSnapshot): IIntegrationEntity[] {
    const entities: IIntegrationEntity[] = [];
    const usedIds = new Map<string, number>();
    const routerDeviceId = this.routerDeviceId(snapshotArg);
    const routerName = this.routerName(snapshotArg);
    const uniqueBase = this.uniqueBase(snapshotArg);
    const seenSensorKeys = new Set<string>();

    entities.push(this.entity('binary_sensor', `${routerName} Connected`, routerDeviceId, `${uniqueBase}_connected`, snapshotArg.connected ? 'on' : 'off', usedIds, {
      deviceClass: 'connectivity',
      host: snapshotArg.router.host,
      port: snapshotArg.router.port,
      verifySsl: snapshotArg.router.verifySsl,
    }, true));

    const firmware = snapshotArg.router.firmware || snapshotArg.router.productVersion || snapshotArg.system.firmwareVersion || snapshotArg.system.productVersion;
    if (firmware) {
      entities.push(this.entity('sensor', `${routerName} Firmware`, routerDeviceId, `${uniqueBase}_firmware`, firmware, usedIds, {
        entityCategory: 'diagnostic',
        latestVersion: snapshotArg.router.latestFirmware || snapshotArg.system.productLatest,
        updateAvailable: snapshotArg.router.updateAvailable ?? snapshotArg.system.updateAvailable,
      }, snapshotArg.connected));
    }

    if (this.pendingNotices(snapshotArg.system) !== undefined) {
      entities.push(this.entity('binary_sensor', `${routerName} Pending notices`, routerDeviceId, `${uniqueBase}_pending_notices`, this.pendingNotices(snapshotArg.system) ? 'on' : 'off', usedIds, {
        entityCategory: 'diagnostic',
        notices: snapshotArg.system.pendingNotices || snapshotArg.system.pending_notices,
      }, snapshotArg.connected));
    }

    for (const descriptor of standardSensorDescriptors) {
      const value = snapshotArg.sensors[descriptor.key];
      if (value === undefined) {
        continue;
      }
      seenSensorKeys.add(descriptor.key);
      entities.push(this.entity('sensor', `${routerName} ${descriptor.name}`, routerDeviceId, `${uniqueBase}_${this.slug(descriptor.key)}`, this.sensorValue(value), usedIds, {
        nativeKey: descriptor.key,
        unit: descriptor.unit,
        deviceClass: descriptor.deviceClass,
        stateClass: descriptor.stateClass,
        entityCategory: descriptor.entityCategory,
      }, snapshotArg.connected));
    }

    for (const [key, value] of Object.entries(snapshotArg.sensors)) {
      if (seenSensorKeys.has(key) || value === undefined || typeof value === 'object') {
        continue;
      }
      entities.push(this.entity('sensor', `${routerName} ${this.title(key)}`, routerDeviceId, `${uniqueBase}_${this.slug(key)}`, this.sensorValue(value), usedIds, {
        nativeKey: key,
        entityCategory: 'diagnostic',
      }, snapshotArg.connected));
    }

    for (const iface of snapshotArg.interfaces) {
      this.pushInterfaceEntities(entities, snapshotArg, iface, usedIds);
    }
    for (const gateway of snapshotArg.gateways) {
      this.pushGatewayEntities(entities, snapshotArg, gateway, usedIds);
    }
    for (const client of snapshotArg.devices) {
      this.pushClientEntities(entities, snapshotArg, client, usedIds);
    }
    this.pushFirewallEntities(entities, snapshotArg, usedIds);
    this.pushServiceEntities(entities, snapshotArg, usedIds);
    this.pushVpnEntities(entities, snapshotArg, usedIds);
    this.pushGenericSwitchEntities(entities, snapshotArg, usedIds);

    if (this.hasFirmwareUpdate(snapshotArg)) {
      entities.push(this.entity('update', `${routerName} Firmware`, routerDeviceId, `${uniqueBase}_firmware_update`, this.updateAvailable(snapshotArg) ? 'on' : 'off', usedIds, {
        nativeType: 'firmware_update',
        nativeAction: 'firmware_update',
        installedVersion: firmware,
        latestVersion: snapshotArg.router.latestFirmware || snapshotArg.system.productLatest,
        writable: this.snapshotActions(snapshotArg).some((actionArg) => actionArg.target === 'router' && (actionArg.action === 'firmware_update' || actionArg.action === 'firmware_upgrade')),
      }, snapshotArg.connected));
    }

    for (const action of this.snapshotActions(snapshotArg)) {
      const button = this.actionButton(snapshotArg, action, usedIds);
      if (button) {
        entities.push(button);
      }
    }

    return entities;
  }

  public static commandForService(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest): IOpnsenseCommand | { error: string } | undefined {
    if (requestArg.domain === opnsenseDomain) {
      return this.opnsenseServiceCommand(snapshotArg, requestArg);
    }

    const targetEntity = this.findTargetEntity(snapshotArg, requestArg);
    if (!targetEntity) {
      return undefined;
    }

    if (requestArg.domain === 'switch' && (requestArg.service === 'turn_on' || requestArg.service === 'turn_off')) {
      return this.switchCommand(snapshotArg, targetEntity, requestArg, requestArg.service === 'turn_on');
    }

    if (requestArg.domain === 'button' && requestArg.service === 'press') {
      return this.buttonCommand(snapshotArg, targetEntity, requestArg);
    }

    if (requestArg.domain === 'update' && requestArg.service === 'install' && targetEntity.attributes?.nativeType === 'firmware_update') {
      return this.firmwareCommand(snapshotArg, requestArg, targetEntity);
    }

    return undefined;
  }

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

  public static defaultPort(): number {
    return opnsenseDefaultPort;
  }

  public static normalizeMac(valueArg?: string): string | undefined {
    if (!valueArg) {
      return undefined;
    }
    const compact = valueArg.replace(/[^0-9a-f]/gi, '').toLowerCase();
    return compact.length === 12 ? compact.match(/.{1,2}/g)?.join(':') : valueArg.toLowerCase();
  }

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

  private static routerInfo(configArg: IOpnsenseConfig, sourceArg: IOpnsenseSnapshot | undefined, manualSnapshotsArg: IOpnsenseSnapshot[], manualRouterArg?: IOpnsenseRouterInfo): IOpnsenseRouterInfo {
    const parsed = this.parseEndpoint(configArg.url || configArg.router?.url || sourceArg?.router.url);
    const manualRouter = manualRouterArg || manualSnapshotsArg.find((snapshotArg) => snapshotArg.router)?.router;
    const router = {
      ...sourceArg?.router,
      ...manualRouter,
      ...configArg.router,
    };
    const host = configArg.host || parsed.host || router.host || sourceArg?.router.host;
    const port = configArg.port || parsed.port || router.port || (host ? opnsenseDefaultPort : undefined);
    const ssl = true;
    const verifySsl = configArg.verifySsl ?? configArg.verify_ssl ?? router.verifySsl ?? opnsenseDefaultVerifySsl;
    const configurationUrl = router.configurationUrl || (host ? this.endpointUrl(host, port) : router.url || configArg.url);
    const mac = this.normalizeMac(configArg.uniqueId || router.macAddress || sourceArg?.router.macAddress);
    return {
      ...router,
      id: router.id || configArg.uniqueId || mac || (host ? `${host}:${port || opnsenseDefaultPort}` : undefined) || configArg.name || 'opnsense',
      host,
      port,
      ssl,
      verifySsl,
      url: configurationUrl,
      name: configArg.name || router.name || host || 'OPNsense',
      model: router.model || 'OPNsense Firewall',
      firmware: router.firmware || router.productVersion,
      macAddress: mac || router.macAddress,
      manufacturer: router.manufacturer || manufacturer,
      configurationUrl,
    };
  }

  private static mergeManualEntries(entriesArg: IOpnsenseManualEntry[]): TMergedManualData {
    const devices: IOpnsenseClientDevice[] = [];
    const arpTable: IOpnsenseArpEntry[] = [];
    const interfaces: IOpnsenseInterfaceInfo[] = [];
    const gateways: IOpnsenseGatewayInfo[] = [];
    const services: IOpnsenseServiceInfo[] = [];
    const switches: IOpnsenseSwitchInfo[] = [];
    const actions: IOpnsenseActionDescriptor[] = [];
    const sensors: IOpnsenseSensorMap = {};
    let router: IOpnsenseRouterInfo | undefined;
    let firewall: IOpnsenseFirewallSnapshot | undefined;
    let system: IOpnsenseSystemInfo | undefined;
    let telemetry: IOpnsenseTelemetryInfo | undefined;
    let vpn: IOpnsenseVpnSnapshot | undefined;
    let hasData = false;

    for (const entry of entriesArg) {
      if (entry.router) {
        router = { ...router, ...entry.router };
        hasData = true;
      } else if (!router && (entry.host || entry.url || entry.name || entry.model || entry.macAddress)) {
        router = {
          id: entry.id || entry.macAddress || entry.host || entry.url,
          url: entry.url,
          host: entry.host,
          port: entry.port,
          ssl: true,
          verifySsl: entry.verifySsl,
          name: entry.name,
          model: entry.model,
          macAddress: entry.macAddress,
          manufacturer: entry.manufacturer,
        };
        hasData = true;
      }
      firewall = this.firewallSnapshot(firewall, entry.firewall);
      system = this.objectMerge(system, entry.system);
      telemetry = this.objectMerge(telemetry, entry.telemetry);
      vpn = this.vpnSnapshot(vpn, entry.vpn || entry.vpns);
      devices.push(...(entry.devices || []), ...(entry.clients || []));
      arpTable.push(...(entry.arpTable || []));
      interfaces.push(...(entry.interfaces || []));
      gateways.push(...(entry.gateways || []));
      services.push(...(entry.services || []));
      switches.push(...(entry.switches || []));
      Object.assign(sensors, entry.sensors || {});
      actions.push(...(entry.actions || []));
      hasData = hasData || Boolean(entry.devices?.length || entry.clients?.length || entry.arpTable?.length || entry.interfaces?.length || entry.gateways?.length || entry.firewall || entry.system || entry.telemetry || entry.services?.length || entry.vpn || entry.vpns || entry.sensors || entry.switches?.length || entry.actions?.length);
    }

    return { router, devices, arpTable, interfaces, gateways, firewall, system, telemetry, services, vpn, sensors: Object.keys(sensors).length ? sensors : undefined, switches, actions, hasData };
  }

  private static devicesFromArp(entriesArg: IOpnsenseArpEntry[], trackerInterfacesArg: string[]): IOpnsenseClientDevice[] {
    const devices: IOpnsenseClientDevice[] = [];
    for (const entry of entriesArg) {
      const mac = this.normalizeMac(entry.mac || entry.macAddress || entry['mac-address']);
      if (!mac) {
        continue;
      }
      const interfaceDescription = this.stringValue(entry.intf_description || entry.interfaceDescription);
      if (trackerInterfacesArg.length && (!interfaceDescription || !trackerInterfacesArg.includes(interfaceDescription))) {
        continue;
      }
      const hostname = this.stringValue(entry.hostname);
      devices.push({
        mac,
        ipAddress: this.stringValue(entry.ipAddress || entry.ip || entry['ip-address'] || entry.address),
        hostname: hostname && hostname !== '?' ? hostname : undefined,
        name: hostname && hostname !== '?' ? hostname : undefined,
        connected: true,
        interface: this.stringValue(entry.interface),
        interfaceDescription,
        intf_description: interfaceDescription,
        manufacturer: this.stringValue(entry.manufacturer),
        expires: entry.expires,
        type: this.stringValue(entry.type),
      });
    }
    return devices;
  }

  private static sensorMap(sourcesArg: Array<IOpnsenseSensorMap | undefined>, devicesArg: IOpnsenseClientDevice[], interfacesArg: IOpnsenseInterfaceInfo[], gatewaysArg: IOpnsenseGatewayInfo[], servicesArg: IOpnsenseServiceInfo[], systemArg: IOpnsenseSystemInfo, telemetryArg: IOpnsenseTelemetryInfo, firewallArg: IOpnsenseFirewallSnapshot, vpnArg: IOpnsenseVpnSnapshot): IOpnsenseSensorMap {
    const sensors: IOpnsenseSensorMap = {};
    for (const source of sourcesArg) {
      Object.assign(sensors, source || {});
    }
    sensors.connected_clients ??= devicesArg.filter((deviceArg) => deviceArg.connected !== false).length;
    sensors.uptime ??= this.numberValue(systemArg.uptime) ?? this.numberValue(telemetryArg.system?.uptime);
    sensors.pending_notices ??= this.pendingNotices(systemArg);
    sensors.cpu_usage ??= this.numberValue(telemetryArg.cpu?.usage_total) ?? this.numberValue(telemetryArg.cpu?.usageTotal) ?? this.numberValue(telemetryArg.cpu?.total);
    sensors.memory_usage ??= this.numberValue(telemetryArg.memory?.used_percent) ?? this.numberValue(telemetryArg.memory?.usedPercent);
    sensors.pf_state_used ??= this.numberValue(firewallArg.state?.used) ?? this.numberValue(telemetryArg.pfstate?.used);
    sensors.pf_state_used_percent ??= this.numberValue(firewallArg.state?.usedPercent) ?? this.numberValue(firewallArg.state?.used_percent) ?? this.numberValue(telemetryArg.pfstate?.used_percent) ?? this.numberValue(telemetryArg.pfstate?.usedPercent);
    sensors.mbuf_used_percent ??= this.numberValue(telemetryArg.mbuf?.used_percent) ?? this.numberValue(telemetryArg.mbuf?.usedPercent);
    sensors.interface_count ??= interfacesArg.length;
    sensors.gateway_count ??= gatewaysArg.length;
    sensors.running_services ??= servicesArg.filter((serviceArg) => this.serviceRunning(serviceArg)).length;
    sensors.openvpn_servers ??= this.vpnInstances(vpnArg, 'openvpn', 'servers').length;
    sensors.wireguard_servers ??= this.vpnInstances(vpnArg, 'wireguard', 'servers').length;
    return this.cleanAttributes(sensors) as IOpnsenseSensorMap;
  }

  private static routerDevice(snapshotArg: IOpnsenseSnapshot, updatedAtArg: string): plugins.shxInterfaces.data.IDeviceDefinition {
    const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
      { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
      { id: 'connected_clients', capability: 'sensor', name: 'Connected clients', readable: true, writable: false },
    ];
    const state: plugins.shxInterfaces.data.IDeviceState[] = [
      { featureId: 'connectivity', value: snapshotArg.connected ? 'online' : 'offline', updatedAt: updatedAtArg },
      { featureId: 'connected_clients', value: snapshotArg.sensors.connected_clients ?? snapshotArg.devices.length, updatedAt: updatedAtArg },
    ];
    this.addFeatureState(features, state, 'cpu_usage', 'CPU usage', snapshotArg.sensors.cpu_usage, updatedAtArg, '%');
    this.addFeatureState(features, state, 'memory_usage', 'Memory usage', snapshotArg.sensors.memory_usage, updatedAtArg, '%');
    this.addFeatureState(features, state, 'pf_state_used_percent', 'Firewall state table used', snapshotArg.sensors.pf_state_used_percent, updatedAtArg, '%');

    return {
      id: this.routerDeviceId(snapshotArg),
      integrationDomain: opnsenseDomain,
      name: this.routerName(snapshotArg),
      protocol: 'http',
      manufacturer: snapshotArg.router.manufacturer || manufacturer,
      model: snapshotArg.router.model || 'OPNsense Firewall',
      online: snapshotArg.connected,
      features,
      state,
      metadata: this.cleanAttributes({
        host: snapshotArg.router.host,
        port: snapshotArg.router.port,
        ssl: snapshotArg.router.ssl,
        verifySsl: snapshotArg.router.verifySsl,
        macAddress: snapshotArg.router.macAddress,
        firmware: snapshotArg.router.firmware || snapshotArg.system.firmwareVersion || snapshotArg.system.productVersion,
        latestFirmware: snapshotArg.router.latestFirmware || snapshotArg.system.productLatest,
        configurationUrl: snapshotArg.router.configurationUrl,
        source: snapshotArg.source,
        liveHttpImplemented: false,
      }),
    };
  }

  private static clientDevice(clientArg: IOpnsenseClientDevice, snapshotArg: IOpnsenseSnapshot, updatedAtArg: string): plugins.shxInterfaces.data.IDeviceDefinition {
    const name = this.clientName(clientArg);
    return {
      id: this.clientDeviceId(clientArg),
      integrationDomain: opnsenseDomain,
      name,
      protocol: 'unknown',
      manufacturer: clientArg.manufacturer || 'Unknown',
      model: clientArg.model || 'Network client',
      online: clientArg.connected !== false && snapshotArg.connected,
      features: [
        { id: 'presence', capability: 'sensor', name: 'Presence', readable: true, writable: false },
        { id: 'ip_address', capability: 'sensor', name: 'IP address', readable: true, writable: false },
      ],
      state: [
        { featureId: 'presence', value: clientArg.connected !== false, updatedAt: updatedAtArg },
        { featureId: 'ip_address', value: clientArg.ipAddress || clientArg.ip || clientArg.address || null, updatedAt: updatedAtArg },
      ],
      metadata: this.cleanAttributes({
        mac: this.clientMac(clientArg),
        ipAddress: clientArg.ipAddress || clientArg.ip || clientArg.address,
        hostname: clientArg.hostname || clientArg.name,
        interface: clientArg.interface,
        interfaceDescription: clientArg.interfaceDescription || clientArg.intf_description,
        leaseType: clientArg.leaseType || clientArg.type,
        expires: this.dateString(clientArg.expires),
        lastActivity: this.dateString(clientArg.lastActivity),
      }),
    };
  }

  private static pushInterfaceEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, ifaceArg: IOpnsenseInterfaceInfo, usedIdsArg: Map<string, number>): void {
    const deviceId = this.routerDeviceId(snapshotArg);
    const ifaceKey = this.slug(ifaceArg.id || ifaceArg.name);
    const ifaceName = ifaceArg.label || ifaceArg.description || ifaceArg.name;
    const values: Array<[string, string, unknown, string | undefined, Record<string, unknown>]> = [
      ['rx_bytes', 'Download', this.bytesToGigabytes(this.numberValue(ifaceArg.rxBytes) ?? this.numberValue(ifaceArg.inbytes)), 'GB', { deviceClass: 'data_size', stateClass: 'total_increasing' }],
      ['tx_bytes', 'Upload', this.bytesToGigabytes(this.numberValue(ifaceArg.txBytes) ?? this.numberValue(ifaceArg.outbytes)), 'GB', { deviceClass: 'data_size', stateClass: 'total_increasing' }],
      ['rx_packets', 'Packets received', this.numberValue(ifaceArg.rxPackets) ?? this.numberValue(ifaceArg.inpkts), 'packets', { stateClass: 'total_increasing' }],
      ['tx_packets', 'Packets transmitted', this.numberValue(ifaceArg.txPackets) ?? this.numberValue(ifaceArg.outpkts), 'packets', { stateClass: 'total_increasing' }],
      ['input_errors', 'Input errors', this.numberValue(ifaceArg.inputErrors) ?? this.numberValue(ifaceArg.inerrs), 'errors', { stateClass: 'total_increasing', entityCategory: 'diagnostic' }],
      ['output_errors', 'Output errors', this.numberValue(ifaceArg.outputErrors) ?? this.numberValue(ifaceArg.outerrs), 'errors', { stateClass: 'total_increasing', entityCategory: 'diagnostic' }],
      ['collisions', 'Collisions', this.numberValue(ifaceArg.collisions), 'collisions', { stateClass: 'total_increasing', entityCategory: 'diagnostic' }],
    ];
    entitiesArg.push(this.entity('binary_sensor', `${this.routerName(snapshotArg)} ${ifaceName} Link`, deviceId, `${this.uniqueBase(snapshotArg)}_interface_${ifaceKey}_link`, this.interfaceUp(ifaceArg) ? 'on' : 'off', usedIdsArg, {
      deviceClass: 'connectivity',
      interface: ifaceArg.name,
      status: ifaceArg.status,
      enabled: this.booleanLike(ifaceArg.enabled),
      macAddress: ifaceArg.macAddress || ifaceArg.mac,
      ipv4: ifaceArg.ipv4,
      ipv6: ifaceArg.ipv6,
      media: ifaceArg.media,
      device: ifaceArg.device,
      gateways: ifaceArg.gateways,
    }, snapshotArg.connected));
    for (const [key, name, value, unit, attrs] of values) {
      if (value === undefined) {
        continue;
      }
      entitiesArg.push(this.entity('sensor', `${this.routerName(snapshotArg)} ${ifaceName} ${name}`, deviceId, `${this.uniqueBase(snapshotArg)}_interface_${ifaceKey}_${key}`, value, usedIdsArg, {
        ...attrs,
        unit,
        interface: ifaceArg.name,
      }, snapshotArg.connected && this.interfaceUp(ifaceArg)));
    }
  }

  private static pushGatewayEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, gatewayArg: IOpnsenseGatewayInfo, usedIdsArg: Map<string, number>): void {
    const gatewayKey = this.slug(gatewayArg.id || gatewayArg.name);
    const name = `${this.routerName(snapshotArg)} Gateway ${gatewayArg.name}`;
    const up = this.gatewayUp(gatewayArg);
    entitiesArg.push(this.entity('binary_sensor', name, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_gateway_${gatewayKey}`, up ? 'on' : 'off', usedIdsArg, {
      deviceClass: 'connectivity',
      nativeType: 'gateway',
      gateway: gatewayArg.name,
      status: gatewayArg.status,
      address: gatewayArg.address,
      interface: gatewayArg.interface,
      monitor: gatewayArg.monitor,
    }, snapshotArg.connected));
    const latency = this.numberValue(gatewayArg.latency) ?? this.numberValue(gatewayArg.rtt) ?? this.numberValue(gatewayArg.delay);
    if (latency !== undefined) {
      entitiesArg.push(this.entity('sensor', `${name} Latency`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_gateway_${gatewayKey}_latency`, latency, usedIdsArg, {
        unit: 'ms',
        stateClass: 'measurement',
        gateway: gatewayArg.name,
      }, snapshotArg.connected && up));
    }
    const loss = this.numberValue(gatewayArg.loss);
    if (loss !== undefined) {
      entitiesArg.push(this.entity('sensor', `${name} Loss`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_gateway_${gatewayKey}_loss`, loss, usedIdsArg, {
        unit: '%',
        stateClass: 'measurement',
        gateway: gatewayArg.name,
      }, snapshotArg.connected && up));
    }
  }

  private static pushClientEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, clientArg: IOpnsenseClientDevice, usedIdsArg: Map<string, number>): void {
    const mac = this.clientMac(clientArg);
    entitiesArg.push(this.entity('binary_sensor', `${this.clientName(clientArg)} Connected`, this.clientDeviceId(clientArg), `${this.slug(mac || this.clientName(clientArg))}_connected`, clientArg.connected !== false ? 'on' : 'off', usedIdsArg, {
      deviceClass: 'connectivity',
      nativePlatform: 'device_tracker',
      mac,
      ipAddress: clientArg.ipAddress || clientArg.ip || clientArg.address,
      hostname: clientArg.hostname || clientArg.name,
      interface: clientArg.interface,
      interfaceDescription: clientArg.interfaceDescription || clientArg.intf_description,
      manufacturer: clientArg.manufacturer,
    }, snapshotArg.connected));
  }

  private static pushFirewallEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, usedIdsArg: Map<string, number>): void {
    for (const rule of this.firewallRules(snapshotArg.firewall.rules)) {
      const uuid = this.ruleId(rule);
      if (!uuid) {
        continue;
      }
      const label = rule.description || rule.descr || uuid;
      entitiesArg.push(this.entity('switch', `${this.routerName(snapshotArg)} Firewall ${label}`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_firewall_rule_${this.slug(uuid)}`, this.ruleEnabled(rule) ? 'on' : 'off', usedIdsArg, {
        nativeType: 'firewall_rule',
        nativeAction: 'toggle',
        uuid,
        interface: rule.interface,
        direction: rule.direction,
        protocol: rule.protocol,
        ruleAction: rule.action,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected));
    }
    for (const [natType, rules] of Object.entries(snapshotArg.firewall.nat || {})) {
      for (const rule of this.firewallRules(rules)) {
        const uuid = this.ruleId(rule);
        if (!uuid) {
          continue;
        }
        const label = rule.description || rule.descr || uuid;
        entitiesArg.push(this.entity('switch', `${this.routerName(snapshotArg)} NAT ${label}`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_nat_${this.slug(natType)}_${this.slug(uuid)}`, this.ruleEnabled(rule), usedIdsArg, {
          nativeType: 'nat_rule',
          nativeAction: 'toggle',
          natRuleType: natType,
          uuid,
          interface: rule.interface,
          protocol: rule.protocol,
          entityCategory: 'config',
          writable: true,
        }, snapshotArg.connected));
      }
    }
    for (const alias of this.firewallAliases(snapshotArg.firewall.aliases)) {
      const uuid = alias.uuid || alias.id || alias.name;
      entitiesArg.push(this.entity('switch', `${this.routerName(snapshotArg)} Alias ${alias.name}`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_alias_${this.slug(uuid)}`, this.ruleEnabled(alias), usedIdsArg, {
        nativeType: 'firewall_alias',
        nativeAction: 'toggle',
        uuid,
        alias: alias.name,
        aliasType: alias.type,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected));
    }
  }

  private static pushServiceEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, usedIdsArg: Map<string, number>): void {
    for (const service of snapshotArg.services) {
      const serviceName = this.serviceName(service);
      const display = this.serviceDisplayName(service);
      entitiesArg.push(this.entity('switch', `${display} Service`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_service_${this.slug(serviceName)}`, this.serviceRunning(service) ? 'on' : 'off', usedIdsArg, {
        nativeType: 'service',
        nativeAction: 'start_stop',
        serviceName,
        description: service.description,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected));
      entitiesArg.push(this.entity('button', `${display} Restart`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_service_${this.slug(serviceName)}_restart`, 'available', usedIdsArg, {
        nativeType: 'service',
        nativeAction: 'restart',
        serviceName,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected));
    }
  }

  private static pushVpnEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, usedIdsArg: Map<string, number>): void {
    for (const vpnType of ['openvpn', 'wireguard'] as const) {
      for (const role of ['servers', 'clients'] as const) {
        for (const instance of this.vpnInstances(snapshotArg.vpn, vpnType, role)) {
          const uuid = this.vpnId(instance);
          if (!uuid) {
            continue;
          }
          const name = `${this.routerName(snapshotArg)} ${this.title(vpnType)} ${this.vpnName(instance)}`;
          entitiesArg.push(this.entity('switch', name, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_${vpnType}_${role}_${this.slug(uuid)}`, this.booleanLike(instance.enabled) ? 'on' : 'off', usedIdsArg, {
            nativeType: 'vpn_instance',
            nativeAction: 'toggle',
            vpnType,
            vpnRole: role.slice(0, -1),
            uuid,
            status: instance.status,
            interface: instance.interface,
            endpoint: instance.endpoint,
            entityCategory: 'config',
            writable: true,
          }, snapshotArg.connected));
          const connectedCount = this.numberValue(instance.connectedClients ?? instance.connected_clients ?? instance.connectedServers ?? instance.connected_servers);
          if (connectedCount !== undefined) {
            entitiesArg.push(this.entity('sensor', `${name} Connected peers`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_${vpnType}_${role}_${this.slug(uuid)}_connected_peers`, connectedCount, usedIdsArg, {
              unit: 'peers',
              stateClass: 'measurement',
              vpnType,
              vpnRole: role.slice(0, -1),
            }, snapshotArg.connected));
          }
        }
      }
    }
  }

  private static pushGenericSwitchEntities(entitiesArg: IIntegrationEntity[], snapshotArg: IOpnsenseSnapshot, usedIdsArg: Map<string, number>): void {
    for (const switchInfo of snapshotArg.switches) {
      const id = switchInfo.id || switchInfo.uuid || switchInfo.name;
      entitiesArg.push(this.entity('switch', `${this.routerName(snapshotArg)} ${switchInfo.name}`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_switch_${this.slug(id)}`, this.booleanLike(switchInfo.enabled) ? 'on' : 'off', usedIdsArg, {
        nativeType: switchInfo.nativeType || 'generic_switch',
        nativeAction: switchInfo.action || 'toggle',
        uuid: switchInfo.uuid,
        service: switchInfo.service,
        path: switchInfo.path,
        method: switchInfo.method,
        payload: switchInfo.payload,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected && switchInfo.available !== false));
    }
  }

  private static actionButton(snapshotArg: IOpnsenseSnapshot, actionArg: IOpnsenseActionDescriptor, usedIdsArg: Map<string, number>): IIntegrationEntity | undefined {
    if (actionArg.target === 'router' && (actionArg.action === 'reboot' || actionArg.action === 'halt')) {
      return this.entity('button', `${this.routerName(snapshotArg)} ${this.title(actionArg.action)}`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_${this.slug(actionArg.action)}`, 'available', usedIdsArg, {
        nativeType: 'router_action',
        nativeAction: actionArg.action,
        actionTarget: 'router',
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected, actionArg.entityId);
    }
    if (actionArg.target === 'interface' && actionArg.action === 'reload' && actionArg.interface) {
      return this.entity('button', `${this.routerName(snapshotArg)} ${actionArg.interface} Reload`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_interface_${this.slug(actionArg.interface)}_reload`, 'available', usedIdsArg, {
        nativeType: 'interface',
        nativeAction: 'reload',
        interface: actionArg.interface,
        entityCategory: 'config',
        writable: true,
      }, snapshotArg.connected, actionArg.entityId);
    }
    if (actionArg.target === 'speedtest' && actionArg.action === 'run') {
      return this.entity('button', `${this.routerName(snapshotArg)} Speedtest`, this.routerDeviceId(snapshotArg), `${this.uniqueBase(snapshotArg)}_speedtest`, 'available', usedIdsArg, {
        nativeType: 'speedtest',
        nativeAction: 'run',
        entityCategory: 'diagnostic',
        writable: true,
      }, snapshotArg.connected, actionArg.entityId);
    }
    return undefined;
  }

  private static opnsenseServiceCommand(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest): IOpnsenseCommand | { error: string } | undefined {
    if (requestArg.service === 'reboot' || requestArg.service === 'halt') {
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'router' && actionArg.action === requestArg.service);
      return action ? this.command(snapshotArg, requestArg, action, undefined, { path: `/api/core/system/${requestArg.service}`, type: 'router.action' }) : undefined;
    }
    if (requestArg.service === 'firmware_update' || requestArg.service === 'upgrade_firmware') {
      return this.firmwareCommand(snapshotArg, requestArg);
    }
    if (requestArg.service === 'start_service' || requestArg.service === 'stop_service' || requestArg.service === 'restart_service') {
      const serviceName = this.stringValue(requestArg.data?.service) || this.stringValue(requestArg.data?.name);
      if (!serviceName) {
        return { error: 'OPNsense service control requires data.service.' };
      }
      const actionName = requestArg.service.replace('_service', '');
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'service' && actionArg.action === actionName && actionArg.service === serviceName);
      return action ? this.command(snapshotArg, requestArg, action, undefined, { type: 'service.action', path: `/api/core/service/${actionName}/${encodeURIComponent(serviceName)}` }) : undefined;
    }
    if (requestArg.service === 'reload_interface') {
      const ifName = this.stringValue(requestArg.data?.interface) || this.stringValue(requestArg.data?.interfaceName);
      if (!ifName) {
        return { error: 'OPNsense reload_interface requires data.interface.' };
      }
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'interface' && actionArg.action === 'reload' && actionArg.interface === ifName);
      return action ? this.command(snapshotArg, requestArg, action, undefined, { type: 'interface.reload', path: `/api/interfaces/overview/reload_interface/${encodeURIComponent(ifName)}` }) : undefined;
    }
    if (requestArg.service === 'close_notice') {
      const id = this.stringValue(requestArg.data?.id) || 'all';
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'notice' && (actionArg.id === id || id === 'all'));
      return action ? this.command(snapshotArg, requestArg, action, undefined, { type: 'notice.close', path: '/api/core/system/dismiss_status', payload: { subject: id } }) : undefined;
    }
    if (requestArg.service === 'send_wol') {
      const mac = this.normalizeMac(this.stringValue(requestArg.data?.mac) || this.stringValue(requestArg.data?.macAddress));
      const ifName = this.stringValue(requestArg.data?.interface);
      if (!mac || !ifName) {
        return { error: 'OPNsense send_wol requires data.interface and data.mac.' };
      }
      return this.command(snapshotArg, requestArg, { target: 'wol', action: 'send', interface: ifName, mac }, undefined, { type: 'wol.send', path: '/api/wol/wol/set', payload: { wake: { interface: ifName, mac } } });
    }
    if (requestArg.service === 'run_speedtest') {
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'speedtest' && actionArg.action === 'run');
      return action ? this.command(snapshotArg, requestArg, action, undefined, { type: 'speedtest.run', path: '/api/speedtest/service/run', method: 'GET' }) : undefined;
    }
    return undefined;
  }

  private static switchCommand(snapshotArg: IOpnsenseSnapshot, entityArg: IIntegrationEntity, requestArg: IServiceCallRequest, enabledArg: boolean): IOpnsenseCommand | { error: string } | undefined {
    const nativeType = this.stringValue(entityArg.attributes?.nativeType);
    const uuid = this.stringValue(entityArg.attributes?.uuid);
    if (nativeType === 'service') {
      const serviceName = this.stringValue(entityArg.attributes?.serviceName);
      if (!serviceName) {
        return { error: 'OPNsense service switch is missing serviceName metadata.' };
      }
      const actionName = enabledArg ? 'start' : 'stop';
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'service' && actionArg.action === actionName && actionArg.service === serviceName);
      return action ? this.command(snapshotArg, requestArg, action, entityArg, { type: 'service.action', path: `/api/core/service/${actionName}/${encodeURIComponent(serviceName)}` }) : undefined;
    }
    if (nativeType === 'firewall_rule' && uuid) {
      return this.command(snapshotArg, requestArg, { target: 'firewall_rule', action: 'toggle', uuid }, entityArg, {
        type: 'firewall.toggle',
        path: `/api/firewall/filter/toggle_rule/${encodeURIComponent(uuid)}/${enabledArg ? '1' : '0'}`,
        payload: { enabled: enabledArg, applyPath: '/api/firewall/filter/apply' },
      });
    }
    if (nativeType === 'nat_rule' && uuid) {
      const natRuleType = this.stringValue(entityArg.attributes?.natRuleType) || 'd_nat';
      const toggleFlag = natRuleType === 'd_nat' ? enabledArg ? '0' : '1' : enabledArg ? '1' : '0';
      return this.command(snapshotArg, requestArg, { target: 'nat_rule', action: 'toggle', uuid, natRuleType }, entityArg, {
        type: 'nat.toggle',
        path: `/api/firewall/${encodeURIComponent(natRuleType)}/toggle_rule/${encodeURIComponent(uuid)}/${toggleFlag}`,
        payload: { enabled: enabledArg, applyPath: `/api/firewall/${natRuleType}/apply` },
      });
    }
    if (nativeType === 'firewall_alias' && uuid) {
      return this.command(snapshotArg, requestArg, { target: 'firewall_alias', action: 'toggle', uuid }, entityArg, {
        type: 'alias.toggle',
        path: `/api/firewall/alias/toggle_item/${encodeURIComponent(uuid)}/${enabledArg ? '1' : '0'}`,
        payload: { enabled: enabledArg, savePath: '/api/firewall/alias/set', reconfigurePath: '/api/firewall/alias/reconfigure' },
      });
    }
    if (nativeType === 'vpn_instance' && uuid) {
      const vpnType = this.stringValue(entityArg.attributes?.vpnType) || 'openvpn';
      const vpnRole = this.stringValue(entityArg.attributes?.vpnRole) || 'server';
      return this.vpnToggleCommand(snapshotArg, requestArg, entityArg, uuid, vpnType, vpnRole, enabledArg);
    }
    if (nativeType === 'unbound_blocklist') {
      return this.command(snapshotArg, requestArg, { target: 'unbound', action: enabledArg ? 'enable' : 'disable', uuid }, entityArg, {
        type: 'unbound.toggle',
        path: uuid ? `/api/unbound/settings/toggle_dnsbl/${encodeURIComponent(uuid)}/${enabledArg ? '1' : '0'}` : undefined,
        payload: { enabled: enabledArg },
      });
    }
    if (nativeType === 'generic_switch') {
      const path = this.stringValue(entityArg.attributes?.path);
      if (!path) {
        return undefined;
      }
      return this.command(snapshotArg, requestArg, { target: 'switch', action: enabledArg ? 'enable' : 'disable', path, method: this.methodValue(entityArg.attributes?.method), payload: this.recordValue(entityArg.attributes?.payload) }, entityArg, {
        type: 'switch.action',
        path,
        method: this.methodValue(entityArg.attributes?.method),
        payload: { ...this.recordValue(entityArg.attributes?.payload), enabled: enabledArg },
      });
    }
    return undefined;
  }

  private static buttonCommand(snapshotArg: IOpnsenseSnapshot, entityArg: IIntegrationEntity, requestArg: IServiceCallRequest): IOpnsenseCommand | { error: string } | undefined {
    const nativeType = this.stringValue(entityArg.attributes?.nativeType);
    const nativeAction = this.stringValue(entityArg.attributes?.nativeAction);
    if (nativeType === 'router_action' && (nativeAction === 'reboot' || nativeAction === 'halt')) {
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'router' && actionArg.action === nativeAction);
      return action ? this.command(snapshotArg, requestArg, action, entityArg, { type: 'router.action', path: `/api/core/system/${nativeAction}` }) : undefined;
    }
    if (nativeType === 'service' && nativeAction === 'restart') {
      const serviceName = this.stringValue(entityArg.attributes?.serviceName);
      if (!serviceName) {
        return { error: 'OPNsense service restart button is missing serviceName metadata.' };
      }
      const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'service' && actionArg.action === 'restart' && actionArg.service === serviceName);
      return action ? this.command(snapshotArg, requestArg, action, entityArg, { type: 'service.action', path: `/api/core/service/restart/${encodeURIComponent(serviceName)}` }) : undefined;
    }
    if (nativeType === 'interface' && nativeAction === 'reload') {
      const ifName = this.stringValue(entityArg.attributes?.interface);
      if (!ifName) {
        return { error: 'OPNsense interface reload button is missing interface metadata.' };
      }
      return this.command(snapshotArg, requestArg, { target: 'interface', action: 'reload', interface: ifName }, entityArg, { type: 'interface.reload', path: `/api/interfaces/overview/reload_interface/${encodeURIComponent(ifName)}` });
    }
    if (nativeType === 'speedtest' && nativeAction === 'run') {
      return this.command(snapshotArg, requestArg, { target: 'speedtest', action: 'run' }, entityArg, { type: 'speedtest.run', path: '/api/speedtest/service/run', method: 'GET' });
    }
    return undefined;
  }

  private static firmwareCommand(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest, entityArg?: IIntegrationEntity): IOpnsenseCommand | undefined {
    const actions = this.snapshotActions(snapshotArg);
    const action = actions.find((actionArg) => actionArg.target === 'router' && (actionArg.action === 'firmware_update' || actionArg.action === 'firmware_upgrade'));
    if (!action) {
      return undefined;
    }
    const upgradeType = this.stringValue(requestArg.data?.type) === 'upgrade' || action.action === 'firmware_upgrade' ? 'upgrade' : 'update';
    return this.command(snapshotArg, requestArg, action, entityArg, { type: 'firmware.action', path: `/api/core/firmware/${upgradeType}` });
  }

  private static vpnToggleCommand(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest, entityArg: IIntegrationEntity, uuidArg: string, vpnTypeArg: string, vpnRoleArg: string, enabledArg: boolean): IOpnsenseCommand | undefined {
    const action = this.snapshotActions(snapshotArg).find((actionArg) => actionArg.target === 'vpn' && actionArg.uuid === uuidArg && actionArg.vpnType === vpnTypeArg);
    if (!action) {
      return undefined;
    }
    let path: string | undefined;
    let reconfigurePath: string | undefined;
    if (vpnTypeArg === 'openvpn') {
      path = `/api/openvpn/instances/toggle/${encodeURIComponent(uuidArg)}`;
      reconfigurePath = '/api/openvpn/service/reconfigure';
    } else if (vpnTypeArg === 'wireguard') {
      const rolePath = vpnRoleArg === 'client' ? 'client/toggle_client' : 'server/toggle_server';
      path = `/api/wireguard/${rolePath}/${encodeURIComponent(uuidArg)}`;
      reconfigurePath = '/api/wireguard/service/reconfigure';
    }
    return this.command(snapshotArg, requestArg, action, entityArg, { type: 'vpn.toggle', path, payload: { enabled: enabledArg, reconfigurePath } });
  }

  private static command(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest, actionArg: IOpnsenseActionDescriptor, entityArg?: IIntegrationEntity, optionsArg: Partial<IOpnsenseCommand> = {}): IOpnsenseCommand {
    return {
      type: optionsArg.type || this.commandType(actionArg),
      service: requestArg.service,
      action: actionArg.action,
      target: requestArg.target,
      method: optionsArg.method || actionArg.method || 'POST',
      path: optionsArg.path || actionArg.path,
      payload: this.cleanAttributes({ ...(actionArg.payload || {}), ...(requestArg.data || {}), ...(optionsArg.payload || {}), actionMetadata: actionArg.metadata }),
      routerId: this.routerDeviceId(snapshotArg),
      entityId: entityArg?.id || actionArg.entityId || requestArg.target.entityId,
      deviceId: entityArg?.deviceId || actionArg.deviceId || requestArg.target.deviceId,
      uuid: actionArg.uuid || this.stringValue(actionArg.id),
      serviceName: actionArg.service,
      interface: actionArg.interface,
      mac: actionArg.mac ? this.normalizeMac(actionArg.mac) : undefined,
      vpnType: actionArg.vpnType,
      vpnRole: actionArg.vpnRole,
      natRuleType: actionArg.natRuleType,
    };
  }

  private static commandType(actionArg: IOpnsenseActionDescriptor): IOpnsenseCommand['type'] {
    if (actionArg.target === 'service') return 'service.action';
    if (actionArg.target === 'firewall_rule') return 'firewall.toggle';
    if (actionArg.target === 'nat_rule') return 'nat.toggle';
    if (actionArg.target === 'firewall_alias') return 'alias.toggle';
    if (actionArg.target === 'vpn') return 'vpn.toggle';
    if (actionArg.target === 'interface') return 'interface.reload';
    if (actionArg.target === 'notice') return 'notice.close';
    if (actionArg.target === 'wol') return 'wol.send';
    if (actionArg.target === 'firmware') return 'firmware.action';
    if (actionArg.target === 'unbound') return 'unbound.toggle';
    if (actionArg.target === 'speedtest') return 'speedtest.run';
    if (actionArg.target === 'switch') return 'switch.action';
    return 'router.action';
  }

  private static findTargetEntity(snapshotArg: IOpnsenseSnapshot, requestArg: IServiceCallRequest): IIntegrationEntity | undefined {
    if (!requestArg.target.entityId) {
      return undefined;
    }
    return this.toEntities(snapshotArg).find((entityArg) => entityArg.id === requestArg.target.entityId || entityArg.uniqueId === requestArg.target.entityId);
  }

  private static actionsFromRouter(routerArg: IOpnsenseRouterInfo): IOpnsenseActionDescriptor[] {
    return (routerArg.actions || []).map((actionArg) => ({ target: 'router', action: actionArg }));
  }

  private static actionsFromInterfaces(interfacesArg: IOpnsenseInterfaceInfo[]): IOpnsenseActionDescriptor[] {
    return interfacesArg.flatMap((interfaceArg) => (interfaceArg.actions || []).map((actionArg) => ({ target: 'interface' as const, action: actionArg, interface: interfaceArg.name })));
  }

  private static actionsFromServices(servicesArg: IOpnsenseServiceInfo[]): IOpnsenseActionDescriptor[] {
    const actions: IOpnsenseActionDescriptor[] = [];
    for (const service of servicesArg) {
      const serviceName = this.serviceName(service);
      if (!serviceName) {
        continue;
      }
      const serviceActions = service.actions?.length ? service.actions : ['start', 'stop', 'restart'] as const;
      for (const action of serviceActions) {
        actions.push({ target: 'service', action, service: serviceName });
      }
    }
    return actions;
  }

  private static actionsFromFirewall(firewallArg: IOpnsenseFirewallSnapshot): IOpnsenseActionDescriptor[] {
    const actions: IOpnsenseActionDescriptor[] = [];
    for (const rule of this.firewallRules(firewallArg.rules)) {
      const uuid = this.ruleId(rule);
      if (uuid) actions.push({ target: 'firewall_rule', action: 'toggle', uuid });
    }
    for (const [natRuleType, rules] of Object.entries(firewallArg.nat || {})) {
      for (const rule of this.firewallRules(rules)) {
        const uuid = this.ruleId(rule);
        if (uuid) actions.push({ target: 'nat_rule', action: 'toggle', uuid, natRuleType });
      }
    }
    for (const alias of this.firewallAliases(firewallArg.aliases)) {
      const uuid = alias.uuid || alias.id || alias.name;
      actions.push({ target: 'firewall_alias', action: 'toggle', uuid });
    }
    return actions;
  }

  private static actionsFromVpn(vpnArg: IOpnsenseVpnSnapshot): IOpnsenseActionDescriptor[] {
    const actions: IOpnsenseActionDescriptor[] = [];
    for (const vpnType of ['openvpn', 'wireguard'] as const) {
      for (const role of ['servers', 'clients'] as const) {
        for (const instance of this.vpnInstances(vpnArg, vpnType, role)) {
          const uuid = this.vpnId(instance);
          if (uuid) actions.push({ target: 'vpn', action: 'toggle', uuid, vpnType, vpnRole: role.slice(0, -1) });
        }
      }
    }
    return actions;
  }

  private static actionsFromSwitches(switchesArg: IOpnsenseSwitchInfo[]): IOpnsenseActionDescriptor[] {
    return switchesArg
      .filter((switchArg) => Boolean(switchArg.path || switchArg.action || switchArg.uuid))
      .map((switchArg) => ({ target: switchArg.nativeType === 'unbound_blocklist' ? 'unbound' : 'switch', action: switchArg.action || 'toggle', uuid: switchArg.uuid, service: switchArg.service, path: switchArg.path, method: switchArg.method, payload: switchArg.payload }));
  }

  private static actionsFromSystem(systemArg: IOpnsenseSystemInfo): IOpnsenseActionDescriptor[] {
    const actions: IOpnsenseActionDescriptor[] = [];
    for (const notice of systemArg.pendingNotices || systemArg.pending_notices || []) {
      if (notice.id) actions.push({ target: 'notice', action: 'close', id: notice.id });
    }
    if (systemArg.speedtest || systemArg.speedtest_available === true) {
      actions.push({ target: 'speedtest', action: 'run' });
    }
    return actions;
  }

  private static snapshotActions(snapshotArg: IOpnsenseSnapshot): IOpnsenseActionDescriptor[] {
    return this.uniqueActions([
      ...(snapshotArg.actions || []),
      ...this.actionsFromRouter(snapshotArg.router),
      ...this.actionsFromInterfaces(snapshotArg.interfaces),
      ...this.actionsFromServices(snapshotArg.services),
      ...this.actionsFromFirewall(snapshotArg.firewall),
      ...this.actionsFromVpn(snapshotArg.vpn),
      ...this.actionsFromSwitches(snapshotArg.switches),
      ...this.actionsFromSystem(snapshotArg.system),
    ]);
  }

  private static uniqueClients(devicesArg: IOpnsenseClientDevice[]): IOpnsenseClientDevice[] {
    const seen = new Map<string, IOpnsenseClientDevice>();
    for (const device of devicesArg) {
      const mac = this.clientMac(device);
      const key = mac || device.id || device.ipAddress || device.ip || device.address || device.name || device.hostname;
      if (!key) {
        continue;
      }
      seen.set(key, { ...seen.get(key), ...device, mac: mac || device.mac });
    }
    return [...seen.values()];
  }

  private static uniqueInterfaces(interfacesArg: IOpnsenseInterfaceInfo[]): IOpnsenseInterfaceInfo[] {
    const seen = new Map<string, IOpnsenseInterfaceInfo>();
    for (const iface of interfacesArg) {
      const key = iface.id || iface.name;
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...iface });
    }
    return [...seen.values()];
  }

  private static uniqueGateways(gatewaysArg: IOpnsenseGatewayInfo[]): IOpnsenseGatewayInfo[] {
    const seen = new Map<string, IOpnsenseGatewayInfo>();
    for (const gateway of gatewaysArg) {
      const key = gateway.id || gateway.name;
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...gateway });
    }
    return [...seen.values()];
  }

  private static uniqueServices(servicesArg: IOpnsenseServiceInfo[]): IOpnsenseServiceInfo[] {
    const seen = new Map<string, IOpnsenseServiceInfo>();
    for (const service of servicesArg) {
      const key = this.serviceName(service);
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...service });
    }
    return [...seen.values()];
  }

  private static uniqueSwitches(switchesArg: IOpnsenseSwitchInfo[]): IOpnsenseSwitchInfo[] {
    const seen = new Map<string, IOpnsenseSwitchInfo>();
    for (const switchInfo of switchesArg) {
      const key = switchInfo.id || switchInfo.uuid || switchInfo.name;
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...switchInfo });
    }
    return [...seen.values()];
  }

  private static uniqueActions(actionsArg: IOpnsenseActionDescriptor[]): IOpnsenseActionDescriptor[] {
    const seen = new Map<string, IOpnsenseActionDescriptor>();
    for (const action of actionsArg) {
      const key = [action.target, action.action, action.uuid || action.id || action.service || action.interface || action.vpnType || action.natRuleType || action.entityId || 'router'].join(':');
      seen.set(key, { ...seen.get(key), ...action });
    }
    return [...seen.values()];
  }

  private static firewallSnapshot(...sourcesArg: Array<IOpnsenseFirewallSnapshot | undefined>): IOpnsenseFirewallSnapshot {
    const firewall: IOpnsenseFirewallSnapshot = { rules: [], nat: {}, aliases: [] };
    for (const source of sourcesArg) {
      if (!source) continue;
      firewall.rules = this.firewallRules(firewall.rules).concat(this.firewallRules(source.rules));
      firewall.aliases = this.firewallAliases(firewall.aliases).concat(this.firewallAliases(source.aliases));
      const nat = { ...(firewall.nat || {}) };
      firewall.nat = nat;
      for (const [natType, rules] of Object.entries(source.nat || {})) {
        nat[natType] = this.firewallRules(nat[natType]).concat(this.firewallRules(rules));
      }
      firewall.state = { ...firewall.state, ...source.state };
      firewall.metadata = { ...firewall.metadata, ...source.metadata };
    }
    firewall.rules = this.uniqueRules(this.firewallRules(firewall.rules));
    firewall.aliases = this.uniqueAliases(this.firewallAliases(firewall.aliases));
    const nat = firewall.nat || {};
    firewall.nat = nat;
    for (const [natType, rules] of Object.entries(nat)) {
      nat[natType] = this.uniqueRules(this.firewallRules(rules));
    }
    return firewall;
  }

  private static vpnSnapshot(...sourcesArg: Array<IOpnsenseVpnSnapshot | undefined>): IOpnsenseVpnSnapshot {
    const vpn: IOpnsenseVpnSnapshot = { openvpn: { servers: [], clients: [] }, wireguard: { servers: [], clients: [] } };
    for (const source of sourcesArg) {
      if (!source) continue;
      for (const vpnType of ['openvpn', 'wireguard'] as const) {
        const current = vpn[vpnType] || {};
        const incoming = source[vpnType] || {};
        current.servers = this.uniqueVpnInstances([...this.vpnRecords(current.servers), ...this.vpnRecords(incoming.servers)]);
        current.clients = this.uniqueVpnInstances([...this.vpnRecords(current.clients), ...this.vpnRecords(incoming.clients)]);
        vpn[vpnType] = current;
      }
      vpn.metadata = { ...vpn.metadata, ...source.metadata };
    }
    return vpn;
  }

  private static objectMerge<T extends Record<string, unknown>>(...sourcesArg: Array<T | undefined>): T {
    const output: Record<string, unknown> = {};
    for (const source of sourcesArg) {
      if (!source) continue;
      for (const [key, value] of Object.entries(source)) {
        if (value && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date) && output[key] && typeof output[key] === 'object' && !Array.isArray(output[key])) {
          output[key] = { ...(output[key] as Record<string, unknown>), ...(value as Record<string, unknown>) };
        } else {
          output[key] = value;
        }
      }
    }
    return output as T;
  }

  private static firewallRules(valueArg: IOpnsenseFirewallSnapshot['rules'] | TOpnsenseNatRules): IOpnsenseFirewallRule[] {
    if (!valueArg) return [];
    return Array.isArray(valueArg) ? valueArg : Object.values(valueArg).filter((ruleArg): ruleArg is IOpnsenseFirewallRule => Boolean(ruleArg));
  }

  private static firewallAliases(valueArg: IOpnsenseFirewallSnapshot['aliases']): IOpnsenseFirewallAlias[] {
    if (!valueArg) return [];
    return Array.isArray(valueArg) ? valueArg : Object.values(valueArg).filter((aliasArg): aliasArg is IOpnsenseFirewallAlias => Boolean(aliasArg));
  }

  private static uniqueRules(rulesArg: IOpnsenseFirewallRule[]): IOpnsenseFirewallRule[] {
    const seen = new Map<string, IOpnsenseFirewallRule>();
    for (const rule of rulesArg) {
      const key = this.ruleId(rule);
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...rule });
    }
    return [...seen.values()];
  }

  private static uniqueAliases(aliasesArg: IOpnsenseFirewallAlias[]): IOpnsenseFirewallAlias[] {
    const seen = new Map<string, IOpnsenseFirewallAlias>();
    for (const alias of aliasesArg) {
      const key = alias.uuid || alias.id || alias.name;
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...alias });
    }
    return [...seen.values()];
  }

  private static vpnInstances(vpnArg: IOpnsenseVpnSnapshot, typeArg: 'openvpn' | 'wireguard', roleArg: 'servers' | 'clients'): IOpnsenseVpnInstance[] {
    return this.vpnRecords(vpnArg[typeArg]?.[roleArg]);
  }

  private static vpnRecords(valueArg: IOpnsenseVpnInstance[] | Record<string, IOpnsenseVpnInstance> | undefined): IOpnsenseVpnInstance[] {
    if (!valueArg) return [];
    return Array.isArray(valueArg) ? valueArg : Object.entries(valueArg).map(([key, value]) => ({ uuid: value.uuid || value.id || key, ...value }));
  }

  private static uniqueVpnInstances(instancesArg: IOpnsenseVpnInstance[]): IOpnsenseVpnInstance[] {
    const seen = new Map<string, IOpnsenseVpnInstance>();
    for (const instance of instancesArg) {
      const key = this.vpnId(instance) || instance.name;
      if (!key) continue;
      seen.set(key, { ...seen.get(key), ...instance });
    }
    return [...seen.values()];
  }

  private static ruleId(ruleArg: IOpnsenseFirewallRule): string | undefined {
    return this.stringValue(ruleArg.uuid || ruleArg.id);
  }

  private static ruleEnabled(ruleArg: IOpnsenseFirewallRule | IOpnsenseFirewallAlias): boolean {
    const enabled = this.booleanLike(ruleArg.enabled);
    if (enabled !== undefined) return enabled;
    const disabled = this.booleanLike(ruleArg.disabled);
    if (disabled !== undefined) return !disabled;
    return true;
  }

  private static serviceName(serviceArg: IOpnsenseServiceInfo): string {
    return serviceArg.name || serviceArg.id || serviceArg.displayName || 'service';
  }

  private static serviceDisplayName(serviceArg: IOpnsenseServiceInfo): string {
    return serviceArg.displayName || serviceArg.description || serviceArg.name || serviceArg.id || 'Service';
  }

  private static serviceRunning(serviceArg: IOpnsenseServiceInfo): boolean {
    return this.booleanLike(serviceArg.status) ?? this.booleanLike(serviceArg.running) ?? this.booleanLike(serviceArg.enabled) ?? false;
  }

  private static vpnId(instanceArg: IOpnsenseVpnInstance): string | undefined {
    return this.stringValue(instanceArg.uuid || instanceArg.id);
  }

  private static vpnName(instanceArg: IOpnsenseVpnInstance): string {
    return instanceArg.name || instanceArg.description || this.vpnId(instanceArg) || 'VPN';
  }

  private static interfaceUp(ifaceArg: IOpnsenseInterfaceInfo): boolean {
    if (ifaceArg.connected !== undefined) return ifaceArg.connected;
    const enabled = this.booleanLike(ifaceArg.enabled);
    const status = this.stringValue(ifaceArg.status)?.toLowerCase();
    if (status) return enabled !== false && ['up', 'associated', 'online'].includes(status);
    return enabled !== false;
  }

  private static gatewayUp(gatewayArg: IOpnsenseGatewayInfo): boolean {
    const disabled = this.booleanLike(gatewayArg.disabled);
    const status = this.stringValue(gatewayArg.status)?.toLowerCase();
    if (disabled === true) return false;
    return !status || ['online', 'up', 'none'].includes(status);
  }

  private static trackerInterfaces(configArg: IOpnsenseConfig, sourceArg?: IOpnsenseSnapshot): string[] {
    const fromConfig = configArg.trackerInterfaces || configArg.tracker_interfaces;
    if (Array.isArray(fromConfig)) return fromConfig.filter((valueArg): valueArg is string => typeof valueArg === 'string' && valueArg.trim().length > 0);
    const fromMetadata = sourceArg?.metadata?.trackerInterfaces;
    return Array.isArray(fromMetadata) ? fromMetadata.filter((valueArg): valueArg is string => typeof valueArg === 'string' && valueArg.trim().length > 0) : [];
  }

  private static pendingNotices(systemArg: IOpnsenseSystemInfo): boolean | undefined {
    return this.booleanLike(systemArg.pendingNoticesPresent) ?? this.booleanLike(systemArg.pending_notices_present);
  }

  private static hasFirmwareUpdate(snapshotArg: IOpnsenseSnapshot): boolean {
    return Boolean(snapshotArg.router.latestFirmware || snapshotArg.system.productLatest || snapshotArg.router.updateAvailable !== undefined || snapshotArg.system.updateAvailable !== undefined);
  }

  private static updateAvailable(snapshotArg: IOpnsenseSnapshot): boolean {
    return Boolean(snapshotArg.router.updateAvailable ?? snapshotArg.system.updateAvailable);
  }

  private static routerDeviceId(snapshotArg: IOpnsenseSnapshot): string {
    return `${opnsenseDomain}.router.${this.uniqueBase(snapshotArg)}`;
  }

  private static clientDeviceId(clientArg: IOpnsenseClientDevice): string {
    return `${opnsenseDomain}.client.${this.slug(this.clientMac(clientArg) || clientArg.id || clientArg.ipAddress || clientArg.ip || clientArg.address || this.clientName(clientArg))}`;
  }

  private static routerName(snapshotArg: IOpnsenseSnapshot): string {
    return snapshotArg.router.name || snapshotArg.system.name || snapshotArg.system.hostname || snapshotArg.router.host || 'OPNsense';
  }

  private static clientName(clientArg: IOpnsenseClientDevice): string {
    return clientArg.name || clientArg.hostname || clientArg.macAddress || clientArg.mac || clientArg.ipAddress || clientArg.ip || clientArg.address || 'Unknown device';
  }

  private static clientMac(clientArg: IOpnsenseClientDevice): string | undefined {
    return this.normalizeMac(clientArg.macAddress || clientArg.mac);
  }

  private static uniqueBase(snapshotArg: IOpnsenseSnapshot): string {
    return this.slug(snapshotArg.router.macAddress || snapshotArg.router.serialNumber || snapshotArg.router.id || snapshotArg.router.host || this.routerName(snapshotArg));
  }

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

  private static addFeatureState(featuresArg: plugins.shxInterfaces.data.IDeviceFeature[], stateArg: plugins.shxInterfaces.data.IDeviceState[], idArg: string, nameArg: string, valueArg: unknown, updatedAtArg: string, unitArg?: string): void {
    if (valueArg === undefined) return;
    featuresArg.push({ id: idArg, capability: 'sensor', name: nameArg, readable: true, writable: false, unit: unitArg });
    stateArg.push({ featureId: idArg, value: this.deviceStateValue(valueArg), updatedAt: updatedAtArg });
  }

  private static entityState(valueArg: unknown): unknown {
    if (typeof valueArg === 'boolean') return valueArg ? 'on' : 'off';
    return valueArg;
  }

  private static sensorValue(valueArg: unknown): unknown {
    if (valueArg instanceof Date) return valueArg.toISOString();
    return valueArg;
  }

  private static deviceStateValue(valueArg: unknown): plugins.shxInterfaces.data.TDeviceStateValue {
    if (typeof valueArg === 'string' || typeof valueArg === 'number' || typeof valueArg === 'boolean' || valueArg === null) return valueArg;
    if (valueArg && typeof valueArg === 'object') return valueArg as Record<string, unknown>;
    return null;
  }

  private static bytesToGigabytes(valueArg: number | undefined): number | undefined {
    return valueArg === undefined ? undefined : valueArg / 1000000000;
  }

  private static parseEndpoint(valueArg: string | undefined): { host?: string; port?: number } {
    if (!valueArg) return {};
    try {
      const parsed = new URL(valueArg.includes('://') ? valueArg : `https://${valueArg}`);
      return { host: parsed.hostname, port: parsed.port ? Number(parsed.port) : undefined };
    } catch {
      return {};
    }
  }

  private static endpointUrl(hostArg: string, portArg: number | undefined): string {
    const port = portArg || opnsenseDefaultPort;
    return `https://${hostArg}${port === opnsenseDefaultPort ? '' : `:${port}`}`;
  }

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

  private static stringValue(valueArg: unknown): string | undefined {
    return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
  }

  private static numberValue(valueArg: unknown): number | undefined {
    if (typeof valueArg === 'number' && Number.isFinite(valueArg)) return valueArg;
    if (typeof valueArg === 'string' && valueArg.trim()) {
      const cleaned = valueArg.replace(/[^0-9.+-]/g, '');
      const parsed = Number(cleaned);
      return Number.isFinite(parsed) ? parsed : undefined;
    }
    return undefined;
  }

  private static booleanLike(valueArg: unknown): boolean | undefined {
    if (typeof valueArg === 'boolean') return valueArg;
    if (typeof valueArg === 'number') return valueArg === 1 ? true : valueArg === 0 ? false : undefined;
    if (typeof valueArg === 'string') {
      const normalized = valueArg.trim().toLowerCase();
      if (['1', 'true', 'yes', 'on', 'enabled', 'running', 'up', 'ok', 'online'].includes(normalized)) return true;
      if (['0', 'false', 'no', 'off', 'disabled', 'stopped', 'down', 'failed', 'offline'].includes(normalized)) return false;
    }
    return undefined;
  }

  private static methodValue(valueArg: unknown): 'GET' | 'POST' | undefined {
    return valueArg === 'GET' || valueArg === 'POST' ? valueArg : undefined;
  }

  private static recordValue(valueArg: unknown): Record<string, unknown> | undefined {
    return valueArg && typeof valueArg === 'object' && !Array.isArray(valueArg) ? valueArg as Record<string, unknown> : undefined;
  }

  private static dateString(valueArg: IOpnsenseClientDevice['lastActivity']): string | undefined {
    if (valueArg instanceof Date) return valueArg.toISOString();
    if (typeof valueArg === 'number') return new Date(valueArg).toISOString();
    return typeof valueArg === 'string' ? valueArg : undefined;
  }

  private static title(valueArg: string): string {
    return valueArg.replace(/_/g, ' ').replace(/\b\w/g, (matchArg) => matchArg.toUpperCase());
  }
}
