import { expect, tap } from '@git.zone/tstest/tapbundle';
import { LinkplayMapper, type ILinkplaySnapshot } from '../../ts/integrations/linkplay/index.js';

const snapshot: ILinkplaySnapshot = {
  online: true,
  source: 'snapshot',
  speakers: [{
    uuid: 'leader-uuid',
    name: 'Living Room',
    available: true,
    device: {
      uuid: 'leader-uuid',
      name: 'Living Room',
      host: '192.168.1.10',
      port: 80,
      protocol: 'http',
      manufacturer: 'Arylic',
      model: 'S50+',
      project: 'ARYLIC_S50',
      macAddress: '00:11:22:33:44:55',
      hardwareVersion: 'A97',
      firmwareVersion: '4.6.415145',
      ethernetAddress: '192.168.1.10',
      playModeSupport: ['10', '41', '40'],
      maxPresets: 3,
    },
    player: {
      status: 'play',
      playMode: '41',
      loopMode: '2',
      equalizerMode: 'Pop',
      volume: 45,
      muted: false,
      title: 'Example Track',
      artist: 'Example Artist',
      album: 'Example Album',
      albumArtUrl: 'http://example.invalid/cover.jpg',
      currentPositionMs: 30000,
      totalLengthMs: 180000,
    },
    sources: [
      { mode: '10', name: 'Wifi', commandValue: 'wifi' },
      { mode: '41', name: 'Bluetooth', commandValue: 'bluetooth' },
      { mode: '40', name: 'Line In', commandValue: 'line-in' },
    ],
    presets: [{ number: 1, name: 'Jazz Radio' }, { number: 2, name: 'News' }, { number: 3, name: 'Kitchen' }],
    audioOutputHardwareMode: 'line_out',
  }, {
    uuid: 'follower-uuid',
    name: 'Kitchen',
    available: true,
    device: {
      uuid: 'follower-uuid',
      name: 'Kitchen',
      host: '192.168.1.11',
      port: 80,
      protocol: 'http',
      manufacturer: 'Arylic',
      model: 'Up2Stream Mini',
      ethernetAddress: '192.168.1.11',
      playModeSupport: ['10', '41'],
      maxPresets: 3,
    },
    player: {
      status: 'pause',
      playMode: '99',
      loopMode: '4',
      volume: 25,
      muted: true,
    },
  }],
  multirooms: [{
    id: 'downstairs',
    name: 'Downstairs',
    leaderUuid: 'leader-uuid',
    followerUuids: ['follower-uuid'],
    volume: 40,
    muted: false,
  }],
};

tap.test('maps LinkPlay speakers and multiroom groups to devices', async () => {
  const devices = LinkplayMapper.toDevices(snapshot);
  const leader = devices.find((deviceArg) => deviceArg.id === 'linkplay.speaker.leader_uuid');
  const group = devices.find((deviceArg) => deviceArg.id === 'linkplay.multiroom.downstairs');

  expect(leader?.manufacturer).toEqual('Arylic');
  expect(leader?.state.some((stateArg) => stateArg.featureId === 'source' && stateArg.value === 'Bluetooth')).toBeTrue();
  expect(group?.state.some((stateArg) => stateArg.featureId === 'members' && stateArg.value === 2)).toBeTrue();
});

tap.test('maps LinkPlay media, sources, presets and multiroom entities', async () => {
  const entities = LinkplayMapper.toEntities(snapshot);
  const player = entities.find((entityArg) => entityArg.id === 'media_player.living_room');
  const kitchen = entities.find((entityArg) => entityArg.id === 'media_player.kitchen');
  const sources = entities.find((entityArg) => entityArg.id === 'sensor.living_room_linkplay_sources');
  const presets = entities.find((entityArg) => entityArg.id === 'sensor.living_room_linkplay_presets');
  const multiroom = entities.find((entityArg) => entityArg.id === 'sensor.living_room_linkplay_multiroom');
  const audioOutput = entities.find((entityArg) => entityArg.id === 'select.living_room_audio_output_hardware_mode');

  expect(player?.state).toEqual('playing');
  expect(player?.attributes?.volumeLevel).toEqual(0.45);
  expect(player?.attributes?.source).toEqual('Bluetooth');
  expect(player?.attributes?.repeat).toEqual('all');
  expect(player?.attributes?.shuffle).toBeTrue();
  expect(player?.attributes?.groupMembers).toEqual(['media_player.living_room', 'media_player.kitchen']);
  expect(player?.attributes?.mediaDuration).toEqual(180);
  expect(player?.attributes?.mediaPosition).toEqual(30);
  expect(kitchen?.state).toEqual('paused');
  expect(sources?.state).toEqual(3);
  expect(presets?.state).toEqual(3);
  expect(multiroom?.state).toEqual('leader');
  expect(audioOutput?.state).toEqual('line_out');
});

export default tap.start();
