import { expect, tap } from '@git.zone/tstest/tapbundle';
import { GoveeLightLocalClient, GoveeLightLocalConfigFlow, GoveeLightLocalIntegration, GoveeLightLocalMapper, HomeAssistantGoveeLightLocalIntegration, createGoveeLightLocalDiscoveryDescriptor, goveeLightLocalProfile, type IGoveeLightLocalSnapshot, type TGoveeLightLocalRawData } from '../../ts/integrations/govee_light_local/index.js';

const rawData: TGoveeLightLocalRawData = {
  devices: [
    {
      fingerprint: 'GOVEE-LAN-001',
      sku: 'H6008',
      name: 'Desk Strip',
      on: true,
      brightness: 75,
      temperature_color: 3200,
      rgb_color: [255, 128, 0],
      capabilities: {
        features: 'COLOR_RGB COLOR_KELVIN_TEMPERATURE BRIGHTNESS SCENES',
        scenes: {
          sunrise: 1,
          movie: 2,
        },
      },
    },
  ],
};

tap.test('matches manual Govee light local candidates and creates config flow output', async () => {
  const descriptor = createGoveeLightLocalDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'govee_light_local-manual-match');
  const result = await matcher!.matches({ source: 'manual', id: 'GOVEE-LAN-001', name: 'Desk Strip', metadata: { rawData } }, {});

  expect(result.matched).toBeTrue();
  expect(result.candidate?.integrationDomain).toEqual('govee_light_local');

  const validation = await descriptor.getValidators()[0].validate(result.candidate!, {});
  expect(validation.matched).toBeTrue();

  const done = await (await new GoveeLightLocalConfigFlow().start(result.candidate!, {})).submit!({});
  expect(done.kind).toEqual('done');
  expect(done.config?.name).toEqual('Desk Strip');
  expect(done.config?.rawData).toEqual(rawData);
});

tap.test('maps Govee light local raw snapshots to runtime devices and entities', async () => {
  const client = new GoveeLightLocalClient({ name: 'Desk Strip', rawData });
  const snapshot = await client.getSnapshot();
  const mappedSnapshot = GoveeLightLocalMapper.toSnapshotFromRaw({ name: 'Desk Strip' }, rawData);
  const devices = GoveeLightLocalMapper.toDevices(mappedSnapshot);
  const entities = GoveeLightLocalMapper.toEntities(mappedSnapshot);

  expect(snapshot.online).toBeTrue();
  expect(mappedSnapshot.device.serialNumber).toEqual('GOVEE-LAN-001');
  expect(devices[0].integrationDomain).toEqual('govee_light_local');
  expect(devices[0].manufacturer).toEqual('Govee');
  expect(entities.some((entityArg) => entityArg.platform === 'light' && entityArg.state === true)).toBeTrue();
  expect(entities[0].attributes?.brightnessPercent).toEqual(75);
});

tap.test('exposes Govee light local runtime, HA alias, and unsupported control without executor', async () => {
  const integration = new GoveeLightLocalIntegration();
  const alias = new HomeAssistantGoveeLightLocalIntegration();
  expect(alias instanceof GoveeLightLocalIntegration).toBeTrue();
  expect(alias.domain).toEqual('govee_light_local');
  expect(integration.status).toEqual('control-runtime');
  expect(goveeLightLocalProfile.metadata.configFlow).toEqual(true);
  expect(goveeLightLocalProfile.metadata.dependencies).toEqual(['network']);

  const runtime = await integration.setup({ name: 'Desk Strip', rawData }, {});
  const status = await runtime.callService!({ domain: 'govee_light_local', service: 'status', target: {} });
  const refresh = await runtime.callService!({ domain: 'govee_light_local', service: 'refresh', target: {} });
  const snapshot = status.data as IGoveeLightLocalSnapshot;

  expect(status.success).toBeTrue();
  expect(refresh.success).toBeTrue();
  expect(snapshot.online).toBeTrue();
  expect((await runtime.devices())[0].name).toEqual('Desk Strip');

  const command = await runtime.callService!({ domain: 'light', service: 'turn_on', target: {}, data: { brightness: 128 } });
  expect(command.success).toBeFalse();
  expect(command.error!).toContain('requires an injected client.execute() or commandExecutor');
  await runtime.destroy();
});

export default tap.start();
