import { expect, tap } from '@git.zone/tstest/tapbundle';
import { AgentDvrMapper, type IAgentDvrSnapshot } from '../../ts/integrations/agent_dvr/index.js';

const snapshot: IAgentDvrSnapshot = {
  connected: true,
  server: {
    unique: 'agent-123',
    name: 'Agent Server',
    host: '192.168.1.90',
    port: 8090,
    protocol: 'http',
    serverUrl: 'http://192.168.1.90:8090/',
    version: '7.1.8.0',
    armed: true,
    activeProfile: 'home',
    deviceCount: 1,
    available: true,
  },
  devices: [{
    id: 2,
    objectId: 2,
    typeId: 2,
    name: 'Porch Cam',
    location: 'Porch',
    data: {
      recording: false,
      alerted: false,
      detected: true,
      online: true,
      alertsActive: true,
      detectorActive: true,
      connected: true,
      ptzid: -1,
      width: 1280,
      height: 720,
      mjpegStreamWidth: 640,
      mjpegStreamHeight: 360,
    },
    urls: {
      stillImageUrl: 'http://192.168.1.90:8090/grab.jpg?oid=2&size=640x360',
      mjpegImageUrl: 'http://192.168.1.90:8090/video.mjpg?oid=2&size=640x360',
      streamSourceUrl: 'http://192.168.1.90:8090/video.mjpg?oid=2&size=640x360',
    },
    available: true,
  }],
  locations: [{ name: 'Porch' }],
  profiles: [{ name: 'home', active: true }, { name: 'away', active: false }],
  updatedAt: '2026-01-01T00:00:00.000Z',
  source: 'http',
};

tap.test('maps Agent DVR server, camera, alarm, and sensor entities', async () => {
  const devices = AgentDvrMapper.toDevices(snapshot);
  const entities = AgentDvrMapper.toEntities(snapshot);

  expect(devices.length).toEqual(2);
  expect(devices[0].features.some((featureArg) => featureArg.id === 'alarm')).toBeTrue();
  expect(devices[1].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'alarm_control_panel.agent_server_alarm_panel')?.state).toEqual('armed_home');
  expect(entities.find((entityArg) => entityArg.id === 'camera.porch_cam')?.attributes?.mjpegImageUrl).toEqual('http://192.168.1.90:8090/video.mjpg?oid=2&size=640x360');
  expect(entities.find((entityArg) => entityArg.id === 'switch.porch_cam_alerts')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.porch_cam_detected')?.state).toEqual('on');
});

tap.test('models Agent DVR camera and alarm services as explicit HTTP commands', async () => {
  const alertCommand = AgentDvrMapper.commandForService(snapshot, {
    domain: 'agent_dvr',
    service: 'disable_alerts',
    target: { entityId: 'camera.porch_cam' },
  });
  const snapshotImageCommand = AgentDvrMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot',
    target: { entityId: 'camera.porch_cam' },
  });
  const recordingSwitchCommand = AgentDvrMapper.commandForService(snapshot, {
    domain: 'switch',
    service: 'turn_on',
    target: { entityId: 'switch.porch_cam_recording' },
  });
  const alarmCommand = AgentDvrMapper.commandForService(snapshot, {
    domain: 'alarm_control_panel',
    service: 'alarm_arm_night',
    target: { entityId: 'alarm_control_panel.agent_server_alarm_panel' },
  });

  expect(alertCommand?.command).toEqual('alertOff');
  expect(alertCommand?.httpCommands?.[0].params).toEqual({ cmd: 'alertOff', oid: 2, ot: 2 });
  expect(snapshotImageCommand?.type).toEqual('snapshot_image');
  expect(recordingSwitchCommand?.command).toEqual('record');
  expect(alarmCommand?.httpCommands?.map((commandArg) => commandArg.params.cmd)).toEqual(['arm', 'setProfileByName']);
  expect(alarmCommand?.profile).toEqual('night');
});

export default tap.start();
