import { expect, tap } from '@git.zone/tstest/tapbundle';
import { HikvisionMapper, type IHikvisionSnapshot } from '../../ts/integrations/hikvision/index.js';

const snapshot: IHikvisionSnapshot = {
  deviceInfo: {
    id: 'HKV123',
    name: 'Garage Hikvision',
    manufacturer: 'Hikvision',
    model: 'DS-7608NI',
    serialNumber: 'HKV123',
    deviceType: 'NVR',
    host: '192.168.1.40',
    port: 80,
    protocol: 'http',
    rtspPort: 554,
    online: true,
  },
  cameras: [
    {
      id: '1',
      name: 'Front Door',
      channel: 1,
      streamingChannelId: '101',
      snapshotUrl: 'http://192.168.1.40:80/ISAPI/Streaming/channels/101/picture',
      rtspUrl: 'rtsp://admin:secret@192.168.1.40:554/Streaming/Channels/101',
      enabled: true,
      available: true,
    },
    {
      id: '2',
      name: 'Driveway',
      channel: 2,
      streamingChannelId: '201',
      snapshotUrl: 'http://192.168.1.40:80/ISAPI/Streaming/channels/201/picture',
      rtspUrl: 'rtsp://admin:secret@192.168.1.40:554/Streaming/Channels/201',
      enabled: true,
      available: true,
    },
  ],
  binarySensors: [
    { key: 'line_crossing', sensorType: 'Line Crossing', name: 'Line crossing', channel: 1, isOn: true, deviceClass: 'motion', available: true },
    { key: 'field_detection', sensorType: 'Field Detection', name: 'Field detection', channel: 2, isOn: false, deviceClass: 'motion', available: true },
  ],
  events: [
    { id: 'line_crossing_1_rule1', key: 'line_crossing', sensorType: 'Line Crossing', name: 'Line crossing channel 1', channel: 1, state: 'on', isOn: true, rawType: 'linedetection' },
  ],
  connected: true,
  updatedAt: '2026-01-01T00:00:00.000Z',
};

tap.test('maps Hikvision cameras, event-backed binary sensors, and NVR metadata', async () => {
  const devices = HikvisionMapper.toDevices(snapshot);
  const entities = HikvisionMapper.toEntities(snapshot);

  expect(devices.length).toEqual(1);
  expect(devices[0].metadata?.deviceType).toEqual('NVR');
  expect(devices[0].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'camera.front_door')?.attributes?.snapshotUrl).toEqual('http://192.168.1.40:80/ISAPI/Streaming/channels/101/picture');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.line_crossing_channel_1')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.field_detection_channel_2')?.state).toEqual('off');
});

tap.test('models snapshots, stream sources, and unsupported event streams explicitly', async () => {
  const snapshotCommand = HikvisionMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot',
    target: { entityId: 'camera.front_door' },
  });
  const streamCommand = HikvisionMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'stream_source',
    target: { entityId: 'camera.front_door' },
  });
  const eventsCommand = HikvisionMapper.commandForService(snapshot, {
    domain: 'hikvision',
    service: 'event_triggers_metadata',
    target: {},
  });
  const unsupportedLiveEventCommand = HikvisionMapper.commandForService(snapshot, {
    domain: 'hikvision',
    service: 'start_event_stream',
    target: {},
  });

  expect(snapshotCommand?.type).toEqual('snapshot_image');
  expect(snapshotCommand?.httpCommands?.[0].path).toEqual('/ISAPI/Streaming/channels/101/picture');
  expect(streamCommand?.type).toEqual('stream_source');
  expect(streamCommand?.streamingChannelId).toEqual('101');
  expect(eventsCommand?.type).toEqual('event_triggers_metadata');
  expect(unsupportedLiveEventCommand?.type).toEqual('subscribe_events');
});

export default tap.start();
