import { expect, tap } from '@git.zone/tstest/tapbundle';
import { MotionEyeMapper, type IMotionEyeSnapshot } from '../../ts/integrations/motioneye/index.js';

const snapshot: IMotionEyeSnapshot = {
  deviceInfo: {
    id: 'motioneye-host',
    name: 'motionEye Server',
    manufacturer: 'motionEye',
    host: '192.168.1.40',
    port: 8765,
    protocol: 'http',
    url: 'http://192.168.1.40:8765',
    online: true,
  },
  cameras: [{
    id: '1',
    numericId: 1,
    name: 'Driveway',
    streamingPort: 8081,
    streamingAuthMode: 'basic',
    mjpegUrl: 'http://192.168.1.41:8081/',
    snapshotUrl: 'http://192.168.1.40:8765/picture/1/current/?_username=user&_signature=abc',
    isStreaming: true,
    motionDetectionEnabled: true,
    moviesEnabled: true,
    stillImagesEnabled: true,
    actions: ['snapshot', 'record_start', 'record_stop'],
    rootDirectory: '/var/lib/motioneye',
    available: true,
  }],
  sensors: [{ key: 'actions', name: 'Driveway Actions', cameraId: '1', value: 3, attributes: { actions: ['snapshot', 'record_start', 'record_stop'] }, available: true }],
  switches: [
    { key: 'motion_detection', name: 'Driveway Motion detection', cameraId: '1', isOn: true, entityCategory: 'config', available: true },
    { key: 'movies', name: 'Driveway Movies', cameraId: '1', isOn: true, entityCategory: 'config', available: true },
  ],
  rawCameras: [],
  connected: true,
  updatedAt: '2026-01-01T00:00:00.000Z',
};

tap.test('maps motionEye cameras, motion switches, and action sensors', async () => {
  const devices = MotionEyeMapper.toDevices(snapshot);
  const entities = MotionEyeMapper.toEntities(snapshot);

  expect(devices.length).toEqual(1);
  expect(devices[0].features.some((featureArg) => featureArg.id === 'motion_detection')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'camera.driveway')?.attributes?.snapshotUrl).toEqual('http://192.168.1.40:8765/picture/1/current/?_username=user&_signature=abc');
  expect(entities.find((entityArg) => entityArg.id === 'switch.driveway_motion_detection')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.driveway_actions')?.state).toEqual(3);
});

tap.test('models stream, snapshot, motion, recording, and text overlay services as commands', async () => {
  const streamCommand = MotionEyeMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'stream_source',
    target: { entityId: 'camera.driveway' },
  });
  const snapshotCommand = MotionEyeMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot',
    target: { entityId: 'camera.driveway' },
  });
  const motionCommand = MotionEyeMapper.commandForService(snapshot, {
    domain: 'switch',
    service: 'turn_off',
    target: { entityId: 'switch.driveway_motion_detection' },
  });
  const recordCommand = MotionEyeMapper.commandForService(snapshot, {
    domain: 'motioneye',
    service: 'record_start',
    target: { entityId: 'camera.driveway' },
  });
  const overlayCommand = MotionEyeMapper.commandForService(snapshot, {
    domain: 'motioneye',
    service: 'set_text_overlay',
    target: { entityId: 'camera.driveway' },
    data: { left_text: 'timestamp', custom_right_text: 'Driveway' },
  });

  expect(streamCommand?.type).toEqual('stream_source');
  expect(snapshotCommand?.type).toEqual('snapshot_image');
  expect(snapshotCommand?.httpCommands?.[0].path).toEqual('/picture/1/current/');
  expect(motionCommand?.type).toEqual('set_switch');
  expect(motionCommand?.key).toEqual('motion_detection');
  expect(motionCommand?.enabled).toEqual(false);
  expect(recordCommand?.type).toEqual('action');
  expect(recordCommand?.action).toEqual('record_start');
  expect(recordCommand?.httpCommands?.[0].path).toEqual('/action/1/record_start');
  expect(overlayCommand?.type).toEqual('set_text_overlay');
  expect(overlayCommand?.customRightText).toEqual('Driveway');
});

export default tap.start();
