import React from 'react';
import PropTypes from 'prop-types';
import TranscriptUtil from '../../../util/TranscriptUtil';
import TimeUtil from '../../../util/TimeUtil';
import FlexPlayerUtil from '../../../util/FlexPlayerUtil';

import { VIEW_LIST, VIEW_WORDCLOUD } from '../ContentAnnotationsColumn';
import TimedList from './TimedList';
import WordCloud from './WordCloud';
import { sanitize } from '../../shared/WordCloudHelpers';
import MediaEvents from '../_MediaEvents';

/*
	This component shows ASR transcriptions in a TimedList or WordCloud
*/

export default class ASR extends React.PureComponent {
    constructor(props) {
        super(props);
    }

    /* ----------------------- RENDER LIST -------------------*/

    renderList(mediaObject, transcript, searchTerm, mediaEvents) {
        // convert transcript to item list for TimedList
        const items = transcript.map(item => ({
            id: 'ca_asr_li_' + item.sequenceNr,
            start:
                FlexPlayerUtil.timeRelativeToOnAir(
                    item.start / 1000,
                    mediaObject
                ) * 1000,
            startLabel: TimeUtil.formatMillisToTime(
                FlexPlayerUtil.timeRelativeToOnAir(
                    item.start / 1000,
                    mediaObject
                ) * 1000
            ).replace(/^00:/g, ''), // remove prefixed 00: hours (so first hour is more compact)
            data: item.words
        }));

        return (
            <TimedList
                items={items}
                mediaEvents={mediaEvents}
                searchTerm={searchTerm}
            />
        );
    }

    /* ----------------------- RENDER WORDCLOUD -------------------*/

    renderWordCloud(transcript, searchTerm, mediaEvents, mediaObject) {
        // get raw word list from transcript
        const words = transcript.reduce(
            (w, item) => w.concat(item.words.split(' ')),
            []
        );

        // When click on a word, onSeek the player to the next occurence of the given word
        // Start on the start of the ASR item for context
        const onWordClick = word => {
            // get current player position
            const pos = mediaEvents.getData(MediaEvents.PLAYER_POS);
            // get next occurence
            let hit = null;

            transcript.some(item => {
                const itemStart = FlexPlayerUtil.timeRelativeToOnAir(
                    item.start / 1000,
                    mediaObject
                );

                // if item in the future, or no first hit
                if (itemStart > pos || hit == null) {
                    // sanitize the words
                    const words = sanitize(item.words);
                    word = word.replace('_', ' ');

                    // if word exists
                    if (words.indexOf(word) !== -1) {
                        // store first hit
                        if (!hit) {
                            hit = item;
                        }

                        // if future hit, store and return
                        if (itemStart > pos) {
                            hit = item;
                            return true;
                        }
                    }
                }
                return false;
            });

            // check if an item was hit
            if (hit != null && mediaObject) {
                // Update player by triggering SET_PLAYER_POS event
                this.props.mediaEvents.trigger(
                    MediaEvents.SET_PLAYER_POS,
                    FlexPlayerUtil.timeRelativeToOnAir(
                        hit.start / 1000,
                        mediaObject
                    )
                );
            }
        };

        return (
            <WordCloud
                words={words}
                mediaEvents={mediaEvents}
                size={100}
                searchTerm={searchTerm}
                onClick={onWordClick}
            />
        );
    }

    /* ----------------------- RENDER -------------------*/

    render = () => {
        const mediaObject = this.props.activeMediaObject;

        if (!mediaObject) {
            return null;
        }

        // get raw transcript
        const transcript = TranscriptUtil.getTranscript(
            this.props.resource.rawData.layer__asr || null,
            mediaObject
        );

        if (!transcript) {
            return null;
        }

        switch (this.props.view) {
            case VIEW_LIST:
                return this.renderList(
                    mediaObject,
                    transcript,
                    this.props.searchTerm,
                    this.props.mediaEvents
                );
            case VIEW_WORDCLOUD:
                return this.renderWordCloud(
                    transcript,
                    this.props.searchTerm,
                    this.props.mediaEvents,
                    mediaObject
                );
            default:
                return null;
        }
    };
}

ASR.propTypes = {
    searchTerm: PropTypes.string.isRequired,
    view: PropTypes.string.isRequired,
    resource: PropTypes.object.isRequired,
    activeMediaObject: PropTypes.object.isRequired,
    mediaEvents: PropTypes.object.isRequired
};
