import { expect, tap } from '@git.zone/tstest/tapbundle';
import { FoscamMapper, type IFoscamSnapshot } from '../../ts/integrations/foscam/index.js';

const snapshot: IFoscamSnapshot = {
  deviceInfo: {
    id: 'FOS123',
    name: 'Porch Foscam',
    manufacturer: 'Foscam',
    model: 'FI9821W',
    serialNumber: 'FOS123',
    host: '192.168.1.40',
    port: 88,
    protocol: 'http',
    rtspPort: 554,
    online: true,
  },
  camera: {
    id: 'camera',
    name: 'Porch Camera',
    stream: 'Main',
    snapshotUrl: 'http://192.168.1.40:88/cgi-bin/CGIProxy.fcgi?usr=admin&pwd=secret&cmd=snapPicture2',
    rtspUrl: 'rtsp://admin:secret@192.168.1.40:554/videoMain',
    streamSourceUrl: 'rtsp://admin:secret@192.168.1.40:554/videoMain',
    motionDetectionEnabled: true,
    supportsPtz: true,
    available: true,
  },
  switches: [
    { key: 'motion_detection', name: 'Motion Detection', isOn: true, available: true },
    { key: 'is_mirror', name: 'Mirror', isOn: false, entityCategory: 'config', available: true },
  ],
  numbers: [
    { key: 'device_volume', name: 'Device Volume', value: 20, min: 0, max: 100, step: 1, entityCategory: 'config', available: true },
  ],
  currentSettings: { motion_detection: true, is_mirror: false, device_volume: 20 },
  connected: true,
  updatedAt: '2026-01-01T00:00:00.000Z',
  source: 'http',
};

tap.test('maps Foscam camera, switches, and numbers', async () => {
  const devices = FoscamMapper.toDevices(snapshot);
  const entities = FoscamMapper.toEntities(snapshot);

  expect(devices.length).toEqual(1);
  expect(devices[0].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'camera.porch_camera')?.attributes?.rtspUrl).toEqual('rtsp://admin:secret@192.168.1.40:554/videoMain');
  expect(entities.find((entityArg) => entityArg.id === 'switch.motion_detection')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'number.device_volume')?.state).toEqual(20);
});

tap.test('models snapshot, PTZ, preset, switch, and number services as explicit commands', async () => {
  const snapshotCommand = FoscamMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot',
    target: { entityId: 'camera.porch_camera' },
  });
  const ptzCommand = FoscamMapper.commandForService(snapshot, {
    domain: 'foscam',
    service: 'ptz',
    target: { entityId: 'camera.porch_camera' },
    data: { movement: 'left', travel_time: '0' },
  });
  const presetCommand = FoscamMapper.commandForService(snapshot, {
    domain: 'foscam',
    service: 'ptz_preset',
    target: { entityId: 'camera.porch_camera' },
    data: { preset_name: 'Home' },
  });
  const switchCommand = FoscamMapper.commandForService(snapshot, {
    domain: 'switch',
    service: 'turn_on',
    target: { entityId: 'switch.mirror' },
  });
  const numberCommand = FoscamMapper.commandForService(snapshot, {
    domain: 'number',
    service: 'set_value',
    target: { entityId: 'number.device_volume' },
    data: { value: 35 },
  });

  expect(snapshotCommand?.type).toEqual('snapshot_image');
  expect(snapshotCommand?.httpCommands?.[0].command).toEqual('snapPicture2');
  expect(ptzCommand?.type).toEqual('ptz');
  expect(ptzCommand?.movement).toEqual('left');
  expect(ptzCommand?.travelTime).toEqual(0);
  expect(presetCommand?.type).toEqual('ptz_preset');
  expect(presetCommand?.httpCommands?.[0].params?.name).toEqual('Home');
  expect(switchCommand?.type).toEqual('set_switch');
  expect(switchCommand?.key).toEqual('is_mirror');
  expect(switchCommand?.enabled).toBeTrue();
  expect(numberCommand?.type).toEqual('set_number');
  expect(numberCommand?.value).toEqual(35);
});

export default tap.start();
