import { ShallowWrapper } from 'enzyme';
import { stub } from 'sinon';
import { InjectedIntl } from 'react-intl';
import expect from 'expect';
import { Button } from 'twitch-core-ui';

import { partialPropShallowWrapper } from 'mtest/helpers/partialPropWrappers';
import { trackClickMock, testClickTracking } from 'mtest/helpers/tracking';
import {
  EventActionsBase as EventActions,
  EventActionsProps,
  INTERACTION_CONTENT_WATCH_NOW,
  CALL_TO_ACTION_IDENTIFIER,
  EVENT_ACTIONS_MEDIUM,
} from 'mweb/common/components/eventActions';
import { ShareButton } from 'mweb/common/components/shareButton';
import { RemindMeButton } from 'mweb/common/components/remindMeButton';
import { PremiereStatus } from 'mweb/common/reducers/data/events';
import { Location } from 'mweb/common/reducers/app';
import { EVENT_MODEL } from 'mtest/fetchMocks/event';
import { supportedPremiereEvents } from 'mweb/common/utils/premiereUtils';
import { TrackClickHandler } from 'mweb/common/tracking/withTracking';
import { OpenInApp } from 'mweb/common/containers/openInApp';

const DEFAULT_PROPS: EventActionsProps = {
  startTime: new Date(EVENT_MODEL.startTime),
  endTime: new Date(EVENT_MODEL.endTime),
  title: EVENT_MODEL.title,
  description: EVENT_MODEL.description,
  isMobileOS: true,
  appLocation: Location.EventDetails,
  handleNotificationRequest: () => undefined,
  handleShare: () => undefined,
  channelName: EVENT_MODEL.channel,
  premiereStatus: undefined,
  trackClick: trackClickMock(),
  intl: ({
    formatNumber: stub().returnsArg(0),
    formatMessage: stub().returns('FormattedText'),
  } as any) as InjectedIntl,
};

describe('<EventActions/>', () => {
  const subject = partialPropShallowWrapper(EventActions, DEFAULT_PROPS);

  it('passes down props to ShareButton', () => {
    expect(subject().find(ShareButton)).toHaveProps({
      title: DEFAULT_PROPS.title,
      appLocation: DEFAULT_PROPS.appLocation,
      handleShare: DEFAULT_PROPS.handleShare,
      shareSheetHeader: 'FormattedText',
    });
  });

  describe('no premiere status provided', () => {
    renderedRemindMeButton(subject());
  });

  describe('premiere status is scheduled', () => {
    renderedRemindMeButton(
      subject({ premiereStatus: PremiereStatus.Scheduled }),
    );
  });

  describe('premiere status is started', () => {
    const controls = subject({ premiereStatus: PremiereStatus.Started });
    renderedEventWatchNowButton(controls);
    renderedOpenInAppButton(controls);

    it('does not render open in app if not mobile os', () => {
      expect(
        subject({
          isMobileOS: false,
          premiereStatus: PremiereStatus.Started,
        }),
      ).toNotContain(OpenInApp);
    });
  });

  supportedPremiereEvents
    .filter(
      status =>
        status !== PremiereStatus.Scheduled &&
        status !== PremiereStatus.Started,
    )
    .forEach(status => {
      describe(`premiere status is ${status}`, () => {
        renderedPastEventButton(subject({ premiereStatus: status }));
      });
    });

  testClickTracking({
    title: 'tracks clicks on watch now button',
    expectedPayload: {
      interactionContent: INTERACTION_CONTENT_WATCH_NOW,
    },
    clickTargetBuilder: (trackClick: TrackClickHandler) =>
      subject({ trackClick, premiereStatus: PremiereStatus.Started }).find(
        Button,
      ),
  });
});

function renderedRemindMeButton(subject: ShallowWrapper<{}, {}>): void {
  describe('RemindMeButton as primary button', () => {
    it('renders remind me button with props', () => {
      const remindMeButton = subject.find(RemindMeButton);
      expect(remindMeButton).toHaveProps({
        startTime: DEFAULT_PROPS.startTime,
        endTime: DEFAULT_PROPS.endTime,
        title: DEFAULT_PROPS.title,
        description: DEFAULT_PROPS.description,
        isMobileOS: DEFAULT_PROPS.isMobileOS,
        appLocation: DEFAULT_PROPS.appLocation,
        handleNotificationRequest: DEFAULT_PROPS.handleNotificationRequest,
      });
    });

    it('does not render other primary buttons', () => {
      expect(subject).toNotContain(Button);
    });

    it('does not render other open in app button ', () => {
      expect(subject).toNotContain(OpenInApp);
    });
  });
}

function renderedEventWatchNowButton(subject: ShallowWrapper<{}, {}>): void {
  describe('Watch Now button as primary button', () => {
    it('renders watch now button with proper link', () => {
      const watchNow = subject.find(Button);
      expect(watchNow.prop('linkTo')).toEqual(`/${EVENT_MODEL.channel}`);
    });

    it('does not render other primary buttons', () => {
      expect(subject).toNotContain(RemindMeButton);
    });
  });
}
function renderedOpenInAppButton(subject: ShallowWrapper<{}, {}>): void {
  describe('Open In App button', () => {
    it('renders with props', () => {
      const openInApp = subject.find(OpenInApp);
      expect(openInApp).toHaveProps({
        path: `/${DEFAULT_PROPS.channelName}`,
        callToActionIdentifier: CALL_TO_ACTION_IDENTIFIER,
        medium: EVENT_ACTIONS_MEDIUM,
      });
    });
  });
}

function renderedPastEventButton(subject: ShallowWrapper<{}, {}>): void {
  describe('Past Event button as primary button', () => {
    it('renders watch past event button', () => {
      const pastEvent = subject.find(Button);
      expect(pastEvent.prop('disabled')).toEqual(true);
    });

    it('does not render other primary buttons', () => {
      expect(subject).toNotContain(RemindMeButton);
    });

    it('does not render other open in app button ', () => {
      expect(subject).toNotContain(OpenInApp);
    });
  });
}
