import { expect, tap } from '@git.zone/tstest/tapbundle';
import { PlexMapper, type IPlexSnapshot } from '../../ts/integrations/plex/index.js';

const snapshot: IPlexSnapshot = {
  capturedAt: '2026-01-01T00:00:00.000Z',
  source: 'manual',
  online: true,
  server: {
    machineIdentifier: 'server-abc',
    friendlyName: 'Media Box',
    version: '1.41.0',
    platform: 'Linux',
    url: 'http://192.168.1.10:32400',
    host: '192.168.1.10',
    port: 32400,
    online: true,
  },
  clients: [{
    machineIdentifier: 'client-abc',
    title: 'Living Room TV',
    product: 'Plex for Android TV',
    platform: 'Android',
    host: '192.168.1.55',
    port: 32500,
    protocolCapabilities: ['playback', 'timeline'],
    source: 'GDM',
    volumeLevel: 0.42,
    muted: false,
  }],
  sessions: [{
    sessionKey: '7',
    ratingKey: '1001',
    key: '/library/metadata/1001',
    title: 'The Test Episode',
    type: 'episode',
    summary: 'A test episode.',
    duration: 3600000,
    viewOffset: 125000,
    librarySectionTitle: 'TV Shows',
    grandparentTitle: 'Example Show',
    parentTitle: 'Season 1',
    parentIndex: 1,
    index: 2,
    thumb: '/library/metadata/1001/thumb/1',
    state: 'playing',
    mediaPositionUpdatedAt: '2026-01-01T00:00:00.000Z',
    User: { id: '1', title: 'Owner' },
    Player: {
      machineIdentifier: 'client-abc',
      title: 'Living Room TV',
      product: 'Plex for Android TV',
      platform: 'Android',
      state: 'playing',
      protocolCapabilities: ['playback', 'timeline'],
    },
    Session: { id: 'session-1', bandwidth: 9000, location: 'lan' },
  }],
  libraries: [{
    key: '1',
    uuid: 'library-tv',
    title: 'TV Shows',
    type: 'show',
    itemCount: 123,
    counts: { show: 10, season: 20, episode: 123 },
    refreshing: false,
    lastAddedItem: 'Example Show - S01E02 - The Test Episode',
    lastAddedTimestamp: '2026-01-01T00:00:00.000Z',
  }],
};

tap.test('maps Plex servers and media clients to canonical devices', async () => {
  const devices = PlexMapper.toDevices(snapshot);
  const server = devices.find((deviceArg) => deviceArg.id === 'plex.server.server_abc');
  const client = devices.find((deviceArg) => deviceArg.id === 'plex.client.server_abc.client_abc');

  expect(server?.online).toBeTrue();
  expect(server?.state.some((stateArg) => stateArg.featureId === 'active_sessions' && stateArg.value === 1)).toBeTrue();
  expect(client?.manufacturer).toEqual('Android');
  expect(client?.state.some((stateArg) => stateArg.featureId === 'current_title' && stateArg.value === 'The Test Episode')).toBeTrue();
});

tap.test('maps Plex activity, media players, and libraries to entities', async () => {
  const entities = PlexMapper.toEntities(snapshot);
  const activity = entities.find((entityArg) => entityArg.id === 'sensor.media_box_plex');
  const player = entities.find((entityArg) => entityArg.id === 'media_player.living_room_tv_plex');
  const library = entities.find((entityArg) => entityArg.id === 'sensor.media_box_tv_shows_plex_library');

  expect(activity?.state).toEqual(1);
  expect(activity?.attributes?.watching).toEqual({ 'Owner - Plex for Android TV': 'Example Show - S1:E2 - The Test Episode' });
  expect(player?.state).toEqual('playing');
  expect(player?.attributes?.mediaContentType).toEqual('tvshow');
  expect(player?.attributes?.mediaDuration).toEqual(3600);
  expect(player?.attributes?.mediaPosition).toEqual(125);
  expect(player?.attributes?.volumeLevel).toEqual(0.42);
  expect(library?.state).toEqual(123);
  expect(library?.attributes?.primaryType).toEqual('episode');
});

export default tap.start();
