import * as React from 'react';
import {
  FormattedMessage,
  defineMessages,
  injectIntl,
  InjectedIntl,
} from 'react-intl';
import {
  Background,
  Layout,
  Stat,
  StyledLayout,
  Text,
  TextType,
  SVG,
  SVGAsset,
  AspectRatio,
} from 'twitch-core-ui';

import { buildVODPath, buildChannelPath } from 'mweb/common/utils/pathBuilders';
import { extendInteractionMedium } from 'mweb/common/tracking/extendInteractionMedium';
import { TrackedLink } from 'mweb/common/tracking/trackedLink';
import { withLatencyTracker } from 'mweb/common/latency/withLatencyTracker';
import { CardImageWrapper } from 'mweb/common/components/more-ui/cardImageWrapper';
import { getChannelThumbnailSrcAndSrcSet } from 'mweb/common/utils/imageUtils';
import { INTERACTION_CONTENT_HOSTED_CHANNEL } from 'mweb/common/components/infoBox';
import {
  FeaturedContent,
  isChannelDetails,
} from 'mweb/common/selectors/pages/channelProfile';
import { ChannelOnlineStatus } from 'mweb/common/reducers/data/channels';

if (process.env.BROWSER) {
  require('./featuredContentCard.sass');
}

const INTERACTION_MEDIUM = 'featured_content';
export const INTERACTION_CONTENT_THUMBNAIL = 'thumbnail';
export const INTERACTION_CONTENT_TITLE = 'title';
const DEFAULT_ALT_TEXT = 'image for featured stream';

const messages = defineMessages({
  views: {
    id: 'views',
    defaultMessage: 'Views',
  },
  viewers: {
    id: 'viewers',
    defaultMessage: 'Viewers',
  },
  videoLength: {
    id: 'video-length',
    defaultMessage: 'Video length',
  },
});

interface FeaturedContentCardOwnProps {
  content: FeaturedContent;
  hostingChannel?: string;
  isHosting?: boolean;
}

export interface FeaturedContentCardProps extends FeaturedContentCardOwnProps {
  intl: InjectedIntl;
}

export class FeaturedContentCardBase extends React.PureComponent<
  FeaturedContentCardProps,
  {}
> {
  static displayName: string = 'FeaturedContentCard';

  isInteractive(): boolean {
    return !!this.props.content.id;
  }

  get contentPath(): string {
    if (isChannelDetails(this.props.content)) {
      return buildChannelPath(
        this.props.hostingChannel || this.props.content.name,
      );
    }
    return buildVODPath(this.props.content.id);
  }

  get featuredContentCardTitle(): JSX.Element {
    if (isChannelDetails(this.props.content)) {
      if (this.props.isHosting) {
        return (
          <FormattedMessage
            id="channel-profile-hosting"
            defaultMessage="Now Hosting {hostedChannel}"
            values={{
              hostedChannel: (
                <TrackedLink
                  to={buildChannelPath(this.contentPath)}
                  interactionContent={INTERACTION_CONTENT_HOSTED_CHANNEL}
                >
                  {this.props.content.displayName}
                </TrackedLink>
              ),
            }}
          />
        );
      }
      return (
        <FormattedMessage
          defaultMessage="Now Streaming"
          id="channel-profile-live"
        />
      );
    }
    return (
      <FormattedMessage
        defaultMessage="Most Recent Broadcast"
        id="channel-profile-most-recent-broadcast"
      />
    );
  }

  get formattedLengthLayout(): JSX.Element | undefined {
    if (!isChannelDetails(this.props.content)) {
      return (
        <Layout className="mw-featured-content-card__time">
          <Stat
            icon={SVGAsset.GlyphLength}
            label={this.props.intl.formatMessage(messages.videoLength)}
            value={this.props.content.formattedLength}
          />
        </Layout>
      );
    }
  }

  get status(): string | undefined {
    if (isChannelDetails(this.props.content)) {
      return this.props.content.status;
    }
    return this.props.content.title;
  }

  get preview(): string {
    if (isChannelDetails(this.props.content)) {
      return this.props.content.preview || '';
    }
    return this.props.content.thumbnailURL;
  }

  get isLive(): boolean {
    return (
      isChannelDetails(this.props.content) &&
      this.props.content.onlineStatus === ChannelOnlineStatus.Online
    );
  }

  get views(): number {
    return isChannelDetails(this.props.content)
      ? this.props.content.viewerCount
      : this.props.content.viewCount;
  }

  render(): JSX.Element {
    return (
      <Layout className="mw-featured-content-card" margin={1}>
        <StyledLayout background={Background.Alt} padding={{ x: 1, y: 0.5 }}>
          <Text type={TextType.H5}>{this.featuredContentCardTitle}</Text>
        </StyledLayout>
        <Layout className="mw-featured-content-card__image">
          <TrackedLink
            to={this.contentPath}
            interactionContent={INTERACTION_CONTENT_THUMBNAIL}
          >
            <Layout>
              <CardImageWrapper
                {...getChannelThumbnailSrcAndSrcSet(this.preview)}
                latencyTracked={true}
                alt={this.status || DEFAULT_ALT_TEXT}
                aspect={AspectRatio.Aspect16x9}
                key={this.preview}
                sizes={[{ size: 'calc(100vw - 2rem)' }]}
              />

              <SVG asset={SVGAsset.Play} width={40} height={44} />
              <Layout className="mw-featured-content-card__views">
                <Stat
                  icon={SVGAsset.GlyphViews}
                  label={this.props.intl.formatMessage(
                    this.isLive ? messages.viewers : messages.views,
                  )}
                  value={this.props.intl.formatNumber(this.views || 0, {
                    maximumSignificantDigits: 3,
                  })}
                />
              </Layout>
              {this.formattedLengthLayout}
            </Layout>
          </TrackedLink>
        </Layout>
        <Layout
          className="mw-featured-content-card__details"
          padding={{ x: 1, y: 0.5 }}
        >
          <TrackedLink
            to={this.contentPath}
            interactionContent={INTERACTION_CONTENT_TITLE}
          >
            <Text type={TextType.H5} ellipsis>
              {this.status}
            </Text>
          </TrackedLink>
          <Text ellipsis>{this.props.content.game}</Text>
        </Layout>
      </Layout>
    );
  }
}

export const FeaturedContentCard = injectIntl(
  extendInteractionMedium(
    withLatencyTracker(FeaturedContentCardBase),
    INTERACTION_MEDIUM,
  ),
) as React.ComponentClass<FeaturedContentCardOwnProps>;
