import { expect, tap } from '@git.zone/tstest/tapbundle';
import { AirgradientClient, AirgradientMapper, type IAirgradientSnapshot } from '../../ts/integrations/airgradient/index.js';

const snapshot: IAirgradientSnapshot = {
  connected: true,
  updatedAt: '2026-01-01T00:00:00.000Z',
  devices: [
    {
      host: '192.168.1.75',
      name: 'Living Room AirGradient',
      serialNumber: 'abcdef123456',
      model: 'I-9PSL',
      modelName: 'AirGradient ONE',
      firmwareVersion: '3.1.2',
      latestFirmwareVersion: '3.2.0',
      online: true,
      measures: {
        signalStrength: -49,
        serialNumber: 'abcdef123456',
        bootTime: 4,
        firmwareVersion: '3.1.2',
        model: 'I-9PSL',
        pm01: 2,
        pm02: 6.5,
        rawPm02: 7,
        pm10: 9,
        ambientTemperature: 21.4,
        relativeHumidity: 45,
        rco2: 620,
        totalVolatileOrganicComponentIndex: 3,
        nitrogenIndex: 1,
        pm003Count: 123,
      },
      config: {
        country: 'US',
        pmStandard: 'us-aqi',
        ledBarMode: 'co2',
        co2AutomaticBaselineCalibrationDays: 30,
        temperatureUnit: 'c',
        configurationControl: 'local',
        postDataToAirGradient: true,
        ledBarBrightness: 80,
        displayBrightness: 60,
        noxLearningOffset: 60,
        tvocLearningOffset: 120,
      },
    },
  ],
  events: [],
};

tap.test('maps AirGradient measures and config to devices and entities', async () => {
  const devices = AirgradientMapper.toDevices(snapshot);
  const entities = AirgradientMapper.toEntities(snapshot);

  expect(devices[0].id).toEqual('airgradient.device.abcdef123456');
  expect(devices[0].manufacturer).toEqual('AirGradient');
  expect(devices[0].features.some((featureArg) => featureArg.id === 'co2')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'sensor.living_room_airgradient_pm2_5')?.state).toEqual(6.5);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.living_room_airgradient_co2')?.state).toEqual(620);
  expect(entities.find((entityArg) => entityArg.uniqueId.endsWith('_display_pm_standard') && entityArg.platform === 'select')?.state).toEqual('us_aqi');
  expect(entities.find((entityArg) => entityArg.uniqueId.endsWith('_display_brightness') && entityArg.platform === 'number')?.state).toEqual(60);
  expect(entities.find((entityArg) => entityArg.uniqueId.endsWith('_update'))?.attributes?.latestVersion).toEqual('3.2.0');
});

tap.test('maps AirGradient services to safe config payloads', async () => {
  const entities = AirgradientMapper.toEntities(snapshot);
  const pmStandardEntity = entities.find((entityArg) => entityArg.uniqueId.endsWith('_display_pm_standard') && entityArg.platform === 'select')!;
  const brightnessEntity = entities.find((entityArg) => entityArg.uniqueId.endsWith('_display_brightness') && entityArg.platform === 'number')!;
  const postDataEntity = entities.find((entityArg) => entityArg.uniqueId.endsWith('_post_data_to_airgradient'))!;
  const ledTestEntity = entities.find((entityArg) => entityArg.uniqueId.endsWith('_led_bar_test'))!;

  const pmCommand = AirgradientMapper.commandForService(snapshot, {
    domain: 'select',
    service: 'select_option',
    target: { entityId: pmStandardEntity.id },
    data: { option: 'ugm3' },
  });
  const brightnessCommand = AirgradientMapper.commandForService(snapshot, {
    domain: 'number',
    service: 'set_value',
    target: { entityId: brightnessEntity.id },
    data: { value: 42 },
  });
  const switchCommand = AirgradientMapper.commandForService(snapshot, {
    domain: 'switch',
    service: 'turn_off',
    target: { entityId: postDataEntity.id },
  });
  const buttonCommand = AirgradientMapper.commandForService(snapshot, {
    domain: 'button',
    service: 'press',
    target: { entityId: ledTestEntity.id },
  });

  expect(pmCommand?.type === 'set_config' ? pmCommand.payload : undefined).toEqual({ pmStandard: 'ugm3' });
  expect(brightnessCommand?.type === 'set_config' ? brightnessCommand.payload : undefined).toEqual({ displayBrightness: 42 });
  expect(switchCommand?.type === 'set_config' ? switchCommand.payload : undefined).toEqual({ postDataToAirGradient: false });
  expect(buttonCommand?.type === 'set_config' ? buttonCommand.payload : undefined).toEqual({ ledBarTestRequested: true });
  expect(AirgradientMapper.commandForService(snapshot, { domain: 'airgradient', service: 'set_config', target: {}, data: { field: 'unknown', value: true } })).toBeUndefined();
});

tap.test('does not fake live AirGradient command success for snapshot-only configs', async () => {
  const client = new AirgradientClient({ snapshot });
  const command = AirgradientMapper.commandForService(snapshot, {
    domain: 'number',
    service: 'set_value',
    target: { entityId: 'number.living_room_airgradient_display_brightness' },
    data: { value: 50 },
  })!;
  const result = await client.sendCommand(command);
  expect(result.success).toBeFalse();
  expect(result.error).toContain('requires config.host');
});

export default tap.start();
