import prepareVideoWatchEvent, {
  PrepareVideoWatchEventInput,
  getAllVideoWatchEventsPrepared,
} from '../prepare-video-watch-event';
import { VERSION } from '../../config/config';
import { BlinkEvent } from '../../types';
import { VideoTimeEvent } from '../../utils/video-event-time';
import { Page } from '../../selectors/get-page-state';

function mockBlinkEvent({
  id,
  playReason,
  stopReason,
  activeTime,
}: {
  id: any;
  playReason: any;
  stopReason: any;
  activeTime: any;
}): BlinkEvent {
  return {
    type: 'videoWatch',
    pageView: 'some-pageview-uuid',
    site: 'www.dagbladet.no',
    referrer: 'www.dinside.no',
    id,
    videoId: id,
    videoPlayReason: playReason,
    videoStopReason: stopReason,
    version: VERSION,
    activeTime,
    videoPlayMuted: true,
    videoStopMuted: false,
    videoPlayPosition: 15,
    videoStopPosition: 50.3,
    videoPlayVolume: 30,
    videoStopVolume: 40,
    videoSticky: false,
    streamingMode: 'live',
    channelId: 'LaksIW2',
  };
}

function mockWatchEvent({
  type,
  time,
  reason,
  videoId,
}: {
  type: any;
  time: any;
  reason: any;
  videoId: any;
}): VideoTimeEvent {
  const isWatchStartEvent = type === 'start' || type === 'shown';

  return {
    type,
    time,
    muted: isWatchStartEvent,
    position: isWatchStartEvent ? 15 : 50.3,
    reason,
    videoId,
    volume: isWatchStartEvent ? 30 : 40,
    playerId: 'test-player-id',
    streamingMode: 'live',
    channelId: 'LaksIW2',
  };
}

describe('prepareVideoWatchEvents', () => {
  it('should format properly based on page state', () => {
    const videoEvents: VideoTimeEvent[] = [
      {
        type: 'start',
        time: new Date(5),
        muted: true,
        position: 11.2,
        reason: 'autostart',
        videoId: '123',
        volume: 30,
        playerId: 'test-player-id',
      },
      {
        type: 'stop',
        time: new Date(50),
        muted: false,
        position: 50.3,
        reason: 'exit',
        videoId: '123',
        volume: 40,
        playerId: 'test-player-id',
      },
    ];

    const input: PrepareVideoWatchEventInput = {
      page: {
        id: 'default',
        state: {
          general: {
            pageView: 'some-pageview-uuid',
            site: 'www.dagbladet.no',
            referrer: 'www.dinside.no',
          },
          video: {
            events: videoEvents,
          },
          player: {
            'test-player-id': [
              {
                type: 'shown',
                time: new Date(10),
                muted: true,
                position: 11.2,
                reason: 'viewable',
                volume: 30,
              },
            ],
          },
        },
      },
      playerId: 'test-player-id',
      videoId: '123',
      streamingMode: 'live',
      channelId: 'LaksIW2',
      time: new Date(2),
    };

    const expected: BlinkEvent[] = [
      {
        type: 'videoWatch',
        pageView: 'some-pageview-uuid',
        site: 'www.dagbladet.no',
        referrer: 'www.dinside.no',
        version: VERSION,
        id: '123',
        videoId: '123',
        videoPlayMuted: true,
        videoStopMuted: false,
        videoPlayPosition: 11.2,
        videoStopPosition: 50.3,
        videoPlayVolume: 30,
        videoStopVolume: 40,
        videoPlayReason: 'viewable',
        videoStopReason: 'exit',
        activeTime: 40,
        videoSticky: false,
        streamingMode: 'live',
        channelId: 'LaksIW2',
      },
    ];

    expect(prepareVideoWatchEvent(input)).toEqual(expected);
  });

  it('should format properly when no events in page state', () => {
    const videoEvents: VideoTimeEvent[] = [];

    const input: PrepareVideoWatchEventInput = {
      page: {
        id: 'default',
        state: {
          general: {
            pageView: 'some-pageview-uuid',
            site: 'www.dagbladet.no',
            referrer: 'www.dinside.no',
          },
          video: {
            events: videoEvents,
          },
          player: {
            'test-player-id': [{}],
          },
        },
      },
      videoId: '123',
      playerId: 'test-player-id',
      time: new Date(2),
    };

    expect(prepareVideoWatchEvent(input)).toEqual([]);
  });
});

describe('prepareAllVideoWatchEvents', () => {
  it('should format properly based on page state', () => {
    const videoEvents: VideoTimeEvent[] = [
      mockWatchEvent({
        type: 'start',
        time: new Date(9),
        reason: 'autostart',
        videoId: '123',
      }),
      mockWatchEvent({
        type: 'start',
        time: new Date(11),
        reason: 'autostart',
        videoId: 'ABC',
      }),
      mockWatchEvent({
        type: 'stop',
        time: new Date(50),
        reason: 'exit',
        videoId: '123',
      }),
      mockWatchEvent({
        type: 'stop',
        time: new Date(55),
        reason: 'pause',
        videoId: 'ABC',
      }),
      // A second event for id 123
      mockWatchEvent({
        type: 'start',
        time: new Date(100),
        reason: 'interaction',
        videoId: '123',
      }),
      mockWatchEvent({
        type: 'stop',
        time: new Date(120),
        reason: 'pause',
        videoId: '123',
      }),
    ];

    const page: Page = {
      id: 'default',
      state: {
        general: {
          pageView: 'some-pageview-uuid',
          site: 'www.dagbladet.no',
          referrer: 'www.dinside.no',
        },
        video: {
          events: videoEvents,
        },
        player: {
          'test-player-id': [
            {
              type: 'shown',
              time: new Date(10),
              reason: 'viewable',
              muted: true,
              volume: 30,
              position: 15,
            },
          ],
        },
      },
    };

    const expected: BlinkEvent[] = [
      mockBlinkEvent({
        id: '123',
        playReason: 'viewable',
        stopReason: 'exit',
        activeTime: 40,
      }),
      mockBlinkEvent({
        id: '123',
        playReason: 'interaction',
        stopReason: 'pause',
        activeTime: 20,
      }),
      mockBlinkEvent({
        id: 'ABC',
        activeTime: 44,
        playReason: 'autostart',
        stopReason: 'pause',
      }),
    ];

    expect(getAllVideoWatchEventsPrepared(page)).toEqual(expected);
  });
});
