import expect from 'expect';
import times from 'lodash-es/times';
import { FormattedMessage } from 'react-intl';
import { Button } from 'twitch-core-ui';

import { partialPropShallowWrapper } from 'mtest/helpers/partialPropWrappers';
import { trackClickMock, testClickTracking } from 'mtest/helpers/tracking';

import {
  ChannelProfileVideoListBase as ChannelProfileVideoList,
  ChannelProfileVideoListProps,
  INTERACTION_CONTENT_SHOW_MORE,
} from 'mweb/common/components/channelProfileVideoList';
import {
  BaseVideoDetails,
  VideoType,
} from 'mweb/common/reducers/data/baseVideoDetails';
import { buildPathForBaseVideo } from 'mweb/common/utils/pathBuilders';
import { TrackClickHandler } from 'mweb/common/tracking/withTracking';

describe('<ChannelProfileVideoList />', () => {
  const OUTER_CLASS = '.mw-channel-profile-video-list';

  const VIDEO_ID = '123';

  const VIDEO: () => BaseVideoDetails = () => ({
    id: VIDEO_ID,
    channel: 'channel',
    title: 'Title',
    thumbnailURL: '//thumbnail.url',
    date: 0,
    viewCount: 0,
    length: 0,
    formattedLength: '0:00',
    game: undefined,
    videoType: VideoType.Archive,
  });

  const DEFAULT_PROPS: ChannelProfileVideoListProps = {
    videos: [],
    channel: 'Channel',
    type: undefined,
    trackClick: trackClickMock(),
  };

  const subject = partialPropShallowWrapper(
    ChannelProfileVideoList,
    DEFAULT_PROPS,
  );

  it('renders the common structure and expands when clicked', () => {
    const list = subject({ videos: times(6, VIDEO) });

    let outer = list.find(OUTER_CLASS);
    expect(outer).toHaveProp('padding', { bottom: 0 });
    expect(outer.childAt(1).children().length).toEqual(3);
    expect(outer.childAt(2).find(FormattedMessage)).toHaveProp(
      'id',
      'show-more',
    );

    list.find(Button).simulate('click');

    outer = list.find(OUTER_CLASS);
    expect(outer).toHaveProp('padding', { bottom: 3 });
    expect(outer.childAt(1).children().length).toEqual(6);
    expect(outer.childAt(2).children().length).toEqual(0);
  });

  it('does not show show more when given less than 3 videos', () => {
    const list = subject({ videos: times(2, VIDEO) });

    const outer = list.find(OUTER_CLASS);
    expect(outer.childAt(1).children().length).toEqual(2);
    expect(outer.childAt(2).children().length).toEqual(0);
  });

  describe('video type variations', () => {
    const testCases = [
      {
        type: VideoType.Archive,
        header: 'channel-profile-past-broadcasts',
      },
      {
        type: VideoType.Highlight,
        header: 'channel-profile-highlights',
      },
      {
        type: VideoType.Clip,
        header: 'channel-profile-clips',
      },
      {
        type: undefined,
        header: 'channel-profile-videos',
      },
    ];

    testCases.forEach(({ type, header }) => {
      it(`generates the right ids for ${type}s`, () => {
        const list = subject({
          videos: times(6, VIDEO),
          type,
        } as ChannelProfileVideoListProps);

        const outer = list.find(OUTER_CLASS);
        expect(outer.childAt(0).find(FormattedMessage)).toHaveProp(
          'id',
          header,
        );
      });
    });
  });

  describe('link building', () => {
    it('builds vod paths for archives', () => {
      const list = subject({ videos: times(1, VIDEO) });
      const item = list
        .find('.mw-channel-profile-video-list')
        .childAt(1)
        .childAt(0);
      expect(item).toHaveProp('linkTo', buildPathForBaseVideo(VIDEO()));
    });
  });

  testClickTracking({
    title: 'tracks clicks on show more',
    expectedPayload: {
      interactionContent: INTERACTION_CONTENT_SHOW_MORE,
    },
    clickTargetBuilder: (trackClick: TrackClickHandler) =>
      subject({ videos: times(6, VIDEO), trackClick }).find(Button),
  });
});
